简体   繁体   中英

run before trigger only once to insert multiple rows PL/SQL


I have a few parameterization tables, where i need to add history version via two columns VALID_FROM and VALID_TO. Before inserting rows i have two precondition:

1) every record, which is in table get new value in column VALID_TO (sysday - 1)
2) if exists some records in a table which have same date as sysdate (DD.MM.YYYY), they must be deleted.

table before inserting rows

columnA VALID_FROM  VALID_TO
row1    1.1.2016    31.12.2999
row2    1.1.2016    31.12.2999
row3    3.1.2016    31.12.2999

table after inserting rows

columnA VALID_FROM  VALID_TO
row1    1.1.2016    24.6.2018
row2    1.1.2016    24.6.2018
row3    3.1.2016    24.6.2018
row1    25.6.2018   31.12.2999
row2    25.6.2018   31.12.2999
row3    25.6.2018   31.12.2999
row4    25.6.2018   31.12.2999

These two steps should be finished before inserting new rows and should be automatic. This is the assignment of the task I received. I cant change it.

I tried to create before insert trigger with global temporary table to avoid ora mutating error, but its not working, because every inserted row is deleted and dates in columns VALID_FROM and VALID to are not correct too. So I need to check old records in table only once and then insert all rows without checking

My code:

CREATE OR REPLACE TRIGGER CHANGE_DATE_PARM_TABLE_MUT2
 after INSERT on TMP_GR_PARM_IDP_IC_CUST
 FOR each ROW
 BEGIN
   --if exists record which have todas date, then delete
  delete from GR_PARM_IDP_IC_CUST1 where DT_VALID_FROM = get_sysdate;
  --change date in VALID_TO for old records
  update GR_PARM_IDP_IC_CUST1 a set
  DT_VALID_TO = TO_CHAR(SYSDATE - 1, 'DD.MM.YYYY')
  where DT_VALID_TO = '31.12.2999';
 --insert records from temporary table into normal parametrization table
  insert into GR_PARM_IDP_IC_CUST1 values (:new.RELATION, :new.DT_VALID_FROM, :new.DT_VALID_TO);
END;

Its is possible solve this problem with trigger? If yes, can someone help me?

Your code looks ok, just execute it BEFORE INSERT instead of AFTER INSERT . And I don't see why you need a global temporary table. Does the following trigger fulfill your requirements?

CREATE OR REPLACE TRIGGER ti_mytable 
  BEFORE INSERT ON mytable FOR EACH ROW
BEGIN
  DELETE FROM mytable WHERE valid_from = TRUNC(SYSDATE);
  UPDATE mytable SET valid_to = TRUNC(SYSDATE - 1);
  :new.valid_from := TRUNC(SYSDATE);
  :new.valid_to := DATE '2999-12-31';
END ti_mytable;
/

SELECT * FROM mytable;
COLA  VALID_FROM   VALID_TO
1     01.01.2016   31.12.2999
2     01.01.2016   31.12.2999
3     03.01.2016   31.12.2999

INSERT INTO mytable (cola) VALUES (4);
1 row inserted.
SELECT * FROM mytable;
COLA  VALID_FROM   VALID_TO
1     01.01.2016   24.06.2018
2     01.01.2016   24.06.2018
3     03.01.2016   24.06.2018
4     25.06.2018   31.12.2999

Furthermore, I'd recommend to store dates always as datatype DATE and never as a string / datatype VARCHAR2 .

无法通过TRIGGER触发。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM