SQL Column definition: default value and not null redundant?

问题描述 投票:0回答:7

我多次看到以下语法在创建/更改 DDL 语句中定义列:

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

问题是:既然指定了默认值,是否还需要指定该列不应接受

NULL
s?换句话说,
DEFAULT
不会使
NOT NULL
变得多余吗?

sql ddl
7个回答
160
投票

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

或者,您也可以在

DEFAULT
语句中使用
UPDATE
,根据SQL-1992标准:

-- 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
仍然是有效的语句。所以回答你的问题:不,它们不是多余的。


28
投票

即使使用默认值,您也可以随时使用

null
覆盖列数据。

NOT NULL
限制不允许您在使用
null
值创建该行后更新该行


4
投票

我的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


3
投票

我会说不是。

如果该列确实接受空值,那么没有什么可以阻止您将空值插入该字段。据我所知,默认值仅适用于创建新行。

不设置空值,那么你不能在字段中插入空值,因为它会抛出错误。

将其视为防止空值的故障安全机制。


2
投票

换句话说,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 为这种情况引入了额外的语法,以使用默认值覆盖显式 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 但取而代之的是默认值。

db<>小提琴演示

如果您指定了 ON NULL 子句,那么当后续的 INSERT 语句试图分配一个评估为 NULL 的值时,Oracle 数据库将分配 DEFAULT 列值。

当你指定ON NULL时,隐式指定了NOT NULL约束和NOT DEFERRABLE约束状态。


0
投票

对于自 12c 以来的 Oracle,您有

DEFAULT ON NULL
这意味着
NOT NULL
约束。

ALTER TABLE tbl ADD (col VARCHAR(20) DEFAULT ON NULL 'MyDefault');

修改表

如果指定 ON NULL 子句,则 Oracle 数据库将分配 后续 INSERT 语句尝试时的 DEFAULT 列值 分配一个评估为 NULL 的值。

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


0
投票

换句话说,DEFAULT 不会使 NOT NULL 变得多余吗?

不,他们不是。

NOT NULL
只是表示您不能向该列插入 NULL,而
DEFAULT
使您可以在没有指定值的情况下向由
DEFAULT
修饰的字段插入数据。


例如,有一张桌子:

CREATE TABLE `test_table` (
    `id` int NOT NULL AUTO_INCREMENT,
    `age` int,
    `name` VARCHAR(20) NOT NULL,
    PRIMARY KEY (`id`)
);

你可能认为

NOT NULL
会阻止你像下面那样做:

insert into test_table (age) value (10);

但是你错了,在这种情况下,MySQL会报错

Field 'name' doesn't have a default value
.

如果你这样做如下:

insert into test_table (age, name) value (10, NULL);

mysql会报错

Column 'name' cannot be null
.

所以,NOT NULL 只是阻止您向该字段插入

NULL
值,而
DEFAULT
允许您插入数据而不指定特定字段的值,它们是不同的。

© www.soinside.com 2019 - 2024. All rights reserved.