Home > Net >  I want to create a trigger, where in data insertion trigger updates a quantity of non-primary or pri
I want to create a trigger, where in data insertion trigger updates a quantity of non-primary or pri

Time:05-24

I want to create a trigger, where in data insertion for the same userid, trigger updates a quantity by 1, of particular row in another table.

CREATE OR REPLACE TRIGGER test_after_insert
AFTER INSERT
   ON visitor
   FOR EACH ROW
WHEN (old.visresid = new.visresid)

BEGIN
   UPDATE visqty
   SET primaryvisqty = primaryvisqty   1
   WHERE old.visresid = new.visresid
DBMS_OUTPUT.put_line ('Table updated');
END;

CodePudding user response:

Should be

CREATE OR REPLACE TRIGGER test_after_insert
   AFTER INSERT ON visitor
   FOR EACH ROW
BEGIN
   UPDATE visqty
   SET primaryvisqty = primaryvisqty   1
   WHERE visresid = :new.visresid;
END;
  • remove WHEN clause
  • fix WHERE clause
  • terminate UPDATE statement with a semi-colon
  • remove DBMS_OUTPUT call (clients, that don't support it, won't see anything anyway)

With sample tables:

SQL> CREATE TABLE visitor
  2  (
  3     visresid   NUMBER
  4  );

Table created.

SQL> CREATE TABLE visqty
  2  (
  3     visresid        NUMBER,
  4     primaryvisqty   NUMBER
  5  );

Table created.

As trigger updates the visqty table, it means that it is pre-populated with data:

SQL> INSERT INTO visqty (visresid, primaryvisqty)
  2       VALUES (1, 0);

1 row created.

Trigger:

SQL> CREATE OR REPLACE TRIGGER test_after_insert
  2     AFTER INSERT
  3     ON visitor
  4     FOR EACH ROW
  5  BEGIN
  6     UPDATE visqty
  7        SET primaryvisqty = primaryvisqty   1
  8      WHERE visresid = :new.visresid;
  9  END;
 10  /

Trigger created.

Testing:

SQL> INSERT INTO visitor (visresid)
  2       VALUES (1);

1 row created.

SQL> SELECT * FROM visqty;

  VISRESID PRIMARYVISQTY
---------- -------------
         1             1

SQL>

If visqty isn't pre-populated, use merge instead of update:

SQL> CREATE OR REPLACE TRIGGER test_after_insert
  2     AFTER INSERT
  3     ON visitor
  4     FOR EACH ROW
  5  BEGIN
  6     MERGE INTO visqty a
  7          USING (SELECT :new.visresid AS visresid FROM DUAL) b
  8             ON (a.visresid = b.visresid)
  9     WHEN MATCHED
 10     THEN
 11        UPDATE SET a.primaryvisqty = a.primaryvisqty   1
 12     WHEN NOT MATCHED
 13     THEN
 14        INSERT     (visresid, primaryvisqty)
 15            VALUES (:new.visresid, 1);
 16  END;
 17  /

Trigger created.

SQL>

CodePudding user response:

:old.visresid will always be NULL on an INSERT so your filter WHERE :old.visresid = :new.visresid (correcting the missing : on the :NEW and :OLD bind variables) will never match anything.

If you want to add one to the row in visqty for each row added to visitor then you can use:

CREATE OR REPLACE TRIGGER test_after_insert
  AFTER INSERT ON visitor
  FOR EACH ROW
BEGIN
  UPDATE visqty
  SET    primaryvisqty = primaryvisqty   1;
END;
/

db<>fiddle here


As I have boolean condition, and I would insert a data to particular field based on 0 or 1, how I could then achieve this? For example, if primvis = 1 then SET primaryvisqty = primaryvisqty 1, if primvis = 0, then instead non primaryvisqty = primaryvisqty 1?

CREATE OR REPLACE TRIGGER test_after_insert
  AFTER INSERT ON visitor
  FOR EACH ROW
BEGIN
  IF :NEW.primvis = 1 THEN
    UPDATE visqty
    SET    primaryvisqty = primaryvisqty   1;
  ELSE
    UPDATE visqty
    SET    nonprimaryvisqty = nonprimaryvisqty   1;
  END IF;
END;
/

db<>fiddle here


You could use a trigger:

CREATE OR REPLACE TRIGGER test_after_insert
  AFTER INSERT ON visitor
  FOR EACH ROW
BEGIN
  MERGE INTO visqty a
  USING DUAL b
  ON (a.permvisid = :NEW.visresid)
  WHEN MATCHED THEN
    UPDATE
    SET primaryvisqty = primaryvisqty   :new.isprimary,
        othervisqty   = othervisqty     1 - :new.isprimary
  WHEN NOT MATCHED THEN
    INSERT (permvisid, primaryvisqty, othervisqty)
    VALUES (:new.visresid, :new.isprimary, 1 - :new.isprimary);
END;
/

But it seems that what you really want is a view and not a table and a trigger:

CREATE VIEW visqty(permvisid, primaryvisqty, othervisqty) AS
SELECT r.rid,
       COUNT(CASE v.isprimary WHEN 1 THEN 1 END) AS primaryvisqty,
       COUNT(CASE v.isprimary WHEN 0 THEN 1 END) AS othervisqty
FROM   residents r
       LEFT OUTER JOIN visitor v
       ON (r.rid = v.visresid)
GROUP BY r.rid

db<>fiddle here

  • Related