错误代码1292 - 截断不正确的DOUBLE值 - Mysql

127

我不确定这个错误是什么!

#1292 - Truncated incorrect DOUBLE value: 

我没有双值字段或数据!

我浪费了整整一个小时试图弄清楚这个问题!

这是我的查询:

INSERT INTO call_managment_system.contact_numbers 
    (account_id, contact_number, contact_extension, main_number, created_by)
SELECT
    ac.account_id,
    REPLACE(REPLACE(REPLACE(REPLACE(ta.phone_number, '-', ''), ' ', ''), ')', ''),'(','') AS Phone,
    IFNULL(ta.ext, '') AS extention,
    '1' AS MainNumber,
    '2' AS created_by
FROM 
    cvsnumbers AS ta
    INNER JOIN accounts AS ac ON ac.company_code = ta.company_code
WHERE 
    LENGTH(REPLACE(REPLACE(REPLACE(REPLACE(ta.phone_number, '-', ''), ' ', ''), ')', ''),'(','') ) = 10

这是我用来创建表格的 "show create table" 命令,它将作为结果插入到表格中。

CREATE TABLE `contact_numbers` (  
    `number_id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
    `account_id` int(10) unsigned NOT NULL DEFAULT '0',  
    `person_id` int(11) NOT NULL DEFAULT '0',  
    `contact_number` char(15) NOT NULL,  
    `contact_extension` char(10) NOT NULL DEFAULT '',  
    `contact_type` enum('Primary','Direct','Cell','Fax','Home','Reception','Office','TollFree') NOT NULL DEFAULT 'Primary',  
    `contact_link` enum('Account','PDM','Other') NOT NULL DEFAULT 'Account',  
    `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '0 = inactive, 1=active', 
    `main_number` tinyint(1) NOT NULL DEFAULT '0' COMMENT '1 = main phone number',  
    `created_on` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,  
    `created_by` int(11) NOT NULL,  
    `modified_on` datetime DEFAULT NULL,  
    `modified_by` int(11) NOT NULL DEFAULT '0',  
    PRIMARY KEY (`number_id`),  
    KEY `account_id` (`account_id`),  
    KEY `person_id` (`person_id`)
) ENGINE=InnoDB AUTO_INCREMENT=534 DEFAULT CHARSET=utf8

14
根据此程序错误报告,该消息是由于将字符串列与整数进行比较,因为它们都被转换为 double 进行比较。请问ac.company_codeta.company_code 是如何声明的? - Barmar
请参见http://bugs.mysql.com/bug.php?id=46641,其中一位发帖者建议将此错误消息重新措辞为“不允许在数字列和非数字列之间进行WHERE比较”。 - Barmar
这两列都是int(11)类型,而不是字符串! - Mike
你能否创建一个带有一些样本数据的 SQLFiddle? - Barmar
10个回答

219

这个消息意味着您正在尝试在WHEREON语句中比较数字和字符串。在您的查询中,唯一可能出现这种情况的地方是ON ac.company_code = ta.company_code;要么确保它们具有相似的声明,要么使用显式的CAST将数字转换为字符串。

如果关闭strict模式,则该错误应变为警告。


2
哇,这个错误信息真是误导人啊。谢谢你的帮助。你说得对,我需要将 DB::table('contacts')->where('attendance', $int) ->update(["attendance" => $string]); 改为 DB::table('contacts')->where('attendance', '' . $int) ->update(["attendance" => $string]); - Ryan
4
谢谢您。进一步解释:这可以通过各种方式触发。在我的情况下,是使用正则表达式从字符串中提取整数,并将其与整数进行比较。奇怪的是,当我只使用SELECT语句时,一切都很好: select xxxx from t1 inner join t2 on t1.id=substr(value,locate(':',tagvalue)+1) 但是一旦我把它转换成一个INSERT...SELECT,就会触发错误。 - xgretsch
当我使用ON DUPLICATE KEY UPDATE pk1=pk1 AND pk2=pk2时,我遇到了这个问题。将AND替换为,解决了我的问题。参考:https://dev59.com/PXA75IYBdhLWcg3wH1bP - Sai
将Where子句的值转换为字符串,工作完成,谢谢。 - Marwan

39

我纠正了这个错误,因为查询中存在语法错误或一些不需要的字符,但MySQL无法捕获。在进行更新时,我在多个字段之间使用了and,例如:

update user 
set token='lamblala', 
    accessverion='dummy' and 
    key='somekey' 
where user = 'myself'

通过用逗号(,)替换and,可以解决上述查询中的问题。


2
谢谢,这不是一个大问题,但有时候小问题会变成大问题。 - Sumit Kumar Gupta
1
非常感谢!!!这发生在更新语句的上下文中。 - KC Baltz

15
我遇到了相同的问题,试图将一个varchar(100)列与数字1进行比较,结果导致产生了1292错误。通过在1周围添加单引号('1')来解决问题。感谢上面的解释。

6

TL; DR

可能是将OR应用于字符串列/字面量引起的。

Full version

在涉及视图的简单INSERT语句中,我收到了同样的错误消息。请注意,所有表都有一个字符串列name

insert into t1 select * from v1

虽然所有的源和目标列都是VARCHAR类型。经过一些调试,我发现了问题的根本原因:该视图包含以下片段:

string_col1 OR '_' OR string_col2 OR '_' OR string_col3

以下代码片段来自Oracle,很可能是由自动转换生成的:

string_col1 || '_' || string_col2 || '_' || string_col3

|| 在 Oracle 中表示字符串连接)。解决方案是使用
concat(string_col1, '_', string_col2, '_', string_col3)

替代方案。


谢谢!作为一个MySQL的新手,我一直在使用SQL Server允许的方式进行连接,例如string1+string2+string3。您提出使用concat函数来解决这个问题的建议帮了我大忙。 - Marcy

4

我看到过一些出现这个错误的情况:

1. 在带有多个or值的where子句中使用不等运算符!=

例如:

where columnName !=('A'||'B')

这可以通过使用技术来解决。
where columnName not in ('A','B')

2. if()函数中缺少比较运算符:

select if(col1,col1,col2);

为了在 col1 中选择存在的值,否则显示 col2 中的值...这会抛出错误;可以通过以下方式解决:
select if(col1!='',col1,col2);

1
当我收到这个错误时,我认为它是一个 bug,但是你应该记住,如果你使用一个单独的查询和相同的 WHERE 子句进行 SELECT,那么你可以从那个 SELECT 语句中获取主 ID 并将它们插入到失败的 UPDATE 查询中,并带有条件“WHERE [primary_id] IN ([list of comma-separated primary ID's from the SELECT statement)”,这样可以减轻原始(失败的)查询 WHERE 子句引起的任何问题。
对于我个人而言,在“WHERE ____ IN ([values here])”中为值使用引号时,只有 10 个预期的 300 个条目受到影响,这在我看来似乎是一个 bug。

1

如果您没有双精度值字段或数据,也许您应该尝试禁用SQL严格模式。

要做到这一点,您需要编辑位于MySQL安装文件夹中的"my.ini"文件,找到"将SQL模式设置为严格"行并更改以下行:

# Set the SQL mode to strict
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

针对此问题,删除"STRICT_TRANS_TABLES"。

# Set the SQL mode to strict
sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

接下来,您必须 重新启动 MySQL 服务 以启用此更改。

要检查更改,请打开编辑器并执行此 SQL 语句:

SHOW VARIABLES LIKE 'sql_mode';

非常重要:保存文件后要注意文件格式。请将其保存为“UTF8”,而不是“带BOM的TFT8”,否则服务将无法重新启动。


1
最好是每个会话基础上这样做,或者更好的是只在修改“有问题的表”的特定脚本中进行:$pdo->query('SET SESSION SQL_MODE = "ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"'),在您的脚本完成后,以同样的方式将严格模式打开:$pdo->query('SET SESSION SQL_MODE = "STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"') - Piemol

0
如果您在表上使用了CHECK CONSTRAINT来限制字符串字段的长度

例如:检查用户名长度是否大于等于8
请使用:
CHECK (CHAR_LENGTH(username)>=8)

而不是

CHECK (username>=8)

如果有任何错误的数据类型比较,请修复检查约束


0
在我的情况下,是一个视图(高度嵌套,视图中的视图)插入导致了中的错误。
CREATE TABLE tablename AS
  SELECT * FROM highly_nested_viewname
;

我们最终采用的解决方法是模拟一个物化视图(实际上是一张表),并定期使用存储过程进行插入/更新。

0
在使用ES6和TypeORM时,我遇到了一个问题,尝试传递.where("order.id IN (:orders)", { orders }),其中orders是由逗号分隔的数字字符串。当我转换为模板文字时,问题得到解决。
.where(`order.id IN (${orders})`);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接