2010-11-27 75 views
1

我有一个名为“偏移量”和其他一些列的ENUM字段的MYSQL表。该字段被定义为:为什么ENUM(“0”,“1”)在Mysql中保存为空字符串?

ENUM(0,1),可NULL,预定值NULL

现在我有两个服务器。生产服务器和开发服务器以及用于创建和更新数据库的相同PHP脚本。

第一步:应用程序创建的记录不用其他经过在创建查询“偏移”。

第二步:应用程序要求用户的某些数据(不是“偏移”的值),读取插入在第一步中的行和制造阵列,更新一些字段(不是“偏移”字段中),以自动方式创建查询并使用更新后的值再次保存该行。

自动查询生成器简单读取数组中传递的所有字段并创建UPDATE字符串。

在两个系统中我得到这个数组:

$values = array(... 'offset' => null); 

,并将其转换中传递值的mysql_real_escape_string此相同的查询:

UPDATE MyTable SET values..., `offset` = '' WHERE id = '10'; 

现在有这个问题。当我在生产系统中启动查询时,该行被保存,在开发系统中,我得到一个错误,并且数据库表示在不保存行的情况下,偏移数据是错误的。

从phpmyadmin当我创建第一步的行时,它在偏移量字段中显示NULL。在系统中保存没有错误的字段后,它会显示一个空字符串。

两个系统都使用MySQL 5,但生产在Linux上使用5.0.51,在Windows上使用5.0.37。

的问题:

为什么一个系统给我一个错误的另一种救场?配置有差别吗?

为什么当我保存为枚举“0”或“1”的字段时,它会保存“”而不是NULL?

回答

2

为什么一个系统给我一个错误,另一个保存该字段?配置有差别吗?

也许。见下文。

为什么当我保存字段是一个枚举“0”或“1”它保存“”而不是NULL?

按照MySQL ENUM documentation

值也可能是空在某些情况下字符串( '')或NULL:

  • 如果插入无效值成ENUM(即,不存在于允许值列表中的字符串),将插入空字符串作为特殊错误值。该字符串可以通过该字符串的数值为0的事实与“正常”空字符串区分开来。...

    如果启用严格的SQL模式,则尝试插入无效的ENUM值会导致错误。

(着重号。)

0

如果你希望它是NULL,你为什么不摆在首位做到这一点:

UPDATE MyTable SET values..., `offset` = NULL WHERE id = 10; 
2

strager的答案似乎是一个很好的解释为什么你的代码在2个环境中的行为不同。

但问题在于别处。如果你想设置一个值设置为NULL在您shound使用完全相同NULL的查询,但您使用mysql_real_escape_string()的结果始终是一个字符串:

$ php -r 'var_dump(mysql_real_escape_string(null));' 
string(0) "" 

您应该区别处理这个问题。例如:

$value = null 
$escaped_value = is_null($value) ? "NULL" : mysql_real_escape_string($value); 
var_dump($escaped_value); 
// NULL 

某些数据库层(如PDO)可以为您处理这个问题。

+0

+1因为这正好是关于转义空值的问题的答案,我会问解决“环境”的差异后,完全避免错误生成的查询 – yuri 2010-11-28 09:01:26

相关问题