繁体   English   中英

mysql过程语法错误

[英]mysql procedure syntax error


通过发送以下查询(MYSQL 5.0),我得到一个错误:

    DELIMITER //
    CREATE PROCEDURE relationTable ()
    BEGIN
        DECLARE articlecount int;
        DECLARE keywordcount int;
        DECLARE articlehits int;
        DECLARE ac int DEFAULT 0;
        DECLARE kc int;
        DECLARE articleid int;
        DECLARE word varchar(100);
        DECLARE word_id int;
        SET articlehits = 0;
        SET articlecount = (SELECT count(id) from articles);
        SET keywordcount = (SELECT count(id) from keywords);
        outerloop: WHILE (ac < articlecount) DO
            SET kc = 0;
            SET articleid = (SELECT id from articles LIMIT 1 OFFSET ac);
            innerloop: WHILE (kc < keywordcount) DO
                IF (articlehits < 5) THEN
                    SELECT keyword, id INTO word, word_id from keywords LIMIT 1 OFFSET kc;
                    IF (0 < (SELECT COUNT(id) from articles WHERE id=articleid AND CONCAT(title, " ",text) REGEXP word)) THEN
                        INSERT INTO articles (id, articleID, keywordID, type) VALUES(NULL, articleid, word_id, 'type1');
                        SET articlehits = articlehits + 1;
                    END IF;
                    SET kc = kc + 1;
                ELSE
                    SET kc = keywordcount;
                END IF;
            END WHILE innerloop;
            SET ac = ac + 1;
        END WHILE outerloop;
    END;
    //
    DELIMITER ;

这将产生以下错误:

错误1064(42000):您的SQL语法有错误; 检查与您的MySQL服务器版本相对应的手册以获取正确的语法,以在'LIMIT 1 OFFSET ac)附近使用; innerloop:WHILE(kc <keywordcount)在第15行做TO TO word,word_id from'

知道为什么会这样吗?

(编写此代码可在文章和关键字之间创建关系表,以在文章视图中启用智能链接。)

尝试删除while标签:

WHILE (ac < articlecount) DO
            SET kc = 0;
            SET articleid = (SELECT id from articles LIMIT 1 OFFSET ac);
            WHILE (kc < keywordcount) DO
                IF (articlehits < 5) THEN
                    SELECT keyword, id INTO word, word_id from keywords LIMIT 1 OFFSET kc;
                    IF (0 < (SELECT COUNT(id) from articles WHERE id=articleid AND CONCAT(title, " ",text) REGEXP word)) THEN
                        INSERT INTO articles (id, articleID, keywordID, type) VALUES(NULL, articleid, word_id, 'type1');
                        SET articlehits = articlehits + 1;
                    END IF;
                    SET kc = kc + 1;
                ELSE
                    SET kc = keywordcount;
                END IF;
            END WHILE;
            SET ac = ac + 1;
        END WHILE;

MySQL具有@varname形式的特定于连接的用户定义变量,以及您在代码示例中使用的类型的声明过程变量。 以我对过程的经验来看,有时只允许使用其中一种类型,如果我没记错的话,在选择INTO时可能是其中一种情况。 您可以在此处尝试使用用户定义的变量,如下所示:

    SET articleid = (SELECT id from articles LIMIT 1 OFFSET ac);
    innerloop: WHILE (kc < keywordcount) DO
        IF (articlehits < 5) THEN
            SELECT keyword, id INTO @word, @word_id from keywords LIMIT 1 OFFSET kc;

只是一个主意。

一个问题可能是SET acticleid =(SELECT ...)。 尝试使用SELECT .. INTO

SELECT id INTO @articleid FROM articles LIMIT 1 OFFSET ac;

存储过程中的变量LIMIT仅在新的MySQL版本中受支持。 请注意,由于您没有ORDER BY您将获得随机行。 看来您想改用CURSOR 参见docs

冒着看起来过于严格的风险,我相信您应该重写此过程以使用游标遍历数据库,而不是使用LIMIT进行单个选择。

在MySQL Docs中查看游标

感谢您到目前为止的帮助。 汤姆·豪斯(Tom Haws)的想法被证明是正确的。 SELECT INTO语句的变量必须是用户定义的。 我编辑了代码以使用游标和用户定义的变量,如下所示:

delimiter //
CREATE PROCEDURE relationTable ()
BEGIN
    DECLARE articlehits int;
    DECLARE looparticles int DEFAULT TRUE;
    DECLARE loopwords int DEFAULT TRUE;
    DECLARE done INT DEFAULT FALSE;     
    DECLARE keywordcursor CURSOR FOR SELECT keyword, id FROM keywords;
    DECLARE articlecursor CURSOR FOR SELECT id FROM articles;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; 
    OPEN articlecursor;
    WHILE (looparticles) DO
        FETCH articlecursor INTO @articleid;
        IF done THEN SET looparticles = FALSE;
        ELSE
            SET articlehits = 0;
            OPEN keywordcursor;
            WHILE (loopwords) DO
                FETCH keywordcursor INTO @word, @wordid;
                IF (articlehits < 5) AND NOT done THEN
                    IF (0 < (SELECT COUNT(id) FROM articles WHERE id=@articleid AND CONCAT(title, " ", text) REGEXP @word)) THEN
                        INSERT INTO keyword_article_rel (id, meldungID, wordID) VALUES(NULL, @articleid, @wordid);
                        SET articlehits = articlehits + 1;
                    END IF;
                ELSE
                    SET loopwords = FALSE;
                    CLOSE keywordcursor;
                    SET done = FALSE;
                END IF;
            END WHILE;
        END IF;
    END WHILE;
    CLOSE articlecursor;
    END;
    //
    delimiter ;

现在,我收到另一个我无法解释的错误:

错误1064(42000):您的SQL语法有错误; 检查与您的MySQL服务器版本相对应的手册,以在'附近使用正确的语法; 未找到的DECLARE继续处理程序集完成= TRUE; OPEN articlecursor; 第6行的W'

此错误使我感到困惑,因为处理程序不会有问题。 处理程序在mysql-documentation的示例中声明。 问题可能是我不能创建两个这样的游标吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM