【问题标题】:Oracle SQL - Trigger inserting into table passing null value from sequenceOracle SQL - 触发器插入到表中,从序列中传递空值
【发布时间】:2019-12-06 18:40:36
【问题描述】:

我有两个表,TABLE_ATABLE_B。当某些东西被插入到 TABLE_A 中时,会有一个触发器也将数据插入到 TABLE_B 中。 TABLE_A 有一个使用序列填充的 ID 列。然后这个 id 也被插入到 TABLE_B 中。这是整个 DDL:

CREATE TABLE  "TABLE_A" 
   (    "ID" NUMBER(8,0) NOT NULL ENABLE, 
    "COLUMN1" NUMBER(8,0) NOT NULL ENABLE, 
    "COLUMN2" NUMBER(4,0) NOT NULL ENABLE
   )
/

CREATE TABLE  "TABLE_B" 
   (    "ID" NUMBER(8,0) NOT NULL ENABLE, 
    "COLUMN1" NUMBER(8,0) NOT NULL ENABLE, 
    "COLUMN2" NUMBER(4,0) NOT NULL ENABLE
   )

/   

  CREATE UNIQUE INDEX  "AID_PK" ON  "TABLE_A" ("ID")
/

ALTER TABLE  "TABLE_A" ADD CONSTRAINT "AID_PK" PRIMARY KEY ("ID")
  USING INDEX  "AID_PK"  ENABLE
/


create or replace TRIGGER my_trigger
BEFORE INSERT OR UPDATE OR DELETE ON TABLE_A
FOR EACH ROW
BEGIN
IF INSERTING THEN
INSERT INTO TABLE_B(
ID,
COLUMN1,
COLUMN2)
VALUES(
:new.ID,
:new.COLUMN1,
:new.COLUMN2);
END IF;
END;

/
ALTER TRIGGER  "my_trigger" ENABLE
/

 CREATE SEQUENCE   "MY_SEQ"  MINVALUE 1 MAXVALUE 999999999999999 INCREMENT BY 1 START WITH 5002 CACHE 20 NOORDER  NOCYCLE  NOKEEP  NOSCALE  GLOBAL;


/

CREATE OR REPLACE EDITIONABLE TRIGGER  "MYSEQ_SEQ_IOT" 
before insert on table_a
for each row
begin
select MY_SEQ.nextval into :new.id from dual;
end;

/
ALTER TRIGGER  "MYSEQ_SEQ_IOT" ENABLE
/

现在当我运行这个语句时:

INSERT INTO PER_ART(
    COLUMN1,
    COLUMN2
    )
VALUES(
    1111111,
    2222222); 

我收到此错误:

ORA-01400: cannot insert NULL into ("TABLE_B"."ID")
ORA-06512: at "my_trigger", line 7
ORA-04088: error during execution of trigger 'my_trigger'

当序列应该填充它时,为什么 ID 为空?

【问题讨论】:

  • 如果触发器被称为my_trigger 那么ALTER TRIGGER "my_trigger" ENABLE 将不起作用,因为"my_trigger"my_trigger 不同。

标签: sql oracle plsql oracle12c


【解决方案1】:

你的两个触发器触发的顺序是不确定的。在我看来,最好的解决方案是只使用一个触发器:

create or replace TRIGGER my_trigger
  BEFORE INSERT ON TABLE_A
  FOR EACH ROW
BEGIN
  select MY_SEQ.nextval
    into :new.id 
    from dual;

  INSERT INTO TABLE_B(
    ID,
    COLUMN1,
    COLUMN2)
  VALUES(
    :new.ID,    -- Or use MY_SEQ.curreval
    :new.COLUMN1,
    :new.COLUMN2);
END;

如果出于某种原因必须有两个触发器,那么您可以使用 CREATE TRIGGER 语句的 FOLLOWS 和 PRECEDES 子句来控制它们的触发顺序。有关控制触发顺序的详细信息,请参阅the documentation

【讨论】:

  • 感谢您的回复。我不知道这个。确认然后它将是每行都遵循 MYSEQ_SEQ_IOT?我已经尝试过了,它似乎有效,但我只是想确认这不是巧合,而且是正确的方法!
  • 如果它有效,那么它可能是正确的。我自己并没有真正使用过 FOLLOWS/PRECEDES 子句。
猜你喜欢
  • 2018-03-07
  • 2013-10-05
  • 1970-01-01
  • 1970-01-01
  • 2016-03-30
  • 2013-07-01
  • 2012-11-14
  • 2015-11-25
  • 1970-01-01
相关资源
最近更新 更多