Skip to Main Content
  • Questions
  • How to create dml trigger in a ddl trigger.

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Christopher.

Asked: May 11, 2020 - 9:29 am UTC

Last updated: May 13, 2020 - 12:32 am UTC

Version: Oracle 12c

Viewed 1000+ times

You Asked

Hi Tom. There are some problems when i was trying to create a dml trigger in a ddl trigger by using
DNS. The ddl trigger goes like the following:
create or replace trigger auto_create_dml_trigger
after create on database
declare
pragma autonomous_transaction;
create_sql varchar2(2000);
begin
create_sql := generate_trigger_exp( ); 
--comment: generate_trigger_exp() is a 
--procedure used to generate an expression that creates a trigger. I assure you I can 
--succussfully get the whole expression. For example, i create a table table_a, then
--auto_create_dml_trigger got fired, and create_sql will get the value 'create or replace 
--trigger syn_update after update on table_a ......' by generate_trigger_exp().
execute immediate create_sql;
commit;
end;


But some problems occured. I was told that 'ORA-04020 deadlock was detected when trying to lock object ...', i don't
know how to fix it. I am a green hand in Oracle and PL/SQL programming. All i want to do is creating
a dml trigger automatically in a ddl trigger while creating a table. Thanks a lot for sparing time reading
my question.

and Chris said...

So you've got a DDL trigger that runs more DDL. So this will happen:

Creating a table fires the DDL trigger.
Which creates a trigger
Which fires the DDL trigger again
Which tries to create a trigger again
Which fires the DDL trigger AGAIN
Which tries to create a trigger AGAIN!
etc.

See the problem?

Depending on how generate_trigger_exp works, it may be trying to re-create the SAME trigger. Which it's going to get stuck doing!

I'd avoid trying to auto-generate triggers like this. If you need a trigger code it explicitly.

Or look to see if there's an existing feature that does what you're planning in the trigger. e.g. IDENTITY columns/sequence defaults for auto-incrementing columns.

Rating

  (2 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

What if i add a judgement?

Christopher He, May 11, 2020 - 10:32 pm UTC

Your answer enlightened me, so i modified my code. I added a judgement in auto_create_dml_trigger, then the code became like this:
create or replace trigger auto_create_dml_trigger
after create on database
declare
pragma autonomous_transaction;
create_sql varchar2(2000);
begin
if(ora_dict_obj_type = 'TABLE') then --Judgement
    create_sql := generate_trigger_exp( ); 
    execute immediate create_sql;
    commit;
end if;
end;


But it still doesn't work, the same ORA-04020 error accured.
Connor McDonald
May 12, 2020 - 8:26 am UTC

Rather than this approach, how about the following

create or replace trigger auto_create_dml_trigger
after create on database
declare
  j int;
begin
  if(ora_dict_obj_type = 'TABLE') then --Judgement
    dbms_job.submit(j,'my_ddl_handler('''||ora_dict_obj_name||''';');
  end if;
end;


Then a background job can take care of doing all the heavy lifting

dbms_job

Christopher He, May 12, 2020 - 2:57 pm UTC

The feature dbms_job really works. My code finally ran as i pursued. I'm so grateful for the help you have provided!
Connor McDonald
May 13, 2020 - 12:32 am UTC

glad we could help

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library