Oracle SQL,触发将表中的行作为FK插入表Y中当前插入的行

时间:2014-03-10 11:08:18

标签: sql oracle triggers foreign-key-relationship

所以在Oracle 11g中我有以下内容:

CREATE TABLE OBJECT(
    ID NUMBER(8) NOT NULL,
    CATEGORY_ENUM_ID NUMBER(8) NOT NULL
);

CREATE SEQUENCE OBJECT_SEQ
 START WITH     1
 INCREMENT BY   1
 NOCACHE
 NOCYCLE;
/
CREATE TABLE TREE(
    ID NUMBER(8) NOT NULL,
    OBJECT_ID NUMBER(8) NOT NULL,
    NAME NVARCHAR2(128)
);

CREATE TABLE CATEGORY_ENUM(
    ID NUMBER(8) NOT NULL,
    NAME NVARCHAR2(64)
);

-- PK's
ALTER TABLE TREE
ADD CONSTRAINT TREE_PK PRIMARY KEY (ID);

ALTER TABLE OBJECT
ADD CONSTRAINT OBJECT_PK PRIMARY KEY (ID);

ALTER TABLE CATEGORY_ENUM
ADD CONSTRAINT CATEGORY_ENUM_PK PRIMARY KEY (ID)

--- FK's
ALTER TABLE TREE
ADD CONSTRAINT TREE_OBJECT_FK FOREIGN KEY (OBJECT_ID)
REFERENCES OBJECT (ID);

ALTER TABLE OBJECT 
ADD CONSTRAINT OBJECT_CATEGORY_FK FOREIGN KEY (CATEGORY_ENUM_ID)
REFERENCES CATEGORY_ENUM (ID);

-- Closed dictionary sample data
INSERT INTO CATEGORY_ENUM (ID, NAME) VALUES (1, 'TREE');
INSERT INTO CATEGORY_ENUM (ID, NAME) VALUES (2, 'HERB');
INSERT INTO CATEGORY_ENUM (ID, NAME) VALUES (3, 'SHROOM');

-- Triggers
CREATE OR REPLACE TRIGGER TREE_before_insert
    BEFORE INSERT
       ON TREE
  REFERENCING NEW AS NEW OLD AS OLD
  FOR EACH ROW
  DECLARE
   CATEGORY_ID NUMBER;
    BEGIN
      SELECT ID INTO CATEGORY_ID FROM CATEGORY_ENUM WHERE NAME = 'TREE' AND ROWNUM <= 1;
          if :NEW.OBJECT_ID is null then 
            :NEW.OBJECT_ID := OBJECT_SEQ.nextval; 
            INSERT INTO OBJECT (ID, CATEGORY_ENUM_ID) VALUES (:NEW.OBJECT_ID, CATEGORY_ID);
          end if; 
    END;
/

如果下次我跑:

INSERT INTO TREE (ID, NAME) VALUES (1, 'Tree1');
INSERT INTO TREE (ID, NAME) VALUES (2, 'Tree2');

我收到错误:

...
TRIGGER TREE_BEFORE_INSERT compiled
Error starting at line 91 in command:
INSERT INTO TREE (ID, NAME) VALUES (1, 'Tree1')
Error report:
SQL Error: ORA-02291: integrity constraint (HR.TREE_OBJECT_FK) violated - parent key not found
02291. 00000 - "integrity constraint (%s.%s) violated - parent key not found"
*Cause:    A foreign key value has no matching primary key value.
*Action:   Delete the foreign key or add a matching primary key.
1 rows inserted.

但是如果在上面之前,我在FEATURES表中插入了任何内容(如下所示),它运行正常。

INSERT INTO OBJECT (ID, CATEGORY_ENUM_ID) VALUES (0, 1);

INSERT INTO TREE (ID, NAME) VALUES (1, 'Tree1');
INSERT INTO TREE (ID, NAME) VALUES (2, 'Tree2');

因此问题仅发生在第一次插入时,其他插件工作正常,从OBJECT_SEQ.nextval分配的ID是正确的。 我做错了什么?

Jah祝福你的帮助。

编辑我删除了一些不必要的代码,所以现在它更清晰,更短。

1 个答案:

答案 0 :(得分:0)

这里的问题是你在“TREE”表上放置了一个主键约束,在“OBJECT”表上放置了一个外键约束。因此,您尝试使用外键约束插入表中的任何新记录,请确保它已在具有主键映射的表中可用。

Example shown below:

**Tables:**
create table tab1
(id number,
name varchar2(100)
)

create table tab2
(id number,
name varchar2(100)
)

**constraints added:**
alter table tab1 add constraint pk_tab1_id primary key (id)
alter table tab2 add constraint fk_tab2_id foreign key(id) references tab1(id)

**Insert statement on the second table:**
insert into tab2(values(1,'abc')

**Error:**
SQL Error: ORA-02291: integrity constraint (PRAVE.fk_tab2_id) violated - parent key not found
02291. 00000 - "integrity constraint (%s.%s) violated - parent key not found"
*Cause:    A foreign key value has no matching primary key value.
*Action:   Delete the foreign key or add a matching primary key.

**Solution:**
**Insert into the table with PK first as below:**
insert into tab1 values(1,'abc')
1 rows inserted.
insert into tab2 values(1,'abc')
1 rows inserted.