如何在SQL中正确设置默认值?

时间:2017-02-02 06:08:35

标签: sql kognitio-wx2

我有一个表,根本不应该有任何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   

1 个答案:

答案 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 ServerMySQLPostgresFirebird的类似问题 DEFAULT ON NULL。 Oracle确实有一个非标准的语法来创建具有whereHas()的表列,它可以做你想要的。

(Kognitio可能会在复合表达式中添加DEFAULT,或者在将来的版本中将DEFAULT ON NULL添加为扩展名。)