0

次のストアプロシージャがあります

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ドキュメントで実行できますSELECT id, data INTO @x, @y FROM test.t1 LIMIT 1;。の使用に問題がありFETCHますか? または何が問題ですか?

4

1 に答える 1

1

FETCH(カーソルから次のレコードを取得し、カーソルを進める) は、 (単一のレコードを返すクエリでのみ機能する)と同じではありません。SELECT ... INTO

FETCHローカル変数(接頭辞はありませんが、ストアド プログラムの開始時に d にする必要があります) にのみフェッチできますが、ユーザー定義変数(接頭辞はあるが d ではない) にもフェッチできます。@DECLARESELECT ... INTO@DECLARE

したがって、レコードが編集DECLAREされるローカル変数が必要です。FETCH

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

とは言っても、あなたの sproc は非常に安全ではなく (最初のINSERTステートメントとSETそれに続くステートメントの間に競合の危険性が存在します)、はるかに単純であるべきことを行うための非常に扱いにくい方法です。

于 2013-07-16T18:43:47.820 に答える