2016-11-23 82 views
0

我的程序有問題。我嘗試從銷售表中獲取值並使用它們進行查詢。 過程是這樣的:程序中的MySQL錯誤「截斷不正確的DOUBLE值」

DROP PROCEDURE IF EXISTS turnover; 

DELIMITER $$ 

CREATE PROCEDURE turnover() 
BEGIN 
    DECLARE col INT; 
    DECLARE q TEXT; 
    DECLARE i INT DEFAULT 0; 
    DECLARE m TEXT; 
    SET col = (SELECT count(DISTINCT article) FROM sales); 
    SET q = "SELECT article, "; 
    WHILE i < co DO 
     SET m = (SELECT DISTINCT month FROM sales LIMIT 1 OFFSET i); 
     SET q = q + "SUM(IF(month=" + m + ",value,NULL)) AS " + m; 
     IF i < (col - 1) THEN 
      SET q = q + ", "; 
     END IF; 
     SET i = i + 1; 
    END WHILE; 
    SET q = q + " FROM sales GROUP BY article"; 
    EXECUTE q; 
END$$ 

DELIMITER ; 

CALL turnover(); 

我收到錯誤:

錯誤代碼:1292截斷不正確DOUBLE值: '值,NULL))AS'

我怎樣才能使它工作?

謝謝。

+0

不知道這是否是你的問題,但應該這一行「WHILE我 JanR

+0

這很難說清楚。你爲什麼不記錄生成的語句?順便說一句,這可能甚至不需要存儲過程。 – e4c5

+0

這個問題與我的MySQL Workbench有什麼關係? – axiac

回答

1

col問題在下面修復或假定。

CREATE SCHEMA safe_Tuesday_01; -- safe sandbox 
USE safe_Tuesday_01; -- DO the work in this db to test it 

-- a fake table, we need something 
create table sales 
( article varchar (100) not null, 
    month int not null 
); 

步驟1,找出字符串的樣子:

DROP PROCEDURE IF EXISTS turnover; 
DELIMITER $$ 
CREATE PROCEDURE turnover() 
BEGIN 
    DECLARE col INT; 
    DECLARE q TEXT; 
    DECLARE i INT DEFAULT 0; 
    DECLARE m TEXT; 
    SET col = (SELECT count(DISTINCT article) FROM sales); 
    SET q = "SELECT article, "; 
    WHILE i < col DO 
     SET m = (SELECT DISTINCT month FROM sales LIMIT 1 OFFSET i); 
     SET q = CONCAT(q,"SUM(IF(month=" + m + ",value,NULL)) AS ", m); 
     IF i < (col - 1) THEN 
      SET q = q + ", "; 
     END IF; 
     SET i = i + 1; 
    END WHILE; 
    SET q = CONCAT(q," FROM sales GROUP BY article"); 
    select q; 
    -- EXECUTE q; -- No no no this is wrong anyway 
END$$ 
DELIMITER ; 

CALL turnover(); 

SELECT article, FROM sales GROUP BY article

那麼這上面SELECT看起來不那麼熱。反覆修復第1步中的邏輯以修復該字符串。

第2步,當你修復上面的代碼,在下面噗噗。請注意,目前,它不是固定的。所以,再次,上面。

但在下面,請使用適當的PREPARED STATEMENT,而不是。

DROP PROCEDURE IF EXISTS turnover; 
DELIMITER $$ 
CREATE PROCEDURE turnover() 
BEGIN 
    DECLARE col INT; 
    DECLARE q TEXT; 
    DECLARE i INT DEFAULT 0; 
    DECLARE m TEXT; 
    SET col = (SELECT count(DISTINCT article) FROM sales); 
    SET q = "SELECT article, "; 
    WHILE i < col DO 
     SET m = (SELECT DISTINCT month FROM sales LIMIT 1 OFFSET i); 
     SET q = CONCAT(q,"SUM(IF(month=" + m + ",value,NULL)) AS ", m); 
     IF i < (col - 1) THEN 
      SET q = q + ", "; 
     END IF; 
     SET i = i + 1; 
    END WHILE; 
    SET q = CONCAT(q," FROM sales GROUP BY article"); 
    -- select q; 
    SET @theSQL=q; 
    PREPARE stmt1 FROM @theSQL; 
    EXECUTE stmt1; 
    DEALLOCATE PREPARE stmt1; 
END$$ 
DELIMITER ; 

完成後,

DROP SCHEMA safe_Tuesday_01; -- clean up, poof, sandbox is gone 

CONCAT是你的朋友。你錯過了這一步。 PREPARE對於用戶變量(帶有@符號)而不是本地變量(來自DECLARE)是非常重要的,否則它將炸燬。所以我用@theSQL

修正了上面的問題,再次參見MySQL Manual Page PREPARE Syntax。重要的是讓你的字符串正確。這是步驟1的要點。只有這樣,才能進入步驟2並使用它。

+0

一個深思熟慮的答案 – e4c5

0

它發生在SELECT DISTINCT month FROM sales不返回任何東西。在下一行中,查詢片段生成爲SUM(IF(month=,value,NULL)) AS,當然,那裏有一個錯誤(也許MySQL不會產生正確的錯誤消息,但這是錯誤發生的地方)。

而導致錯誤的是WHILE行,它將i與未知變量co進行比較。它可能應該閱讀:

WHILE i < col DO 

但由於colarticle不同值的數量不解決這個問題,你從1迭代,以col超過month不同值。最有可能的是它們的數量不同,如果文章的數量更大,那麼錯誤將再次發生。

相關問題