我多次看到以下语法在创建/更改 DDL 语句中定义列:
ALTER TABLE tbl ADD COLUMN col VARCHAR(20) NOT NULL DEFAULT "MyDefault"
问题是:既然指定了默认值,是否还需要指定该列不应接受 NULL ?换句话说, DEFAULT 不会使 NOT NULL 变得多余吗?
我多次看到以下语法在创建/更改 DDL 语句中定义列:
ALTER TABLE tbl ADD COLUMN col VARCHAR(20) NOT NULL DEFAULT "MyDefault"
问题是:既然指定了默认值,是否还需要指定该列不应接受 NULL ?换句话说, DEFAULT 不会使 NOT NULL 变得多余吗?
DEFAULT
是在插入/更新语句中没有显式值的情况下将插入的值。让我们假设,您的 DDL 没有NOT NULL
约束:
ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT 'MyDefault'
然后你可以发出这些声明
-- 1. This will insert 'MyDefault' into tbl.col
INSERT INTO tbl (A, B) VALUES (NULL, NULL);
-- 2. This will insert 'MyDefault' into tbl.col
INSERT INTO tbl (A, B, col) VALUES (NULL, NULL, DEFAULT);
-- 3. This will insert 'MyDefault' into tbl.col
INSERT INTO tbl (A, B, col) DEFAULT VALUES;
-- 4. This will insert NULL into tbl.col
INSERT INTO tbl (A, B, col) VALUES (NULL, NULL, NULL);
或者,您也可以根据SQL-1992标准使用DEFAULT
in语句:UPDATE
-- 5. This will update 'MyDefault' into tbl.col
UPDATE tbl SET col = DEFAULT;
-- 6. This will update NULL into tbl.col
UPDATE tbl SET col = NULL;
请注意,并非所有数据库都支持所有这些 SQL 标准语法。添加NOT NULL
约束将导致 statements 错误4, 6
,而1-3, 5
仍然是有效的 statements。所以回答你的问题:不,它们不是多余的。
即使使用默认值,您也始终可以使用 覆盖列数据null
。
该NOT NULL
限制不允许您在使用null
值创建该行后更新该行
我的 SQL 老师说,如果你同时指定一个DEFAULT
值 and NOT NULL
or NULL
,DEFAULT
应该总是在NOT NULL
or之前表示NULL
。
像这样:
ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT "MyDefault" NOT NULL
ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT "MyDefault" NULL
我会说不是。
如果该列确实接受空值,那么没有什么可以阻止您在字段中插入空值。据我所知,默认值仅适用于创建新行。
如果设置了 not null,则不能在字段中插入 null 值,因为它会引发错误。
将其视为防止空值的故障安全机制。
换句话说, DEFAULT 不会使 NOT NULL 变得多余吗?
不,这不是多余的。扩展接受的答案。对于可为空的列col
,即使定义了 DEFAULT,我们也可以插入 NULL:
CREATE TABLE t(id INT PRIMARY KEY, col INT DEFAULT 10);
-- we just inserted NULL into column with DEFAULT
INSERT INTO t(id, col) VALUES(1, NULL);
+-----+------+
| ID | COL |
+-----+------+
| 1 | null |
+-----+------+
Oracle 为这种情况引入了额外的语法,以使用 default 覆盖显式 NULL DEFAULT ON NULL
:
CREATE TABLE t2(id INT PRIMARY KEY, col INT DEFAULT ON NULL 10);
-- same as
--CREATE TABLE t2(id INT PRIMARY KEY, col INT DEFAULT ON NULL 10 NOT NULL);
INSERT INTO t2(id, col) VALUES(1, NULL);
+-----+-----+
| ID | COL |
+-----+-----+
| 1 | 10 |
+-----+-----+
在这里,我们尝试插入 NULL 但取而代之的是默认值。
如果您指定 ON NULL 子句,则当后续 INSERT 语句尝试分配一个评估为 NULL 的值时,Oracle 数据库将分配 DEFAULT 列值。
当您指定 ON NULL 时,将隐式指定 NOT NULL 约束和 NOT DEFERRABLE 约束状态。
对于自 12c 以来的 Oracle,您有DEFAULT ON NULL
这意味着NOT NULL
约束。
ALTER TABLE tbl ADD (col VARCHAR(20) DEFAULT ON NULL 'MyDefault');
开空
如果您指定 ON NULL 子句,则当后续 INSERT 语句尝试分配一个评估为 NULL 的值时,Oracle 数据库将分配 DEFAULT 列值。
当您指定 ON NULL 时,将隐式指定 NOT NULL 约束和 NOT DEFERRABLE 约束状态。如果您指定与 NOT NULL 和 NOT DEFERRABLE 冲突的内联约束,则会引发错误。