【问题标题】:Syntax error in local variable inside trigger declaration触发器声明中的局部变量中的语法错误
【发布时间】:2013-07-16 18:34:27
【问题描述】:

我有以下存储过程

CREATE PROCEDURE `update_ordenes`()
BEGIN
    DECLARE record CURSOR FOR 
        SELECT ordenes.idorden, ordenes.idafiliado 
            FROM ordenes, afiliados 
            WHERE afiliados.idafiliado = ordenes.idafiliado;

    OPEN record;
    REPEAT
        FETCH record INTO @id_orden, @id_afil_viejo;

        INSERT INTO afil2(nombre, apellido, documento) 
            (SELECT nombre, apellido, documento
                FROM afiliados 
                WHERE idafiliado = @id_afil_viejo);

        SET @last_id = (SELECT id FROM afil2 ORDER BY id DESC LIMIT 1);

        UPDATE ordenes 
        SET afil2 = @last_id,
            ordenes.idafiliado = NULL
        WHERE ordenes.idafiliado = @id_afil_viejo
              AND ordenes.idorden = @orden_id;
    UNTIL done END REPEAT;
END

由于某种原因,我在FETCH record INTO @id_orden, @id_afil_viejo; 行收到语法错误

mysql documentation 中我可以运行SELECT id, data INTO @x, @y FROM test.t1 LIMIT 1;。 是FETCH的使用有问题吗?或者有什么问题?

【问题讨论】:

    标签: mysql stored-procedures user-variables


    【解决方案1】:

    FETCH(从游标中获取下一条记录并前进)与SELECT ... INTO(仅适用于返回单个记录的查询)相同。 p>

    FETCH 可以获取到local variables(没有@ 前缀,但必须在存储程序的开头为DECLAREd),而SELECT ... INTO 也可以获取到user-defined variables(确实有@前缀并且不是DECLAREd)。

    因此,您必须 DECLARE 一个局部变量,您的记录将在其中 FETCHed:

    CREATE PROCEDURE `update_ordenes`()
    BEGIN
    
        DECLARE id_orden BIGINT UNSIGNED DEFAULT 5;  -- as appropriate
        DECLARE id_afiv_viejo VARCHAR(15) NOT NULL;  -- as appropriate
    
        DECLARE record CURSOR FOR 
            SELECT ordenes.idorden, ordenes.idafiliado 
                FROM ordenes, afiliados 
                WHERE afiliados.idafiliado = ordenes.idafiliado;
    
        OPEN record;
        REPEAT
            FETCH record INTO id_orden, id_afil_viejo;
    
            INSERT INTO afil2(nombre, apellido, documento) 
                (SELECT nombre, apellido, documento
                    FROM afiliados 
                    WHERE idafiliado = id_afil_viejo);
    
            SET @last_id = (SELECT id FROM afil2 ORDER BY id DESC LIMIT 1);
    
            UPDATE ordenes 
            SET afil2 = @last_id,
                ordenes.idafiliado = NULL
            WHERE ordenes.idafiliado = id_afil_viejo
                  AND ordenes.idorden = id_orden;
        UNTIL done END REPEAT;
    END
    

    总而言之,您的存储过程非常不安全(在第一个 INSERT 语句和随后的 SET 之间存在竞争危险),并且执行本应更简单的事情的方法非常笨拙。

    【讨论】:

    • 我没有找到更好的方法来获取 afil2 中插入行的 ID,但我全神贯注! :)
    • 我是商店程序的新手。
    猜你喜欢
    • 1970-01-01
    • 2017-03-09
    • 1970-01-01
    • 2014-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多