【问题标题】:MySQL error "Truncated incorrect DOUBLE value" in procedure程序中的 MySQL 错误“截断不正确的 DOUBLE 值”
【发布时间】:2016-11-23 00:13:33
【问题描述】:

我的程序有问题。我尝试从销售表中获取值并使用它们进行查询。 过程如下:

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 值:',value,NULL)) AS '

我怎样才能让它工作?

谢谢。

【问题讨论】:

  • 不确定这是否是您的问题,但这条线 WHILE i &lt; co DO 应该是 WHILE i &lt; col DO 吗?当您尝试将字符串与查询中某处的 int 进行比较时,通常会发生该错误。
  • 这很难说。为什么不记录生成的语句?顺便说一句,这可能甚至不需要存储过程。
  • 这个问题与我的 MySQL Workbench 有什么关系?
  • @e4c5 这是一个公平的评论。出于教育目的,无论它可能是XY Problem,我都在下面的答案中扑通一声。

标签: mysql sql mysql-error-1292


【解决方案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
);

第一步,找出字符串的样子:

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 手册页 PREPARE Syntax。正确设置字符串很重要。这就是第 1 步的重点。只有这样您才能进入第 2 步并使用它。

【讨论】:

  • 一个深思熟虑的答案
【解决方案2】:

SELECT DISTINCT month FROM sales 没有返回任何东西时会发生这种情况。在下一行,查询片段生成为SUM(IF(month=,value,NULL)) AS,当然,那里有一个错误(也许 MySQL 没有产生正确的错误消息,但这就是错误所在)。

错误的原因是WHILE 行将i 与未知变量co 进行比较。它可能应该是:

WHILE i < col DO

但这并不能解决问题,因为colarticle 的不同值的数量,并且您在month 的不同值上从1 迭代到col。很可能它们的数量不同,如果文章数量更大,那么错误将再次发生。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多