【发布时间】:2012-08-05 10:12:47
【问题描述】:
我已经多次看到以下在创建/更改 DDL 语句中定义列的语法:
ALTER TABLE tbl ADD COLUMN col VARCHAR(20) NOT NULL DEFAULT "MyDefault"
问题是:既然指定了默认值,是否还需要指定该列不应接受 NULL ?换句话说,DEFAULT 不渲染 NOT NULL 是多余的吗?
【问题讨论】:
标签: sql default-value ddl notnull
我已经多次看到以下在创建/更改 DDL 语句中定义列的语法:
ALTER TABLE tbl ADD COLUMN col VARCHAR(20) NOT NULL DEFAULT "MyDefault"
问题是:既然指定了默认值,是否还需要指定该列不应接受 NULL ?换句话说,DEFAULT 不渲染 NOT NULL 是多余的吗?
【问题讨论】:
标签: sql default-value ddl notnull
即使使用默认值,您也始终可以使用null 覆盖列数据。
NOT NULL 限制不允许您在使用 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 标准在UPDATE 语句中使用DEFAULT:
-- 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 约束将导致语句4, 6 出错,而1-3, 5 仍然是有效语句。所以回答你的问题:不,它们不是多余的。
【讨论】:
我会说不是。
如果该列确实接受空值,那么没有什么可以阻止您在字段中插入空值。据我所知,默认值仅适用于创建新行。
如果设置了非空值,则不能在字段中插入空值,因为它会引发错误。
将其视为防止空值的故障安全机制。
【讨论】:
我的SQL老师说过,如果同时指定DEFAULT值和NOT NULL或NULL,DEFAULT应该总是在NOT NULL或NULL之前表达。
像这样:
ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT "MyDefault" NOT NULL
ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT "MyDefault" 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 ON NULL 覆盖显式 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 子句,则 Oracle 数据库会在后续 INSERT 语句尝试分配计算结果为 NULL 的值时分配 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 子句,则 Oracle 数据库分配 DEFAULT 列值,当随后的 INSERT 语句尝试 分配一个计算结果为 NULL 的值。
当您指定 ON NULL 时,NOT NULL 约束和 NOT DEFERRABLE 约束状态是隐式指定的。如果您指定内联 与 NOT NULL 和 NOT DEFERRABLE 冲突的约束,然后是 引发错误。
【讨论】: