SQL列定义:默认值而不是空冗余?

时间:2012-08-08 10:05:18

标签: sql default-value ddl notnull

我多次看到以下语法定义了create / alter DDL语句中的列:

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) NOT NULL DEFAULT "MyDefault"

问题是:由于指定了默认值,是否还需要指定列不应接受NULL?换句话说,DEFAULT不会呈现NOT NULL冗余吗?

6 个答案:

答案 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 NULLDEFAULT不是多余的。特别是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 NULLNULLDEFAULT应始终在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,但改为使用默认值。

db<>fiddle demo

ON 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');

ALTER TABLE

<块引用>

ON NULL

如果您指定 ON NULL 子句,则 Oracle 数据库将分配 DEFAULT 列值,当随后的 INSERT 语句尝试 分配一个计算结果为 NULL 的值。

当您指定 ON NULL 时,NOT NULL 约束和 NOT DEFERRABLE 约束状态是隐式指定的。如果您指定一个内联 与 NOT NULL 和 NOT DEFERRABLE 冲突的约束,然后是 出现错误。