当枚举字段设置为无效值时,使MySQL默认为NULL

4
有没有一种方法可以使MySQL在枚举字段设置为无效值时默认为NULL?
此外,我能否指定一个HTML表单中的值,以便在保存到数据库时将其存储为空值?我不想进行任何检查,例如“如果是空字符串,则保存为空”。如果可能的话,这是一个好主意吗?是否存在安全问题?
我的情况是:我有一个HTML下拉菜单,其中包含一个“null”选项,后跟与DB的枚举相对应的项目列表。当选择并保存null选项时,我希望它在DB中反映为NULL。现在,它被转换为空字符串,如下所示: “如果将无效值(即未出现在允许值列表中的字符串)插入ENUM,则插入空字符串作为特殊错误值。该字符串可以通过该字符串具有数字值0来与“正常”空字符串区分开来。”

http://dev.mysql.com/doc/refman/5.5/en/enum.html


在你的枚举中创建一个值,表示“未选择”。 - MatBailie
不是我想要的方式。这对应用程序来说太麻烦了。 - StackOverflowNewbie
添加一个触发器,将所有的0字符串(无效值标记)替换为NULL。 - MatBailie
是否可以创建一个触发器,用于替换所有表中所有枚举类型的0字符串?在进行插入/更新之前,我最好先进行“如果为空字符串,则保存NULL”检查吗? - StackOverflowNewbie
1个回答

9
如果一个ENUM列被声明为允许NULL,那么NULL值是该列的有效值,并且默认值为NULL。如果一个ENUM列被声明为NOT NULL,则其默认值是允许值列表中的第一个元素。因此,如果您在INSERT语句中没有为字段设置值,并且已将ENUM字段声明为接受NULL,则它将默认为NULL。
【编辑】
针对您的评论,如果您有这个表定义:
CREATE TABLE IF NOT EXISTS `tbl_test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `type` enum('New','Done') DEFAULT NULL,
  PRIMARY KEY (`id`)
)

你的Web应用程序正在尝试使用以下方式更新现有记录
UPDATE `test`.`tbl_test` SET `type` = NULL WHERE `tbl_test`.`id` =1

它将把值设置为NULL。

您可以通过查询表格中可能的ENUM值来减少在HTML下拉列表中出现无效枚举数据的风险,以在下拉列表中显示。 这里是我找到的一个Php示例

SHOW COLUMNS FROM `tbl_test` WHERE Field = 'type'

[编辑]

回答您的附加评论,如果您希望用户能够选择一个NULL值并允许一个空字符串作为有效值,您需要像这样指定您的下拉菜单:

<select>
  <option value="-1">-- not selected ---</option>
  <option value=""></option>
  <option value="Book">Book</option>
  <option value="Music">Music</option>
</select>

通过使用<option value= ...>属性,您可以控制POST到您的WebApp的值,并相应地进行处理。在这个例子中,一个值为-1的选项将被您的WebApp翻译成NULL。

允许NULL,NULL是默认值。我认为这个摘录并没有涉及到当插入无效值时默认值为NULL的情况。而且我正在为这个字段设置一个值;它来自HTML表单。我不需要对“坏”数据进行验证——实际上我希望HTML表单能够将该字段设置为NULL。 - StackOverflowNewbie
我已经编辑了我的答案,添加了一个代码示例。也许我从你的问题中漏掉了什么,但是你的问题实际上与你的Web应用程序如何处理数据有关。 - Brad
是的,我明白SET type = NULL会将字段值设置为NULL。问题是我从HTML表单中获取我的值。有没有办法从HTML表单发送一个NULL?如果没有,我该如何让MySQL接受无效的ENUM值并将字段默认为NULL? - StackOverflowNewbie
好的,你的WebApp需要处理提交的数据,并将空字符串值转换为NULL值。你能够进行这个更改吗? - Brad
可以的,只是会有点繁琐。本来希望有一个更简单的解决方案。 - StackOverflowNewbie
更新的答案。如果HTML表单POST包括该字段,则必须发送一个值。您的Web应用程序将需要检查特定的值并在调用UPDATE之前将其转换为NULL。 - Brad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接