Eosphorus
Eosphorus

Reputation: 312

Getting a Tablename from all_tables for a trigger

We have an application that creates a table with a randomly generated name. I would like to create a trigger on this table.Since I do not know the name of the tabe I would like to get it from the all_table view. How can I go about achieveing something like this?

    create or replace trigger t1      
after insert or update on (select table_name from all_tables where owner = 'CustomAPP' and table_name like 'STAGE_%')  
     -- for each row
    declare
      -- local variables here
    begin

    end t1;

The SQL above obviously gives an error because of the select clause after the create trigger instead of a table name. Please advise

Upvotes: 1

Views: 1494

Answers (3)

Adam Musch
Adam Musch

Reputation: 13583

Solution 1:

If the problem is "poor performance due to lack of statistics", perhaps changing the OPTIMIZER_DYNAMIC_SAMPLING parameter at a system or session level can help. See the Performance Tuning Guide for a more thorough discussion, but I've found the default of 2 (64 blocks) to be insufficient, especially for large data sets where keeping optimizer statistics current is impractical.

Solution 2:

If you really want to automatically create a trigger after a table's been created, you'll need to create a DDL trigger for the schema. The SQL below demonstrates that.

CREATE OR REPLACE TRIGGER MAKE_ME_A_TRIGGER
AFTER CREATE ON CUSTOM_APP_SCHEMA
AS
  l_trigger_sql varchar2(4000);
BEGIN  
  if l_ora_obj_dict_type = 'TABLE'
  then
    l_trigger_sql := 'create or replace trigger ' || ora_dict_obj_name
                     ' before insert on ' || ora_dict_obj_type||   
                     ' for each row ' ||  
                     'begin ' ||  
                     '  null; ' ||
                     'end;'
    execute immediate l_sql;
  end if;
END;
/

Upvotes: 1

WCRC
WCRC

Reputation: 405

You can use EXECUTE IMMEDIATE to dynamically execute SQL, including DDL scripts, provided the active connection has appropriate permissions on the database. Use PL/SQL to build the full DDL statement via string concatenation, and then you can execute it dynamically.

Docs: http://docs.oracle.com/cd/B12037_01/appdev.101/b10807/13_elems017.htm

More Docs: http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/dynamic.htm

Upvotes: 0

Justin Cave
Justin Cave

Reputation: 231671

You would need to make the entire CREATE TRIGGER dynamic in order to do this. Something like this should work. You probably want to make the trigger name depend on the name of the table assuming there could be multiple tables that your query against ALL_TABLES might return multiple rows. And you certainly want the trigger to do something rather than having an empty body.

SQL> create table stg_12345( col1 number );

Table created.

SQL> begin
  2    for x in (select *
  3                from user_tables
  4               where table_name like 'STG%')
  5    loop
  6      execute immediate
  7        'create or replace trigger trg_foo ' ||
  8        ' before insert on ' || x.table_name ||
  9        ' for each row ' ||
 10        'begin ' ||
 11        '  null; ' ||
 12        'end;';
 13    end loop;
 14  end;
 15  /

PL/SQL procedure successfully completed.

SQL> select count(*) from user_triggers where trigger_name = 'TRG_FOO';

  COUNT(*)
----------
         1

Of course, the idea of an application that creates tables on the fly is one that frightens me to the core. If you have any control over that, I would strongly suggest reconsidering the architecture.

Upvotes: 2

Related Questions