如何在数据库中实施业务逻辑以防止在单独的表(oracle db)中引用的日期段冲突

时间:2018-12-06 14:44:23

标签: database oracle triggers constraints period

我有2个数据库表(K_TILBUD和WEB_PRODUKT_TILBUD):

K_TILBUD
TILBUD_ID - *NUMBER(10,0)*
TILBUD - *VARCHAR2(2000 CHAR)*
AKTIV_STATUS - *VARCHAR2(1 CHAR)*
DATO_FRA - *DATE*
DATO_TIL - *DATE*
WEB_PRODUKT_TILBUD
ID - *NUMBER*
TILBUD_ID - *NUMBER(10,0)*
PRODUKT_ID - *NUMBER(10,0)*
BUTIKK_ID - *VARCHAR2(2 CHAR)*

在创建/更新(插入和更新)WEB_PRODUKT_TILBUD行时,希望避免给定的“ PRODUKT_ID和BUTIKK_ID”组合获得的K_TILBUD期间(DATO_FRA-DATO_TIL)与现有的“ PRODUKT_ID&BUTIKK_ID”冲突”组合的TILBUD_ID期间。

换句话说:WEB_PRODUKT_TILBUD中具有相同PRODUKT_ID和BUTIKK_ID的2行不能引用(冲突)日期(DATO_FRA-DATO_TIL)相冲突的K_TILBUD(通过TILBUD_ID)。

由于数据库中可能存在手动更新,因此希望在数据库级别强制执行此规则。

据我所知,常规约束甚至无法完成工作。

到目前为止,最接近的方法是无效的触发器:

CREATE OR REPLACE TRIGGER TI_WEB_PRODUKT_TILBUD 
BEFORE INSERT OR UPDATE ON WEB_PRODUKT_TILBUD 
FOR EACH ROW
DECLARE
V_FRADATO DATE;
V_TILDATO DATE;
V_COUNT NUMBER; 
BEGIN
SELECT K_TILBUD.DATO_FRA, K_TILBUD.DATO_TIL 
INTO V_FRADATO, V_TILDATO
FROM K_TILBUD
WHERE K_TILBUD.TILBUD_ID = :NEW.TILBUD_ID;
SELECT COUNT(*) INTO V_COUNT 
FROM WEB_PRODUKT_TILBUD, K_TILBUD 
WHERE WEB_PRODUKT_TILBUD.PRODUKT_ID=:NEW.PRODUKT_ID 
AND WEB_PRODUKT_TILBUD.BUTIKK_ID=:NEW.BUTIKK_ID 
AND WEB_PRODUKT_TILBUD.TILBUD_ID = K_TILBUD.TILBUD_ID 
AND K_TILBUD.DATO_FRA <= V_TILDATO AND K_TILBUD.DATO_TIL >= V_FRADATO;
IF V_COUNT > 0 THEN
    RAISE_APPLICATION_ERROR(-20100, 'Et produkt tilbud kan ikke forekomme flere ganger i samme K_TILBUD periode');
END IF;
EXCEPTION WHEN NO_DATA_FOUND THEN NULL;
END;

这当然不是有效的oracle数据库触发器,因为它引用了“ OLD table”(触发器不允许),因此会产生 以下错误:

  

一个错误保存对表“ WEB_PRODUKT_TILBUD”的更改:行   49:ORA-04091:表WEB_PRODUKT_TILBUD正在变异,   触发器/功能可能看不到它ORA-06512:在   “ TI_WEB_PRODUKT_TILBUD”,第10行ORA-04088:在执行期间出错   执行触发器“ TI_WEB_PRODUKT_TILBUD”

但是尝试的触发器说明了要实现的目标-如开头所述。

这有可能做到吗?以其他方式?

创建存储的程序(类似于上面的触发器)并从触发器中调用它会有所帮助吗?也许使它有效吗?

还有其他建议建议如何在数据库级别实施此逻辑吗?

0 个答案:

没有答案