INSERT ALL失败,触发设置时间戳记

时间:2019-03-21 20:25:58

标签: sql oracle oracle11g

假设我们有一个这样的表:

CREATE TABLE test_table 
(
    text   VARCHAR2(200) NOT NULL,
    text2  VARCHAR2(200) NOT NULL,
    ts     TIMESTAMP
);

我们想使用INSERT ALL插入一些数据:

INSERT ALL 
    INTO test_table ( text, text2 ) VALUES ( 'test', 'test2' ) 
SELECT * FROM dual;

结果是

1 row inserted.

但是,当我们要添加触发器时,用ts填充SYSTIMESTAMP

CREATE OR REPLACE TRIGGER  test_trigger
BEFORE INSERT ON  test_table
FOR EACH ROW
BEGIN
    DBMS_OUTPUT.put_line('text=' || :new.text);
    DBMS_OUTPUT.put_line('text2=' || :new.text2);
    DBMS_OUTPUT.put_line('ts=' || :new.ts);
    :new.ts := SYSTIMESTAMP;
END;
/

运行相同的脚本

SET SERVEROUT ON;
INSERT ALL 
    INTO test_table ( text, text2 ) VALUES ( 'test', 'test2' ) 
SELECT * FROM dual;

结果是:

text=test
text2=
ts=
INSERT ALL 
INTO test_table ( text, text2 ) VALUES ( 'test', 'test2' ) 
SELECT * FROM dual
Error report -
ORA-01400: cannot insert NULL into ("TEST"."TEST_TABLE"."TEXT2")

使用INSERT很好

SET SERVEROUT ON;
INSERT INTO test_table ( text, text2 ) VALUES ( 'test', 'test2' ) 

结果是

text=test
text2=test2
ts=
1 row inserted.

这也可行:

INSERT ALL 
INTO test_table ( text, text2, ts) VALUES ( 'test', 'test2', null ) 
SELECT * FROM dual

当我将ts列类型更改为DATE时,可以使用这种触发器。 我正在使用Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production,我也检查过Oracle 12c,但没有错误,所以11g版本中可能存在某种错误吗?

1 个答案:

答案 0 :(得分:3)

您的代码似乎没有问题,可能与您使用的版本有关。 就是说,您想要实现的目标通常是通过执行create table语句完成的

CREATE TABLE test_table (
    text   VARCHAR2(200) NOT NULL,
    text2   VARCHAR2(200) NOT NULL,
    ts    TIMESTAMP not null default systimestamp
);

您完全不需要触发器。