1

我正在尝试创建一个存储函数,但是出现了一个让我发疯的错误,我真的不知道我的脚本有什么问题,我认为它没有错误,但我不知道为什么我收到此错误:

1064 - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以获取在 'DECLARE cr1 CURSOR FOR SELECT codeArt, qte FROM LigneBonEntrée WHERE numBon = ' 附近使用的正确语法

这是我的脚本:

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 回答