SoFunction
Updated on 2025-03-02

Problems encountered by Oracle using insert trigger and solutions

Problems encountered with Oracle using insert triggers

First of all, TRIGGER basic statement

create or replace trigger 'trigger_name'--Trigger name
before insert --or after insert (Trigger timing)
--KeywordsbeforeandafterUsed to identify the trigger time,As the name implies,beforeThe command in the trigger isDMLExecute before modifying data,
--afterThe command in the trigger isDMLAfter modifying the data, execute it。
REFERENCING new as new --orold as old (Used for parameter usage in triggers)
--Note:beforeIn-housenewRefers to the currently inserted set,afterIn-houseoldRefers to the currently inserted set
FOR EACH ROW --Refers to the current trigger as a row-level trigger(Row-level trigger relative to statement-level trigger)
--Row-level triggers can pass :new.property and :old.property等获得updateor者insert发生之前的新值and发生值之后的旧值。
declare --Declare variables……
BEGIN
END;

About the :new.properties and :old.properties of row-level triggers

TRIGGER TONGBUJIAYI_SFZH
before
 DELETE OR UPDATE of D_SFZH
 ON T_DA_JKDA_RKXZL
REFERENCING NEW AS NEW OLD AS OLD
 FOR EACH ROW
BEGIN
 IF UPDATING
 THEN
insert into T_DA_JKDA_RKXZL_GWANDJY(ID,D_GRDABH,P_RGID,D_SFZH,D_SFZHXGQ,D_DATZXGH,D_XM,D_BGSJ,D_BGZT)
VALUES (SYS_GUID(),:OLD.D_GRDABH,:OLD.P_RGID,:OLD.D_SFZH,:NEW.D_SFZH,'',:OLD.D_XM,sysdate,'2');
ELSIF DELETING
 THEN
insert into T_DA_JKDA_RKXZL_GWANDJY(ID,D_GRDABH,P_RGID,D_SFZH,D_SFZHXGQ,D_DATZXGH,D_XM,D_BGSJ,D_BGZT)
VALUES (SYS_GUID(),:OLD.D_GRDABH,:OLD.P_RGID,:OLD.D_SFZH,'','',:OLD.D_XM,sysdate,'1');
END IF;
END;

When executing DML statements in Oracle, you need to display them for submission.

When we insert, the trigger will be triggered to perform various operations on the trigger table and the extension table.

However, at this time the trigger and the insert statement are in the same transaction management, so when the insert statement is not submitted, we cannot perform other additional operations on the trigger table.

If you perform other additional operations, the following exception message will be thrown.

ORA-04091: Table**** changed trigger/function cannot read it

This trigger generates a scene:

An ID number and personal information were imported into the system, and information about the epidemic was modified in the system.

However, when importing this person's information again (the information imported does not contain information about the epidemic every time), it needs to be synchronized.

This introduces a trigger, and the trigger condition is insert

TRIGGER DETECTION_USERS_SYN_VACCINE
  BEFORE INSERT ON DETECTION_USERS
  REFERENCING new as new
  FOR EACH ROW

DECLARE --oracleOnly use once when declaring multiple attributesDECLAREJust
  V_ID              DETECTION_USERS.ID%TYPE;--The properties declared here are as followsDETECTION_USERSProperty declaration in table
  V_IS_VACCINATION  DETECTION_USERS.IS_VACCINATION%TYPE;
  V_VACCINE1        DETECTION_USERS.VACCINE1%TYPE;
  V_VACCINE2        DETECTION_USERS.VACCINE2%TYPE;
  V_VACCINE3        DETECTION_USERS.VACCINE3%TYPE;
  V_NUM_VACCINATION DETECTION_USERS.NUM_VACCINATION%TYPE;
  --Declare cursor query this person's previous vaccination information
  CURSOR latests is
    SELECT ID,
           IS_VACCINATION,
           VACCINE1,
           VACCINE2,
           VACCINE3,
           NUM_VACCINATION
      FROM (SELECT t.*, row_number() over(order by nvl(zdrq, '0') DESC) rn
              from (SELECT *
                      FROM (SELECT ID,
                                   IS_VACCINATION,
                                   VACCINE1,
                                   VACCINE2,
                                   VACCINE3,
                                   NUM_VACCINATION,
                                   (CASE
                                     WHEN (VACCINE3 IS NOT null) THEN
                                      VACCINE3
                                     WHEN (VACCINE2 IS NOT null) THEN
                                      VACCINE2
                                     WHEN (VACCINE1 IS NOT null) THEN
                                      VACCINE1
                                     ELSE
                                      ''
                                   END) AS zdrq
                              FROM DETECTION_USERS
                             WHERE "IDENTITY" = :new."IDENTITY"
                               AND IS_VACCINATION IS NOT NULL)) t)
     WHERE rn = 1;
BEGIN

  OPEN latests;
  FETCH latests
    INTO V_ID,
         V_IS_VACCINATION,
         V_VACCINE1,
         V_VACCINE2,
         V_VACCINE3,
         V_NUM_VACCINATION;
         ---Print statement
--  DBMS_OUTPUT.PUT_LINE('latests===' || V_ID || '**' || V_IS_VACCINATION || '**' ||
--                       V_VACCINE1 || '**' || V_VACCINE2 || '**' ||
--                       V_VACCINE3 || '**' || V_NUM_VACCINATION);
--  DBMS_OUTPUT.PUT_LINE('new===' || : || '**' || :new.IS_VACCINATION || '**' ||
--                       :new.VACCINE1 || '**' || :new.VACCINE2 || '**' ||
--                       :new.VACCINE3 || '**' || :new.NUM_VACCINATION);

  IF INSERTING THEN
    :new.IS_VACCINATION  := V_IS_VACCINATION;--Will be openedcursorAssign value to the newly inserted value
    :new.VACCINE1        := V_VACCINE1;
    :new.VACCINE2        := V_VACCINE2;
    :new.VACCINE3        := V_VACCINE3;
    :new.NUM_VACCINATION := V_NUM_VACCINATION;
  
  END IF;
  --FETCH NEXT FROM from_inserted INTOV_ID,V_IS_VACCINATION,V_VACCINE1,V_VACCINE2, V_VACCINE3,V_NUM_VACCINATION;
  --cycle,HerecursorOnly one,unnecessary。
  CLOSE latests;

END;

Summarize

The above is personal experience. I hope you can give you a reference and I hope you can support me more.