I have an error: 'ORA-04092: cannot COMMIT in a trigger' when trying to execute ddl command in one simple oracle after update trigger. Trigger needs to create public database link after one field in column is updated. Here is the source:
create or replace
TRIGGER CreateLinkTrigger
after UPDATE of Year ON tableInit
for each row
DECLARE
add_link VARCHAR2(200);
BEGIN
IF :new.year = '2014'
then
add_link := q'{create public database link p2014 connect to test14 identified by temp using 'ora'}';
execute immediate add_link;
END IF;
END;
So, as You can see i need to create new public database link after new year has been activated.
So when i try to update table 'tableInit' with year value of '2014' i get ORA-04092 error.
Is there any way to avoid this error, or another solution for this?
Thanks...
Creating a database link on the fly seems like an unusual thing to do; your schema should generally be static and stable. However, if you must, it would be simpler to wrap the update and the link in a procedure, or just issue two statements - presumably whatever performs the update is fairly controlled anyway, otherwise you'd have to deal with multiple people triggering this multiple times, which would be even more of a mess.
You can probably make this work by adding PRAGMA autonomous_transaction;
to your trigger, as demonstrated for a similar issue (creating a view rather than a link) in this answer, but I'm not in a position to test that at the moment.
create or replace
TRIGGER CreateLinkTrigger
after UPDATE of Year ON tableInit
for each row
DECLARE
add_link VARCHAR2(200);
PRAGMA autonomous_transaction;
BEGIN
...
You could also make the trigger submit an asynchronous job to perform the DDL, as described in this answer, and there's more of an example in this answer, where you'd change the job's anonymous block to do your execute immediate
.
It would probably be better to just create the links for the next few years in advance during a maintenance window, or on a schedule, or from a procedure; rather than trying to associate a schema change to a data change.