mysql过程语法错误

发布于 2025-01-04 14:37:15 字数 1781 浏览 2 评论 0原文


我通过发送以下查询(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) 附近使用的语法;内循环:WHILE (kc < keywordscount) DO TO word, word_id from' 第 15 行

知道为什么会发生这种情况吗?

(编写此内容是为了创建文章和关键字之间的关系表,以在文章视图中启用智能链接。)



I get an error by sending the following query (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 ;

This produces the following error:

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right
syntax to use near 'LIMIT 1 OFFSET ac); innerloop: WHILE (kc <
keywordcount) DO TO word, word_id from' at line 15

Any idea why this happens?

(Wrote this to create a relation table between articles and keywords, to enable smart-links in article view.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

那伤。 2025-01-11 14:37:15

尝试删除 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;

Try to remove the while labels:

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;
挽你眉间 2025-01-11 14:37:15

MySQL 具有 @varname 形式的特定于连接的用户定义变量以及您在代码示例中使用的类型的声明过程变量。根据我的程序经验,有时只允许其中一种类型,如果我没记错的话,其中一种情况可能是在 SELECTing 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;

只是一个想法。

MySQL has connection-specific user-defined variables of the form @varname and declared procedure variables of the type you are using in your code sample. In my experience with procedures, sometimes only one of the types is allowed, and if I recall correctly, one of those situations may be when SELECTing INTO. You might try using user-defined variables here, as follows:

    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;

Just an idea.

桃气十足 2025-01-11 14:37:15

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

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

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

One problem may be the SET acticleid = (SELECT...). Try with SELECT .. INTO:

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

Variable LIMIT in stored procedures is only supported in new MySQL versions. Note that since you dont have an ORDER BY you will get a random row. It looks like you want to use a CURSOR instead. See docs.

迷迭香的记忆 2025-01-11 14:37:15

冒着显得过于挑剔的风险,我相信您应该重写此过程以使用游标遍历数据库,而不是使用 LIMIT 进行单独选择。

请参阅 MySQL 文档中的游标

At the risk of seeming over-critical, I believe you should rewrite this procedure to use cursors for traversing your databases, instead of individual selects with LIMIT.

see Cursors in MySQL Docs

滥情空心 2025-01-11 14:37:15

感谢您迄今为止的帮助。
事实证明,汤姆·霍斯的想法是正确的。 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 服务器版本相对应,以便使用正确的语法
靠近 ';声明未找到的继续处理程序设置完成= TRUE;
打开文章光标;第 6 行的 W'

这个错误让我很困惑,因为处理程序不可能有问题。处理程序的声明如 mysql 文档的 示例 中所示。问题可能是我无法像这样创建两个光标吗?

Thank for your help so far.
The idea of Tom Haws proved to be correct. The variables for a SELECT INTO statement have to be user-defined.
I edited my code to use cursors, and user-defined variables as followed:

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 ;

And now I get an other error that I really can't explain:

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near '; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN articlecursor; W' at line 6

This error confuses me because it can't have a problem with the handler. The handler is declared as in the example of the mysql-documentation. Could the problem be that I can't create two cursors like this?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文