我的Oracle DB中有2个表
CLIENT_ID(PK) - INSERT_DATE
1 - 1/1/2017
CLIENT_ID(FK) - EXIT_DATE
1 - 5/1/2017
我想创建一个Before Insert Trigger,如果我尝试在EXIT_DATE上插入一个早于INSERT_DATE列的日期,则会显示错误。
例如,如果我尝试插入31/12/2016,它将显示错误“退出日期不能早于INSERT DATE”我的问题还在于触发器必须在2个表之间匹配Client_ID。 (我使用的是Oracle 11g)
答案 0 :(得分:1)
已修改,其中包含FOREIGN KEY
阻止孤儿CLIENT_ID
的信息。
要生成强制执行您所描述的规则的触发器,以下内容将起作用 首先,创建一些测试表:
CREATE TABLE INSERT_TABLE(
CLIENT_ID NUMBER NOT NULL PRIMARY KEY,
INSERT_DATE DATE NOT NULL
);
CREATE TABLE EXIT_TABLE(
CLIENT_ID NUMBER NOT NULL REFERENCES INSERT_TABLE(CLIENT_ID),
EXIT_DATE DATE NOT NULL
);
CREATE INDEX EXIT_INSERT_FKI ON EXIT_TABLE(CLIENT_ID);
然后,应用触发器:
CREATE OR REPLACE TRIGGER EXIT_AFTER_INSERT_ENFORCER
BEFORE INSERT ON EXIT_TABLE
FOR EACH ROW
DECLARE
V_INSERT_DATE DATE;
BEGIN
SELECT INSERT_TABLE.INSERT_DATE
INTO V_INSERT_DATE
FROM INSERT_TABLE
WHERE INSERT_TABLE.CLIENT_ID = :NEW.CLIENT_ID;
IF :NEW.EXIT_DATE < V_INSERT_DATE
THEN RAISE_APPLICATION_ERROR(-20100, 'EXIT DATE cannot be older than the INSERT DATE');
END IF;
EXCEPTION WHEN NO_DATA_FOUND THEN NULL;
END;
/
注意:触发器不是实现此目的的唯一方法。 MATERIALIZED VIEW
也可以通过CHECK CONSTRAINT
强制执行此约束。替代建模也会简化事情。我将在下面详细介绍一个替代方案。
然后测试触发器:
以下是好的:
INSERT INTO INSERT_TABLE VALUES (1, TO_DATE('20170101', 'YYYYMMDD'));
INSERT INTO EXIT_TABLE VALUES (1, TO_DATE('20170501', 'YYYYMMDD'));
1 row inserted.
1 row inserted.
但是以下内容被阻止,因为退出日期在插入日期之前:
INSERT INTO INSERT_TABLE VALUES (2, TO_DATE('20170101', 'YYYYMMDD'));
INSERT INTO EXIT_TABLE VALUES (2, TO_DATE('19910501', 'YYYYMMDD'));
ORA-20100:退出日期不能早于INSERT DATE
这应该完成你所描述的。
我补充说,作为一个额外的考虑,替代数据模型可以帮助这样的约束。如果INSERT_DATE
和EXIT_DATE
都是同一客户的属性,那么只有一个表的替代设计可以更简单地强制执行此操作:
CREATE TABLE INSERT_EXIT(
CLIENT_ID NUMBER NOT NULL PRIMARY KEY,
INSERT_DATE DATE NOT NULL,
EXIT_DATE DATE NULL,
CONSTRAINT EXIT_AFTER_INSERT CHECK (EXIT_DATE >= INSERT_DATE)
);
在此表中,允许以下内容:
INSERT INTO INSERT_EXIT VALUES (1,TO_DATE('20170101', 'YYYYMMDD'),NULL);
INSERT INTO INSERT_EXIT VALUES (2,TO_DATE('20170101', 'YYYYMMDD'),TO_DATE('20170501', 'YYYYMMDD'));
1 row inserted.
1 row inserted.
但以下是自然不允许的:
INSERT INTO INSERT_EXIT VALUES (3,TO_DATE('20170101', 'YYYYMMDD'),TO_DATE('19700101', 'YYYYMMDD'));
ORA-02290:违反检查约束(MYSCHEMA.EXIT_AFTER_INSERT)