【发布时间】:2018-11-30 05:19:47
【问题描述】:
Oracle 中是否有任何方法可以设置默认列值时 NULL 仅用于新插入?如果现有记录为 NULL,我不想更改它们。
我想在表级别执行此操作。不使用 NVL 插入逻辑。
【问题讨论】:
-
你的问题其实和this answer很像,不过我也在下面给出了答案。
Oracle 中是否有任何方法可以设置默认列值时 NULL 仅用于新插入?如果现有记录为 NULL,我不想更改它们。
我想在表级别执行此操作。不使用 NVL 插入逻辑。
【问题讨论】:
据我所知,如果您更改表并为列设置默认值,它应该只会影响将通过插入进入的 新 记录,而不是现有记录。
ALTER TABLE yourTable MODIFY (col VARCHAR(100) DEFAULT 'some value');
使用上述方法,已经NULL 的col 值应该保持NULL,至少从插入的角度来看不会改变那些NULL 值。而新插入的未指定col 值的记录应接收默认值some value。
【讨论】:
这是一个演示,展示了正在发生的事情。
首先,一个测试表和一些插入:
SQL> create table test (id number, col varchar2(10));
Table created.
SQL> insert into test (id, col) values (1, null);
1 row created.
SQL> insert into test (id, col) values (2, 'Littlefoot');
1 row created.
SQL> select * from test;
ID COL
---------- ----------
1
2 Littlefoot
更改表格,使新添加的行包含 COL 列的“某些值”:
SQL> alter table test modify col default 'some value';
Table altered.
好的;现在,故事的重要部分:注意以下几点:
SQL> -- this won't work as you wanted, because I explicitly inserted NULL into COL
SQL> insert into test (id, col) values (3, null);
1 row created.
SQL> -- this will work, because COL is omitted from the INSERT statement
SQL> insert into test (id) values (4);
1 row created.
SQL> select * From test;
ID COL
---------- ----------
1
2 Littlefoot
3
4 some value
SQL>
看到了吗?如果你明确地将 NULL 放入列中,它将不会获得默认值。
但是,如果您使用的是 12c(我知道,您不是 - 只是说,以供将来参考),还有另一种选择:DEFAULT ON NULL。它是这样的:
SQL> alter table test modify col default on null 'some value';
alter table test modify col default on null 'some value'
*
ERROR at line 1:
ORA-02296: cannot enable (SCOTT.) - null values found
哎呀!如果列中有 NULL,则不起作用。我知道 #2 你不想修改现有的行,但是 - 对于这个演示,我会这样做:
SQL> update test set col = 'x' where col is null;
2 rows updated.
SQL> alter table test modify col default on null 'some value';
Table altered.
好的;让我们看看它是如何表现的:我明确地将 NULL 插入到列中。在前面的示例中,它没有在其中放置“一些值”,而是将其保留为 NULL。现在怎么样?
SQL> insert into test (id, col) values (5, null);
1 row created.
SQL> select * From test;
ID COL
---------- ----------
1 x
2 Littlefoot
3 x
4 some value
5 some value
不错;我们在列中有“一些价值”。
现在你有更多关于这个问题的信息;看看有没有帮助。
【讨论】:
正如 Littlefoot 所提到的,如果您明确地将 NULL 放入列中,它将不会获得默认值。
如果插入查询中的列没有提及值,则使用DEFAULT。但是,显式 NULL 会覆盖默认表达式。
对于 12c 及更高版本,您可以使用 DEFAULT ON NULL 选项。
对于以前的版本,据我所知,唯一的方法是通过 TRIGGER 复制该功能
CREATE TABLE YOURTABLE ( yourcolumn VARCHAR(100) );
CREATE OR REPLACE TRIGGER trg_mod_yourtabcol BEFORE
INSERT ON yourtable
FOR EACH ROW
WHEN ( new.yourcolumn IS NULL )
BEGIN
:new.yourcolumn := 'SOME DEFAULT VALUE';
END;
/
INSERT INTO YOURTABLE(yourcolumn) VALUES(NULL);
select * from YOURTABLE;
Table YOURTABLE created.
Trigger TRG_MOD_YOURTABCOL compiled
1 row inserted.
YOURCOLUMN
----------------------------------------------------------------------------------------------------
SOME DEFAULT VALUE
1 row selected.
【讨论】: