为什么CAST()在MySQL函数中无法正常工作?

时间:2016-01-26 12:47:46

标签: mysql stored-procedures

我有以下功能:

CREATE FUNCTION test_rule (value TEXT, greater_than DECIMAL(10,4))
RETURNS BOOL
RETURN greater_than IS NULL OR CAST(value AS DECIMAL(10,4)) > greater_than;

如果我将此函数与空字符串vor value一起使用,则会收到错误:

SELECT test_rule('',10)
  

(1366):十进制值不正确:''对于第-1行的列''

但是没有函数,同样的表达式可以正常工作:

SELECT '' IS NULL OR CAST('' AS DECIMAL(10,4)) > 10
  

0

为什么会这样?

我正在使用MySQL版本5.6.22

1 个答案:

答案 0 :(得分:1)

mysql处理某些数据转换的方式也受sql mode settings(特别是“严格的SQL模式”部分)和CAST functions的影响。

关于这些限制如何应用于表达式评估的文档有点模糊,但是CAST函数文档确实提到了

  

SQL模式会影响转换操作的结果。

评论中提及的sql_mode设置为STRICT_TRANS_TABLES, NO_ENGINE_SUBSTITUTION的OP。 STRICT_TRANS_TABLES表示为事务表启用了严格的sql模式,也可能用于强制转换操作。

''(空字符串)无法正确转换为数字。如果未启用严格的sql模式,则mysql会生成警告,并使用给定数字类型的默认值评估'' - 即0。但是,如果启用了严格的sql模式,则此类转换会导致错误。

您可以通过将适当的值设置为sql_mode变量来更改全局或会话级别的sql模式。

存储程序还有一个复杂问题。存储的程序使用在compile time处有效的sql模式设置运行:

  

MySQL存储sql_mode系统变量设置有效时a   例程被创建或更改,并始终执行例程   此设置有效,无论当前服务器SQL模式何时   例程开始执行。

如果您希望在不同的sql模式设置下运行不同的存储过程,那么

  1. 删除现有的存储例程
  2. 将sql模式更改为所需的设置
  3. 重新创建存储的程序
  4. 您可以通过列出INFORMATION_SCHEMA.ROUTINES表(sql_mode列)来查询任何存储例程的sql模式设置。

    但是,我会考虑在这个特定实例中重写代码,以便检查value参数是否等于''空字符串,而不是开始使用sql模式设置。问题是这些特殊的sql模式设置要求在系统更改或迁移过程中很容易被遗忘或忽略,现有的代码可能会开始抛出错误,很难重新跟踪问题的来源。