1

ストアド関数を作成しようとしていますが、エラーが表示されて頭がおかしくなりました。スクリプトの何が問題なのか本当にわかりません。スクリプトにエラーはないと思いますが、その理由がわかりません。このエラーが発生しています:

1064 - SQL 構文にエラーがあります。「DECLARE cr1 CURSOR FOR SELECT codeArt, qte FROM LigneBonEntrée WHERE numBon = 」の近くで使用する正しい構文については、MySQL サーバーのバージョンに対応するマニュアルを確認してください。

そして、これは私のスクリプトです:

DELIMITER $$

CREATE DEFINER=root@localhost FUNCTION verifierQteDemandee(numBonIn INT) RETURNS BOOLEAN
BEGIN
    DECLARE numLignesBonEntrée, numLignesBonSortie INTEGER;
    DECLARE codeArtLigneBonEntrée, codeArtLigneBonSortie, qteLigneBonEntrée, qteLigneBonSortie INTEGER;
    DECLARE no_more_rows BOOLEAN;
    DECLARE qteArticle INTEGER;
    DECLARE test BOOLEAN DEFAULT TRUE;

    SET numLignesBonEntrée =    (SELECT COUNT(*) FROM LigneBonEntrée WHERE numBon = numBonIn);

    SET numLignesBonSortie =    (SELECT COUNT(*) FROM numLignesBonSortie WHERE numBon = (SELECT estLieA FROM LigneBonEntrée WHERE numBon = numBonIn));

    IF numLignesBonEntrée <> numLignesBonSortie THEN
        SET test = FALSE;
    ELSE
        DECLARE cr1 CURSOR FOR  SELECT codeArt, qte FROM LigneBonEntrée WHERE numBon = numBonIn ORDER BY codeArt ASC;

        DECLARE cr2 CURSOR FOR  SELECT codeArt, qte FROM LigneBonSortieWHERE numBon = (SELECT estLieA FROM LigneBonEntréeWHERE numBon = numBonIn) ORDER BY codeArt ASC;

        DECLARE CONTINUE HANDLER FOR NOT FOUND
        SET no_more_rows = TRUE;

        OPEN cr1;
        OPEN cr2;

        the_loop: LOOP
            FETCH cr1 INTO codeArtLigneBonEntrée, qteLigneBonEntrée;
            FETCH cr2 INTO codeArtLigneBonSortie, qteLigneBonSortie;
            IF no_more_rows THEN 
                CLOSE cr;
                LEAVE the_loop;
            END IF;

            IF codeArtLigneBonEntrée <> codeArtLigneBonSortie THEN
                SET test = FALSE;
            END IF;

            IF qteLigneBonEntrée <> qteLigneBonSortie THEN
                SET test = FALSE;
            END IF;

        END LOOP the_loop;
    END IF;
    RETURN test;

END$$

DELIMITER ;
4

1 に答える 1

1

すべての DECLARE は、他のロジックよりも前に、プロシージャの先頭に配置する必要があります。以下を試してみてください。

DELIMITER $$

CREATE DEFINER=root@localhost FUNCTION verifierQteDemandee(numBonIn INT) RETURNS BOOLEAN
BEGIN
    DECLARE numLignesBonEntrée, numLignesBonSortie INTEGER;
    DECLARE codeArtLigneBonEntrée, codeArtLigneBonSortie, qteLigneBonEntrée, qteLigneBonSortie INTEGER;
    DECLARE no_more_rows BOOLEAN;
    DECLARE qteArticle INTEGER;
    DECLARE test BOOLEAN DEFAULT TRUE;

    -- Moved declarations to before other logic
    DECLARE cr1 CURSOR FOR  SELECT codeArt, qte FROM LigneBonEntrée WHERE numBon = numBonIn ORDER BY codeArt ASC;
    DECLARE cr2 CURSOR FOR  SELECT codeArt, qte FROM LigneBonSortieWHERE numBon = (SELECT estLieA FROM LigneBonEntréeWHERE numBon = numBonIn) ORDER BY codeArt ASC;
    DECLARE CONTINUE HANDLER FOR NOT FOUND
        SET no_more_rows = TRUE;

    SET numLignesBonEntrée =    (SELECT COUNT(*) FROM LigneBonEntrée WHERE numBon = numBonIn);

    SET numLignesBonSortie =    (SELECT COUNT(*) FROM numLignesBonSortie WHERE numBon = (SELECT estLieA FROM LigneBonEntrée WHERE numBon = numBonIn));

    IF numLignesBonEntrée <> numLignesBonSortie THEN
        SET test = FALSE;
    ELSE

        OPEN cr1;
        OPEN cr2;

        the_loop: LOOP
            FETCH cr1 INTO codeArtLigneBonEntrée, qteLigneBonEntrée;
            FETCH cr2 INTO codeArtLigneBonSortie, qteLigneBonSortie;
            IF no_more_rows THEN 
                CLOSE cr;
                LEAVE the_loop;
            END IF;

            IF codeArtLigneBonEntrée <> codeArtLigneBonSortie THEN
                SET test = FALSE;
            END IF;

            IF qteLigneBonEntrée <> qteLigneBonSortie THEN
                SET test = FALSE;
            END IF;

        END LOOP the_loop;
    END IF;
    RETURN test;

END$$

DELIMITER ;

Mysql ドキュメント: http://dev.mysql.com/doc/refman/5.0/en/declare.html

DECLARE は、BEGIN ... END 複合ステートメント内でのみ許可され、他のステートメントの前に開始する必要があります。

宣言は特定の順序に従う必要があります。カーソル宣言は、ハンドラー宣言の前に表示する必要があります。変数と条件の宣言は、カーソルまたはハンドラーの宣言の前に記述する必要があります。

于 2013-06-10T21:20:34.993 に答える