我的MySQL脚本语法出错

时间:2013-06-10 21:12:08

标签: mysql stored-functions

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

  

1064 - 您的SQL语法出错;检查手册   对应于您的MySQL服务器版本,以便使用正确的语法   靠近'DECLARE cr1 CURSOR FOR SELECT codeArt,qteFROMLigneBonEntré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 ;

1 个答案:

答案 0 :(得分: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

  

仅允许在BEGIN ... END复合语句中使用DECLARE   并且必须在任何其他陈述之前开始。

     

声明必须遵循一定的顺序。游标声明必须   出现在处理程序声明之前。变量和条件   声明必须出现在游标或处理程序声明之前。