为插入创建一个列 NULL,为更新创建一个 NOT NULL
Make a column NULL for insert and NOT NULL for update
这是我在多个项目中偶然发现的,每次都感觉自己在重新发明轮子:
我有一个 table 存储用户数据。每当创建用户时,我都会在 table 上创建一行。此行在创建时有几个 NULL 字段,因为用户只是告知了一些关键信息(其他非关键信息将在稍后填写)。
但是,当用户完成数据填充后,我想强制这个cols为NOT NULL。
有什么方法可以让不涉及触发器的INSERT列为NULL,而UPDATE列为NOT NULL吗?或者任何其他聪明的解决方案?
谢谢
如果您在 CREATE TABLE
语句中使用列选项,则列无法同时为 NULLable 和 NOT NULL。无法区分插入和更新。
另一种方法是让该列可以为空,但在更新后添加一个引发异常的触发器(在 MySQL 术语中称为 SIGNAL),如果该列在更新后仍然为 NULL。
这是一个快速演示:
mysql> create table mytable (id int primary key, x int);
Query OK, 0 rows affected (0.05 sec)
mysql> delimiter //
mysql> create trigger notnullonupdate before update on mytable
-> for each row
-> begin
-> if NEW.x IS NULL then
-> signal sqlstate '45000'
-> set message_text = 'x must be updated to non-NULL value';
-> end if;
-> end//
mysql> delimiter ;
mysql> insert into mytable set id = 42, x = null;
Query OK, 1 row affected (0.03 sec)
mysql> update mytable set id = 42;
ERROR 1644 (45000): x must be updated to non-NULL value
尽管这是可能的,但工作量很大。
大多数开发人员只会通过编写应用程序代码来处理此问题,以确保在执行更新之前该值不为空。当然,这样做的风险是,如果您忘记了应用程序中进行更新的情况之一,或者如果有人在 mysql 客户端中进行了临时更新,则可能会导致您的数据处于无效状态你不会知道的。
CREATE TABLE users ( regular_column SOMETYPE NOT NULL,
smart_column SOMETYPE NULL,
completed ENUM('no', 'yes') NOT NULL DEFAULT 'no',
CHECK ((completed = 'no') OR (smart_column IS NOT NULL)) );
This row has several NULL fields on creation, because the user just informed some critical information (and other non-critical info is going to be filled later).
此时completed = 'no'
,CHECK约束为TRUE,smart_column
可能为NULL。
when the user completes the filling of the data, I want to enforce this cols to be NOT NULL.
此刻 completed = 'yes'
,CHECK 约束不允许 smart_column
中的 NULL 值。
即将 completed
列设置为 'yes'
可修复 smart_column
- 您可以更改它但不能将其设置为 NULL。在 smart_column
被设置为一个值之前,您不能将 completed
设置为 'yes'
。
这是我在多个项目中偶然发现的,每次都感觉自己在重新发明轮子:
我有一个 table 存储用户数据。每当创建用户时,我都会在 table 上创建一行。此行在创建时有几个 NULL 字段,因为用户只是告知了一些关键信息(其他非关键信息将在稍后填写)。
但是,当用户完成数据填充后,我想强制这个cols为NOT NULL。
有什么方法可以让不涉及触发器的INSERT列为NULL,而UPDATE列为NOT NULL吗?或者任何其他聪明的解决方案?
谢谢
如果您在 CREATE TABLE
语句中使用列选项,则列无法同时为 NULLable 和 NOT NULL。无法区分插入和更新。
另一种方法是让该列可以为空,但在更新后添加一个引发异常的触发器(在 MySQL 术语中称为 SIGNAL),如果该列在更新后仍然为 NULL。
这是一个快速演示:
mysql> create table mytable (id int primary key, x int);
Query OK, 0 rows affected (0.05 sec)
mysql> delimiter //
mysql> create trigger notnullonupdate before update on mytable
-> for each row
-> begin
-> if NEW.x IS NULL then
-> signal sqlstate '45000'
-> set message_text = 'x must be updated to non-NULL value';
-> end if;
-> end//
mysql> delimiter ;
mysql> insert into mytable set id = 42, x = null;
Query OK, 1 row affected (0.03 sec)
mysql> update mytable set id = 42;
ERROR 1644 (45000): x must be updated to non-NULL value
尽管这是可能的,但工作量很大。
大多数开发人员只会通过编写应用程序代码来处理此问题,以确保在执行更新之前该值不为空。当然,这样做的风险是,如果您忘记了应用程序中进行更新的情况之一,或者如果有人在 mysql 客户端中进行了临时更新,则可能会导致您的数据处于无效状态你不会知道的。
CREATE TABLE users ( regular_column SOMETYPE NOT NULL,
smart_column SOMETYPE NULL,
completed ENUM('no', 'yes') NOT NULL DEFAULT 'no',
CHECK ((completed = 'no') OR (smart_column IS NOT NULL)) );
This row has several NULL fields on creation, because the user just informed some critical information (and other non-critical info is going to be filled later).
此时completed = 'no'
,CHECK约束为TRUE,smart_column
可能为NULL。
when the user completes the filling of the data, I want to enforce this cols to be NOT NULL.
此刻 completed = 'yes'
,CHECK 约束不允许 smart_column
中的 NULL 值。
即将 completed
列设置为 'yes'
可修复 smart_column
- 您可以更改它但不能将其设置为 NULL。在 smart_column
被设置为一个值之前,您不能将 completed
设置为 'yes'
。