我多次看到以下语法定义了create / alter DDL语句中的列:
ALTER TABLE tbl ADD COLUMN col VARCHAR(20) NOT NULL DEFAULT "MyDefault"
问题是:由于指定了默认值,是否还需要指定列不应接受NULL?换句话说,DEFAULT不会呈现NOT NULL冗余吗?
答案 0 :(得分:92)
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
语句中使用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
约束将导致语句4, 6
出错,而1-3, 5
仍然是有效语句。所以回答你的问题:
不,NOT NULL
和DEFAULT
不是多余的。特别是NOT NULL
can have a tremendous impact on query performance as explained in this blog post here
答案 1 :(得分:14)
即使使用默认值,您也始终可以使用null
覆盖列数据。
NOT NULL
限制不允许您在使用null
值
答案 2 :(得分:2)
我的SQL老师说如果同时指定DEFAULT
值和NOT NULL
或NULL
,DEFAULT
应始终在NOT NULL
或{{{{}}之前表达1}}。
像这样:
NULL
ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT "MyDefault" NOT NULL
答案 3 :(得分:0)
我会说不。
如果列确实接受空值,那么没有什么可以阻止你在字段中插入空值,据我所知,默认值仅适用于创建新规则。
如果没有设置空值,则无法在字段中插入空值,因为它会引发错误。
将其视为防止空值的故障安全机制。
答案 4 :(得分:0)
换句话说,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子句,则当随后的INSERT语句尝试分配计算结果为NULL的值时,Oracle数据库将分配DEFAULT列值。
当您指定ON NULL时,隐式指定NOT NULL约束和NOT DEFERRABLE约束状态。
答案 5 :(得分:0)
对于自 12c 以来的 Oracle,您有 DEFAULT ON NULL
,这意味着 NOT NULL
约束。
ALTER TABLE tbl ADD (col VARCHAR(20) DEFAULT ON NULL 'MyDefault');
<块引用>
ON NULL
如果您指定 ON NULL 子句,则 Oracle 数据库将分配 DEFAULT 列值,当随后的 INSERT 语句尝试 分配一个计算结果为 NULL 的值。
当您指定 ON NULL 时,NOT NULL 约束和 NOT DEFERRABLE 约束状态是隐式指定的。如果您指定一个内联 与 NOT NULL 和 NOT DEFERRABLE 冲突的约束,然后是 出现错误。