我有一个表,根本不应该有任何NULL值。当我设置NOT NULL约束时,它会禁止该语句,并且它会因约束错误而失败。仅当insert语句中未引用该列时,才会发生默认约束。
我们怎样才能解决这个问题?如果insert语句的任何列都具有NULL值,则必须使用DEFAULT值而不是NULL值。
create table temp1 (col0 int, col1 int default 0);
insert into temp1 (col0) values (1); --> col0 -> 1 and col1 ->0
insert into temp1 (col0,col1) values (1,NULL); --> col0 -> 1 and col1 -> NULL (I would expect a 0 here instead of NULL)
alter table temp1 (add column col2 int not null default 0); --> col2 -> 0 for all the existing rows
insert into temp1 (col0) values (2); --> col0 -> 2 and col1 ->0 and col2-> 0
select * from temp1;
COL0 |COL1 |COL2
1 |0 |0
1 |(null) |0
2 |0 |0
答案 0 :(得分:2)
将NULL转换为列的插入默认值不是标准SQL的一部分。
如您所见,您可以省略insert语句中的列,但这与插入NULL值不同。相反,实际上,列的DEFAULT的默认值为NULL(SQL92 13.8 General Rules 4b);这就是为什么如果没有明确的默认定义,插入默认值会给出NULL。
您也可以包含该列并使用关键字DEFAULT(SQL92 7.1 General Rules 2)。 WX2目前不支持此语法,但Kognitio计划在即将发布的版本8.2中添加它。
insert into temp1 (col0, col1) values (1, DEFAULT);
标准只允许您使用DEFAULT,如上所示,而不是复合表达式或insert-select语句。
-- NOT VALID IN STANDARD SQL!
insert into temp1 (col0, col1) values (1, case when ... then 1 else DEFAULT end);
-- NOT VALID IN STANDARD SQL!
insert into temp1 (col0, col1) select C1, DEFAULT from ...;
您可以使用COALESCE()函数解决此问题。
insert into temp1 (col0, col1) select E1, COALESCE(E2, 0) from ...;
其他数据库通常不允许将NULL转换为默认值:查看SQL Server,MySQL,Postgres和Firebird的类似问题
DEFAULT ON NULL。 Oracle确实有一个非标准的语法来创建具有whereHas()
的表列,它可以做你想要的。
(Kognitio可能会在复合表达式中添加DEFAULT,或者在将来的版本中将DEFAULT ON NULL添加为扩展名。)