2011-10-13 81 views
2

我試圖使用一次性查詢while循環一個MySQL(5.1.41-3ubuntu12.10-log)數據庫:WHILE語法錯誤在MySQL

WHILE ((SELECT COUNT(*) FROM 
    (SELECT id, COUNT(*) AS cnt 
     FROM foo 
     GROUP BY id 
     ORDER BY COUNT(*) DESC) cnts 
    WHERE cnt > 1) != 0) DO 
BEGIN 

SET @curr_id = (SELECT id FROM 
      (SELECT id, COUNT(*) AS cnt 
       FROM foo 
       GROUP BY id 
       ORDER BY COUNT(*) DESC) cnts 
      WHERE cnt > 1 
      LIMIT 1); 


SET @new_id = (SELECT MAX(id) + 1 
     FROM foo); 

UPDATE foo 
    SET id = @new_id 
    WHERE id = @curr_id 
    LIMIT 1; 

END WHILE;  

這樣做是同時有多個記錄使用下一個ID更新其中一個ID。

在體內的語法是正確的,在while語句中使用的謂詞還沒有執行它自己的任何麻煩。 MySQL的返回的查詢開始一個語法錯誤:

Error Code : 1064 
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 'WHILE ((SELECT count(*) FROM 
    (SELECT id, COUNT(*) AS cnt 
     FROM stock_produ' at line 1 

我知道這可能不是做事的正確方法,但是這是一個非常嚴重的(或者說不是不惜一切)思想out數據庫,所以如果我能以這種方式工作,那將是非常棒的。

感謝,

羅賓

回答

7

看起來好像你正試圖運行此程序代碼爲匿名塊。雖然這在一些數據庫(如Oracle)中起作用,但它不能在MySQL中完成。

如果你想運行這個,然後把它放在存儲過程,然後調用過程。因此:

創建過程

DELIMITER $$ 

CREATE PROCEDURE `foo_update_routine`() 
BEGIN 
    WHILE ((SELECT COUNT(*) FROM 
    (SELECT id, COUNT(*) AS cnt 
     FROM foo 
     GROUP BY id 
     ORDER BY COUNT(*) DESC 
    ) cnts 
    WHERE cnt > 1) != 0) 
    DO 
    SET @curr_id = (SELECT id FROM 
     (SELECT id, COUNT(*) AS cnt 
     FROM foo 
     GROUP BY id 
     ORDER BY COUNT(*) DESC 
    ) cnts 
     WHERE cnt > 1 
     LIMIT 1); 

    SET @new_id = (SELECT MAX(id) + 1 FROM foo); 

    UPDATE foo SET id = @new_id 
     WHERE id = @curr_id 
     LIMIT 1; 

    END WHILE; 
END $$ 

呼叫過程

CALL `foo_update_routine`; 

PS你可能想調查the HAVING clause你的SELECT語句...

+1

是的!而已!似乎有點愚蠢,你不能在沒有程序調用的情況下做到這一點。還要感謝'有'提示。我不知道那件事。 – thepandaatemyface