2017-04-18 47 views
0

我想创建一个触发器,它可以修改或者在我的表中插入日期“合同”:问题与触发器更改日期在Oracle

“如果用目前的合同客户签订一个新的结束日期 前一个将成为新的”

所以开始日期的前一天,我触发是:

CREATE OR REPLACE TRIGGER TRIGGER_D 
BEFORE 
INSERT OR UPDATE ON CONTRACTS 
FOR EACH ROW 
DECLARE 
idcliente CONTRACTS.CLIENTID%TYPE; 
fecha_fin CONTRACTS.ENDDATE%TYPE; 
BEGIN 
    if :NEW.CLIENTID = idcliente 
    then 
    if TO_CHAR(fecha_fin) IS NULL OR TO_CHAR(fecha_fin) > TO_CHAR(:NEW.STARTDATE) 
     then 
     INSERT INTO CONTRACTS (ENDDATE) VALUES 
     (:NEW.STARTDATE); 
     update CONTRACTS 
     set 
      ENDDATE = :NEW.STARTDATE; 
    end if;  
    end if; 
END; 

我试图插入一行是这样的:

INSERT INTO CONTRACTS (CONTRACTID, CLIENTID, STARTDATE, ENDDATE, CONTRACT_TYPE ,ADDRESS ,TOWN, ZIPCODE, COUNTRY) 
VALUES    ('TW42260/09','99/98480296/22T',TO_DATE('18/04/17','DD/MM/YY'), NULL ,'Flat Rate Lover','69 Citadel Street, Ground floor, door 1','Summer forest', '11164' ,'Taiwan, Province of China'); 

这个触发器编译得很好,但他们没有在桌子上做任何事情。

+1

你没有设置'idcliente',所以第一个比较永远不会是真的(对于'fecha_fin'也是如此),所以触发器什么都不做。如果你在触发器中插入/更新,它会再次触发,所以你冒着递归的风险,并且更新会得到一个变异的表错误。你的任务是否需要你使用触发器? –

+0

为什么比较“大于”的字符串? –

+0

这是大学的工作 –

回答

0

你想是这样的:

CREATE OR REPLACE TRIGGER TRIGGER_D 
BEFORE 
INSERT OR UPDATE ON CONTRACTS 
FOR EACH ROW 
DECLARE 
BEGIN 
    UPDATE CONTRACTS 
    SET ENDDATE = :NEW.STARTDATE - INTERVAL '1' DAY 
    WHERE CLIENTID = :NEW.CLIENTID 
    AND ENDDATE > :NEW.STARTDATE 
    AND STARTDATE < :NEW.STARTDATE; 
END; 

但是,更新表触发器在监测和它很可能是触发会导致将再次调用触发更新,并得到一个变异表错误。

将存储过程中的业务逻辑封装到可以执行前一行更新然后执行插入/更新的过程中可能会更好。然后,而不是直接在表上执行DML语句,而是调用存储过程。

+0

非常感谢您,我只是在触发器上放置了“插入”,并且突变表格消失了,因为我没有真正使用“更新”选项。非常感谢 :) –