0

Is possible to create or replace a view inside a trigger in Oracle?

The view is created by joining 2 tables and one of them is the one updated by the trigger

Ian Carpenter
  • 8,346
  • 6
  • 50
  • 82
user2999664
  • 15
  • 1
  • 1
  • 5
  • 3
    Yes, but why on earth would you want to? What is the actual problem you're attempting to solve? I mean, rather than asking us how to implement the solution you've decided upon why are you wanting to implement this solution? – Ben Nov 16 '13 at 17:48
  • @Ben is 100% correct - terrible idea. – OldProgrammer Nov 16 '13 at 20:33

2 Answers2

3

Just to provide all options (however weird the idea of creating a view inside a trigger might be...) you can create a view in a trigger. Yes, an implicit COMMIT will follow, but if we make the trigger work in autonomous transaction, then the dynamic DDL will not fail. Using Luke Woodward's example:

CREATE TABLE test (a integer);

INSERT INTO test (a) VALUES (5);

CREATE OR REPLACE TRIGGER test_trig
  AFTER UPDATE ON test
  FOR EACH ROW
DECLARE
  -- making the trigger work outside of the main transaction
  PRAGMA autonomous_transaction;
BEGIN
    EXECUTE IMMEDIATE 'CREATE OR REPLACE VIEW test_view AS SELECT * FROM test';
END;
/

UPDATE test SET a = 6;

SELECT * FROM test_view;
         A
----------
         6 

Check at SQLFiddle

Przemyslaw Kruglej
  • 8,003
  • 2
  • 26
  • 41
2

No, you can't. Creating a view forces a commit, and you cannot commit in a trigger.

Here's what happens when you try to do this:

SQL> CREATE TABLE test (a integer);

Table created.

SQL> INSERT INTO test (a) VALUES (5);

1 row created.

SQL> COMMIT;

Commit complete.

SQL> CREATE OR REPLACE TRIGGER test_trig
  2    AFTER UPDATE ON test
  3    FOR EACH ROW
  4  BEGIN
  5    EXECUTE IMMEDIATE 'CREATE OR REPLACE VIEW test_view AS SELECT * FROM test';
  6  END;
  7  /

Trigger created.

SQL> UPDATE test SET a = 6;
UPDATE test SET a = 6
       *
ERROR at line 1:
ORA-04092: cannot COMMIT in a trigger
ORA-06512: at "LUKE.TEST_TRIG", line 2
ORA-04088: error during execution of trigger 'LUKE.TEST_TRIG'
Luke Woodward
  • 63,336
  • 16
  • 89
  • 104
  • 1
    Actually, you can, if you define the trigger with `PRAGMA autonomous_transaction`: http://sqlfiddle.com/#!4/66193/1 – Przemyslaw Kruglej Nov 17 '13 at 01:01
  • 1
    @PrzemyslawKruglej: OK, I didn't know you could use an autonomous transaction in a trigger. But that doesn't change the fact that creating a view in a trigger is catastrophically poor application design. If the transaction that causes the trigger to fire gets rolled back, the view doesn't get unapplied and the application could therefore be left in an inconsistent state. – Luke Woodward Nov 17 '13 at 18:06
  • Of course, I agree with you 100%. Still, the question was whether or not it is possible, however weird or wrong that is. – Przemyslaw Kruglej Nov 17 '13 at 18:22