SQL在Procedure内执行报错

问题现象

一个直接执行可以成功(可能会报Warning)的SQL语句,在Procedure内部执行失败并报错。

例如:

一个UPDATE语句尝试将一个date属性的列值更新为空字符串:

UPDATE t1 SET start_date="" where id=2;

直接执行该语句成功并报Warning:

+---------+------+--------------------------------------------------------+
| Level   | Code | Message                                                |
+---------+------+--------------------------------------------------------+
| Warning | 1265 | Data truncated for column 'start_date' at row 2 |
+---------+------+--------------------------------------------------------+

在Procedure内部执行该语句失败并报错:

ERROR 1292 (22007): Incorrect date value: '' for column 'start_date' at row 2

可能原因

创建Procedure时,MySQL会记录当时的变量sql_mode的值,并保存在系统表mysql.proc中。Procedure运行时使用创建时的sql_mode值而非运行时的sql_mode值,如果创建时的sql_mode值比运行时的sql_mode值限制条件更多,就会出现上述问题。

在上述案例中,创建Procedure时的sql_mode值为'STRICT_TRANS_TABLES',而运行时的sql_mode值为'''STRICT_TRANS_TABLES'的限制条件比''更多,所以出现上述问题。

解决方案

可以选择以下两种解决方案:

  • 按照实际需求,重新设置sql_mode的值,然后重新创建Procedure。

  • 按照实际需求,修改已有的Procedure在mysql.proc里的sql_mode的值。

    UPDATE mysql.proc SET sql_mode='xxx' WHERE Procedure='xxx';