Search code examples
sqloracleplsqltriggerssql-insert

How to implement AFTER INSERT Trigger in Oracle PL/SQL?


I am trying to implement after insert trigger in PLSQL.
The goal is to check if there are multiple (>1) rows having specific status for each client.
If so I'd like to rise an exception and roll the insertion back.

I am struggling with implementing warning-free query, which causes error during insertion.
How could I manage this?
Here is my implemented trigger which I guess needs some changes.

CREATE TRIGGER blatrigger
    AFTER INSERT
    ON BLATABLE
    REFERENCING NEW AS NEW OLD AS OLD
    FOR EACH ROW
DECLARE
    exception_name EXCEPTION;
    PRAGMA EXCEPTION_INIT (exception_name, -20999);
BEGIN
    if (select count(*) as counter from BLATABLE where CLIENTID = :NEW.CLIENTID and STATUS='PENDING').counter > 1
    THEN
        raise exception_name;
    END IF;
END;

Here is the table itself:

create table BLATABLE
(
    ID            NUMBER(19) not null primary key,
    CLIENTID      NUMBER(10),
    CREATED       TIMESTAMP(6),
    STATUS        VARCHAR2(255 char)
);

Solution

  • Use a Statement Level Trigger, rather than a Row Level by removing FOR EACH ROW, and converting to your code as below :

    CREATE OR REPLACE TRIGGER blatrigger
      AFTER INSERT ON BLATABLE
      REFERENCING NEW AS NEW OLD AS OLD
    
    DECLARE
      counter        INT;
      exception_name EXCEPTION;
      PRAGMA EXCEPTION_INIT(exception_name, -20999);
    BEGIN
      SELECT MAX(COUNT(*))
        INTO counter
        FROM BLATABLE
       WHERE STATUS = 'PENDING'
       GROUP BY CLIENTID;
         
      IF counter > 1 THEN
        RAISE exception_name;
      END IF;
    END;
    /
    

    where

    • the SELECT statement need to be removed from IF .. THEN conditional
    • Most probably, the mutating table error would raise for Row Level Trigger case

    Demo