2012-02-11 235 views
0


我得到通過發送下面的查詢(MYSQL 5.0)的錯誤:MySQL的程序語法錯誤

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 ; 

這將產生以下錯誤:

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

任何想法,爲什麼出現這種情況?

(寫到這來創建文章和關鍵字之間的關係表,以便在文章視圖智能鏈接。)

+0

1.錯誤報告中的單詞DO和單詞片段TO是你問題的一部分的奇怪跳過? – 2012-02-11 14:55:40

+0

2.是否可能需要SELECT INTO用戶定義的變量而不是聲明的過程變量? – 2012-02-11 14:58:25

+0

你是什麼意思的「用戶定義」變量? – enigma 2012-02-11 15:43:21

回答

0

儘量去除,而標籤:

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; 
+0

我試過了,但是錯誤保持不變。 – enigma 2012-02-11 15:49:22

0

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; 

只是一個想法。

+0

好的,謝謝我會改變它,看看它是否有效。 – enigma 2012-02-14 09:16:55

0

一個問題可能是SET acticleid =(SELECT ...)。試着用SELECT .. INTO

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

可變LIMIT在存儲過程中僅在新的MySQL版本的支持。請注意,由於您沒有ORDER BY,您將得到一個隨機行。它看起來像你想用CURSOR來代替。請參閱docs

+0

感謝您的提示。我會稍後再嘗試。 – enigma 2012-02-14 09:16:21

0

在看似過分危險的情況下,我相信你應該重寫這個過程來使用遊標遍歷數據庫,而不是使用LIMIT進行單獨選擇。

看到Cursors in MySQL Docs

+0

感謝您的提示。我會稍後再嘗試。 – enigma 2012-02-14 09:15:13

0

感謝您的幫助迄今。 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 [email protected] 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 ; 

現在我得到,我真的無法解釋的其他錯誤:

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

這個錯誤讓我困惑因爲它不會對處理程序有問題。該處理程序在mysql文檔的example中聲明。問題可能是我不能創建兩個這樣的遊標?