当我运行以下更新查询时,出现奇怪的“截断不正确的整数值”错误:
update tbl
set projectNumber = right(comments, 7)
where createdBy = 'me'
and length(CONVERT(right(comments, 7), SIGNED INTEGER)) = 7
and CONVERT(right(comments, 7), SIGNED INTEGER) > 0
and CONVERT(right(comments, 7), SIGNED INTEGER) is not null
and createdOn > '2011-01-31 12:00:00'
and projectNumber is null
项目编号为 varchar(10)。
当我作为直接选择运行它时,我没有收到错误,并且看到了预期的结果。 有什么想法吗? 本质上,我正在尝试更新projectNumber字段,其中导入注释中的注释末尾是7个数字字符(但projectNumber不是always7个数字,这就是该字段是varchar(10)的原因)。
这不是一个错误。当您要求 CONVERT() 将非数字转换为整数时,这是来自 CONVERT() 的警告;
在控制台中运行这些查询以查看:
mysql> SELECT CONVERT(right('1s23d45678', 7), SIGNED INTEGER);
+-------------------------------------------------+
| CONVERT(right('1s23d45678', 7), SIGNED INTEGER) |
+-------------------------------------------------+
| 3 |
+-------------------------------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> SHOW WARNINGS;
+---------+------+----------------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------------+
| Warning | 1292 | Truncated incorrect INTEGER value: '3d45678' |
+---------+------+----------------------------------------------+
1 row in set (0.00 sec)
正如我所说,这是警告,而不是错误。您的查询应该正确执行更新。
正如其他答案中所述,这是截至 2019 年的错误,它会阻止查询运行。即使存在无法转换为数字的字符串也要运行查询,只需使用
UPDATE IGNORE
。
例如原始代码的最小版本:
UPDATE IGNORE tbl
SET projectNumber = RIGHT(comments, 7)
WHERE CONVERT(RIGHT(COMMENTS, 7), SIGNED INTEGER) > 0
此警告的另一个常见原因是要转换的字符串中存在空格。 在
trim()
之前使用 convert()
可以消除它。
我找到了一种解决方案,它是开箱即用的并且可以轻松实施。 该解决方案与 MS SQL Server 中的
SET ANSI_WARNING OFF
非常相似。
在 MySQL 中,首先需要使用以下命令检查“sql_mode”是否设置了哪些配置:
SHOW VARIABLES LIKE 'sql_mode';
或者使用下面的方法:
SELECT @@GLOBAL.sql_mode;
CSV 中可能有以下几组值。
ONLY_FULL_GROUP_BY、STRICT_TRANS_TABLES、NO_ZERO_IN_DATE、NO_ZERO_DATE、ERROR_FOR_DIVISION_BY_ZERO、NO_ENGINE_SUBSTITUTION
根据您的错误,您可以使用以下命令删除设置并重置它:
SET GLOBAL sql_mode = 'ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
通过使用上面的命令来重置它。在我的例子中,它解决了类似的问题“截断了不正确的整数值”。我希望其他也面临此问题的用户也能使用它。
有关此“sql_mode”的更多详细信息,请参阅this。
希望这能充分利用!
如果您对列数据使用文本类型,并且尝试将默认值设置为
0
,则只需将其设置为 NULL
:
ALTER TABLE `__table__`
CHANGE `__column_name__old__` `__column_name__new__`
INT(4) NOT NULL DEFAULT '0';
Toby Speight 在他的回答中概述了该问题的一种解决方案。 我不知道是否有人会像我一样愚蠢,但这可能与谁有关:
我尝试将列
IsDeleted
的数据类型从 VARCHAR ('Y' => true, 'N' => false) 修改为 BIT,收到错误代码 1292。
要解决该问题:将所有“Y”更新为“1”(
UPDATE table SET isDeleted = '1' WHERE isDeleted = 'Y'
)并将所有“N”更新为“0”,尝试再次修改列类型,瞧数据类型已修改,加上“1”列包含 TRUE 和反之-现在反之亦然。
感谢@bhavesh-harsora,我通过更新sql_mode修复了错误。 错误是由 sql 模式下的
STRICT_TRANS_TABLES
此标志引起的。
另外,当我删除这个标志时 错误信息已更改
来自:“错误代码:1292。截断不正确的整数值:''”
to:“2333 行受影响,1024 条警告:1292 截断的不正确 INTEGER 值:'' .......”。
因此,据我了解,删除此标志会将一些错误转换为警告。
奇怪的是,当我运行
DELETE
查询时,我遇到了此错误,但是当我以相同条件运行 SELECT
查询时,我没有收到此错误。
DELETE pv
FROM table_a AS pv
INNER JOIN table_b AS ws ON pv.ws_id = ws.id
INNER JOIN table_c AS w ON w.product_id = pv.product_id
INNER JOIN table_d ppp_l ON ppp_l.id = 7002 and ppp_l.product_id = w.product_id
WHERE CAST(ppp_l.value as UNSIGNED) < CAST(ws.value as UNSIGNED);
但是 SELECT 查询运行时没有任何错误:
SELECT
pv.id
FROM table_a AS pv
INNER JOIN table_b AS ws ON pv.ws_id = ws.id
INNER JOIN table_c AS w ON w.product_id = pv.product_id
INNER JOIN table_d ppp_l ON ppp_l.id = 7002 and ppp_l.product_id = w.product_id
WHERE CAST(ppp_l.value as UNSIGNED) < CAST(ws.value as UNSIGNED)
这里也提到了这个问题:https://bugs.mysql.com/bug.php?id=76353
我不知道这是否会对任何人有帮助,但就我而言,我有一个更新后触发器,它无法写入需要“整数”值的不同表,尽管原始表具有 LONGTEXT。