【问题标题】:Why an ENUM("0", "1") is saved as an empty string in Mysql?为什么 ENUM("0", "1") 在 Mysql 中保存为空字符串?
【发布时间】:2010-11-27 14:00:44
【问题描述】:

我有一个 MYSQL 表,其中包含一个名为“offset”的 ENUM 字段和一些其他列。该字段定义为:

ENUM(0,1),可以是NULL,预定义值NULL

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

第一步:应用程序在不通过 CREATE 查询中的“offset”的情况下创建记录。

第二步:应用程序向用户询问一些数据(不是“偏移”值),读取在第一步中插入的行并创建一个数组,更新一些字段(不是“偏移” " 字段),以自动方式创建查询并使用更新的值再次保存该行。

自动查询构建器简单地读取数组中传递的所有字段并创建 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?

【问题讨论】:

    标签: php mysql enums null


    【解决方案1】:

    为什么一个系统给我一个错误而另一个系统保存字段?是配置不同吗?

    大概吧。见下文。

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

    根据MySQL ENUM documentation

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

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

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

    (已添加重点。)

    【讨论】:

      【解决方案2】:

      strager 的回答似乎很好地解释了为什么您的代码在 2 个环境中表现不同。

      问题出在其他地方。如果您想在查询中将值设置为 NULL,您应该完全使用 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
      

      一些 DB 层,比如 PDO,可以很好地处理这个问题。

      【讨论】:

      • +1 因为这正是解决“环境”差异并完全避免错误生成的查询后我会问的关于转义空值的附带问题的答案
      • @Massimiliano Torromeo 它正在使用准备好的语句。我已经完成了在枚举类型字段中存储 NULL 的任务。感谢您分享此“某些 DB 层,例如 PDO,可以很好地处理这个问题。”陈述。我从这个声明中得到了答案。你拯救了我的一天。
      【解决方案3】:

      如果你希望它是NULL,你为什么不首先这样做:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-02
        • 2020-02-23
        • 1970-01-01
        • 2020-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多