我正在使用Oracle Database 18c Express Edition和APEX 19.1。
要求是能够在相同或不同类型的项目之间链接:
例如
logs.item_id = 1
logs.item_id = 2
events.item_id = 5
我的想法是要有一个共享的ID序列,该序列将在每次插入时填充-例如-日志表。
对于日志,事件和其他项目具有唯一的ID,我可以在单独的链接表中创建链接
执行DDL脚本后,我的第一个
INSERT INTO events (dummy) VALUES ('D');
结果错误。
ORA-02291: integrity constraint (C##TEST.EVE_ITE_FK_1) violated - parent key not found
以下插入从3开始分配序列值。
DROP TABLE items CASCADE CONSTRAINTS;
DROP TABLE logs CASCADE CONSTRAINTS;
DROP TABLE events CASCADE CONSTRAINTS;
DROP TABLE links CASCADE CONSTRAINTS;
DROP SEQUENCE items_seq;
DROP TRIGGER logs_trg;
DROP TRIGGER events_trg;
/
CREATE TABLE logs (
item_id NUMBER(*,0) PRIMARY KEY
,dummy CHAR(1));
/
CREATE TABLE events (
item_id NUMBER (*,0) PRIMARY KEY
,dummy CHAR(1));
/
CREATE TABLE links (
id NUMBER(*,0) GENERATED ALWAYS AS IDENTITY PRIMARY KEY
,item_id_1 NUMBER(*,0)
,item_id_2 NUMBER(*,0));
/
CREATE TABLE items (
id NUMBER(*,0) PRIMARY KEY
,type CHAR(1 CHAR));
/
ALTER TABLE logs ADD CONSTRAINT log_ite_fk_1 FOREIGN KEY (item_id) REFERENCES items (id);
/
ALTER TABLE events ADD CONSTRAINT eve_ite_fk_1 FOREIGN KEY (item_id) REFERENCES items (id);
/
ALTER TABLE links ADD CONSTRAINT lin_ite_fk_1 FOREIGN KEY (item_id_1) REFERENCES items (id);
/
ALTER TABLE links ADD CONSTRAINT lin_ite_fk_2 FOREIGN KEY (item_id_2) REFERENCES items (id);
/
CREATE SEQUENCE items_seq START WITH 1;
/
CREATE OR REPLACE TRIGGER logs_trg FOR INSERT ON logs
COMPOUND TRIGGER
l_item_id PLS_INTEGER := items_seq.nextval;
co_item_type CONSTANT CHAR(1) := 'L';
BEFORE STATEMENT
IS
BEGIN
INSERT INTO items(id
,type)
VALUES (l_item_id
,co_item_type);
END BEFORE STATEMENT;
BEFORE EACH ROW
IS
BEGIN
SELECT l_item_id
INTO :NEW.item_id
FROM dual;
END BEFORE EACH ROW;
END;
/
CREATE OR REPLACE TRIGGER events_trg FOR INSERT ON events
COMPOUND TRIGGER
l_item_id PLS_INTEGER := items_seq.nextval;
co_item_type CONSTANT CHAR(1) := 'E';
BEFORE STATEMENT
IS
BEGIN
INSERT INTO items(id
,type)
VALUES (l_item_id
,co_item_type);
END BEFORE STATEMENT;
BEFORE EACH ROW
IS
BEGIN
SELECT l_item_id
INTO :NEW.item_id
FROM dual;
END BEFORE EACH ROW;
END;
/
您对我如何使它与第一个插入物一起使用有任何建议吗?
我希望
INSERT INTO events (dummy) VALUES ('D');
生成items.id = 1和events.item_id = 1。
编辑:
按照Enrique的建议,我使用returning
子句切换为非复合触发器-如下。
DROP TABLE items CASCADE CONSTRAINTS;
DROP TABLE logs CASCADE CONSTRAINTS;
DROP TABLE events CASCADE CONSTRAINTS;
DROP TABLE links CASCADE CONSTRAINTS;
DROP SEQUENCE items_seq;
/
CREATE TABLE logs (
item_id NUMBER(*,0) PRIMARY KEY
,dummy CHAR(1));
/
CREATE TABLE events (
item_id NUMBER (*,0) PRIMARY KEY
,dummy CHAR(1));
/
CREATE TABLE links (
id NUMBER(*,0) GENERATED ALWAYS AS IDENTITY PRIMARY KEY
,item_id_1 NUMBER(*,0)
,item_id_2 NUMBER(*,0));
/
CREATE TABLE items (
id NUMBER(*,0) PRIMARY KEY
,type CHAR(1 CHAR));
/
ALTER TABLE logs ADD CONSTRAINT log_ite_fk_1 FOREIGN KEY (item_id) REFERENCES items (id);
/
ALTER TABLE events ADD CONSTRAINT eve_ite_fk_1 FOREIGN KEY (item_id) REFERENCES items (id);
/
ALTER TABLE links ADD CONSTRAINT lin_ite_fk_1 FOREIGN KEY (item_id_1) REFERENCES items (id);
/
ALTER TABLE links ADD CONSTRAINT lin_ite_fk_2 FOREIGN KEY (item_id_2) REFERENCES items (id);
/
CREATE SEQUENCE items_seq START WITH 1;
/
CREATE OR REPLACE TRIGGER logs_trg FOR INSERT ON logs
COMPOUND TRIGGER
l_item_id PLS_INTEGER := items_seq.nextval;
co_item_type CONSTANT CHAR(1) := 'L';
BEFORE STATEMENT
IS
BEGIN
INSERT INTO items(id
,type)
VALUES (l_item_id
,co_item_type);
END BEFORE STATEMENT;
BEFORE EACH ROW
IS
BEGIN
SELECT l_item_id
INTO :NEW.item_id
FROM dual;
END BEFORE EACH ROW;
END;
/
CREATE OR REPLACE TRIGGER events_trg BEFORE INSERT ON events
FOR EACH ROW
DECLARE
co_item_type CONSTANT CHAR(1) := 'M';
BEGIN
INSERT INTO items(id
,type)
VALUES (items_seq.nextval
,co_item_type)
RETURNING id INTO :NEW.item_id;
DBMS_OUTPUT.PUT_LINE(systimestamp);
END;
/
INSERT INTO events (dummy) values ('D');
INSERT INTO events (dummy) values ('D');
现在问题不同了。 events
表上的第一个插入在items_seq
上生成2个值
INSERT INTO events (dummy) VALUES ('D');
DBMS_OUTPUT:
08-MAY-19 11.08.29.301000000 +02:00
08-MAY-19 11.08.29.303000000 +02:00
进行中的插入片段的行为符合预期-每个插入片段1个序列号。因此2个插入会生成3个序列值。
我期望的结果是在items.id
表上首次插入events
= 1。
答案 0 :(得分:0)
只需使用此
v_myid号;
插入表(col1,col2) 值(value1,value2) 将id返回到v_myid;