在事件中获取 MySQL 错误创建处理程序

Posted

技术标签:

【中文标题】在事件中获取 MySQL 错误创建处理程序【英文标题】:Getting MySQL error creating handler in an event 【发布时间】:2021-02-25 20:11:02 【问题描述】:

我正在尝试在 mysql 5.6 中创建一个事件,但每当我尝试 DECLARE 某些内容(例如参数或处理程序)时都会收到错误消息:

SQL 错误 [1064] [42000]:您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在 'DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @rollMeBack = TRUE; 附近使用正确的语法;

我是一名 SQL Server 人员,语法让我很不舒服。我尝试在this question 中声明一个变量,但我仍然在该行得到错误。帮助我 Obi Wan Kenobi:你是我唯一的希望。

整个(混淆)代码:

DELIMITER ||

CREATE EVENT my_event
ON SCHEDULE EVERY 5 MINUTE
ON COMPLETION PRESERVE
ENABLE
COMMENT 'Fixes status'
DO IF EXISTS (
        SELECT NULL FROM [...problem records..]
    ) THEN
        -- =================================================================================================
        -- Get a complete list of bad records:
    SET @rollMeBack = FALSE ;

        SET @LogId = 0;
        CREATE TEMPORARY TABLE updateable
            SELECT DISTINCT e.id , (@LogId:=@LogId + 1) + (SELECT MAX(dsd.id) FROM LogTable dsd ) AS LogId
            FROM Table1 e 
                INNER JOIN Table2 r
                    ON r.e_id = e.id 
                    /*Waiting 5 minutes to not interfere with current operations:*/
                    AND r.rDateTime <= CURRENT_TIMESTAMP() - INTERVAL 5 MINUTE
            WHERE e.Status = 'Sent'
                AND NOT EXISTS(SELECT NULL FROM Table2 r2 WHERE r2.e_id = e.id and r2.rDateTime is null)
            LIMIT 100 ;
        
        -- =================================================================================================
        -- =================================================================================================
        DECLARE CONTINUE HANDLER FOR SQLEXCEPTION 
            SET @rollMeBack = TRUE;

        START TRANSACTION
            -- =================================================================================================
            UPDATE Table1 as e1 
                INNER JOIN updateable AS u
                    ON e1.d=id = u.id
            SET e1.Status = 'Completed',
                e1.cDateTime = COALESCE (e1.cDateTime, (select max(rDateTime) from Table2 r5 where r5.e_id = e1.id));
            -- =================================================================================================
            -- Log updates:
            INSERT INTO Debug (ID, Message)
            SELECT u.LogId,
                'Record set to `Completed`'
            FROM updateable AS u;
            -- =================================================================================================
            -- Cleanup:
            DROP TABLE updateable;

        IF @rollMeBack = TRUE THEN
            ROLLBACK;
        ELSE
            COMMIT;
        END IF
        -- =================================================================================================
        -- =================================================================================================
    END IF; ||

分隔符;

【问题讨论】:

是否有机会显示导致此错误的代码? 【参考方案1】:

一些修改使其可操作。

首先,必须在正确的位置声明处理程序。来自docs:

处理程序声明必须出现在变量或条件之后 声明。

其次,DO IF EXISTS...END IF; 应该包含一个 BEGIN...END 块,之后您可以进行处理程序声明:

...
COMMENT 'Fixes status'
DO IF EXISTS (
        SELECT NULL FROM [...problem records..]
    ) THEN
    BEGIN -- Note the added begin
        -- Moved the handler declaration to be the first statement of this block
        DECLARE CONTINUE HANDLER FOR SQLEXCEPTION 
            SET @rollMeBack = TRUE;

        -- =================================================================================================
        -- Get a complete list of bad records:
    SET @rollMeBack = FALSE ;
    ...

代码末尾:

        ...
        -- =================================================================================================
    END; -- Note the added END
END IF; ||

DELIMITER ;

顺便说一句,IF @rollMeBack = TRUE THEN...END IF 块中也存在语法错误 - END IF 末尾缺少分号。

【讨论】:

以上是关于在事件中获取 MySQL 错误创建处理程序的主要内容,如果未能解决你的问题,请参考以下文章

如何将事件处理程序分配给以编程方式创建的图片框

如何在Timer事件处理程序中获取Timer对象列表的列表索引

如何在 jquery 中动态创建事件处理程序

javafx事件处理程序返回错误,我不完全了解

如何修复('throw er; //未处理'错误'事件')代码生命周期?

向任何控件添加事件处理程序会导致 Visual Studio 中的错误