我多次看到以下语法在创建/更改 DDL 语句中定义列:
ALTER TABLE tbl ADD COLUMN col VARCHAR(20) NOT NULL DEFAULT "MyDefault"
问题是:既然指定了默认值,是否还需要指定该列不应接受
NULL
s?换句话说,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);
或者,您也可以在
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
仍然是有效的语句。所以回答你的问题:不,它们不是多余的。
即使使用默认值,您也可以随时使用
null
覆盖列数据。
NOT NULL
限制不允许您在使用 null
值创建该行后更新该行
我的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 为这种情况引入了额外的语法,以使用默认值覆盖显式 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 子句,则 Oracle 数据库将分配 后续 INSERT 语句尝试时的 DEFAULT 列值 分配一个评估为 NULL 的值。
当你指定 ON NULL 时,NOT NULL 约束和 NOT DEFERRABLE 约束状态是隐式指定的。如果您指定内联 与 NOT NULL 和 NOT DEFERRABLE 冲突的约束,则 出现错误。
换句话说,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
允许您插入数据而不指定特定字段的值,它们是不同的。