The PL/SQL reference guide has a short section and example for the INSTEAD OF CREATE ON SCHEMA trigger. Since the description was so little and could not find much detail on the internet, tried some examples as below. This feature is good to prevent any CREATE operation for an user, giving him/her privilege to alter or drop existing object.
The code below shows a simple trigger that raises an error when any CREATE statement is used by the user.
SQL> show user User is BTHOMAS SQL> create or replace trigger prevent_new_objects 2 instead of create on schema 3 begin 4 raise_application_error(-20001, 'No new objects allowed in schema'); 5 end; SQL> / Trigger created. SQL> create table x1 (n1 number); create table x1 (n1 number) * ERROR at line 1: ORA-00604: error occurred at recursive SQL level 1 ORA-20001: No new objects allowed in schema ORA-06512: at line 2 SQL>
If I connect as a different user, I can create table under BTHOMAS.
SQL> connect system/* Connected. SQL> create table bthomas.x1 (n1 number); Table created. SQL>
The restriction is honored even if I use EXECUTE IMMEDIATE to create the object from a PL/SQL unit.
SQL> begin 2 execute immediate 'create table x1 (n1 number)'; 3 end; 4 / begin * ERROR at line 1: ORA-20001: No new objects allowed in schema ORA-06512: at line 2 ORA-06512: at line 2 SQL>
Things are not different even if I create the trigger under another user (you cannot create this type of trigger under SYS user!). In the code below, SYSTEM user creates the trigger owned by BTHOMAS, but still SYSTEM user cannot create any object. BTHOMAS user is unaffected.
SQL> connect system/* Connected. SQL> create or replace trigger bthomas.prevent_new_objects 2 instead of create on schema 3 begin 4 raise_application_error(-20001, 'No new objects allowed in schema'); 5* end; SQL> / Trigger created. SQL> create table x1 (x number); create table x1 (x number) * ERROR at line 1: ORA-00604: error occurred at recursive SQL level 1 ORA-20001: No new objects allowed in schema ORA-06512: at line 2 SQL> create table bthomas.x1 (n number); create table bthomas.x1 (n number) * ERROR at line 1: ORA-00604: error occurred at recursive SQL level 1 ORA-20001: No new objects allowed in schema ORA-06512: at line 2 SQL> show user USER is "SYSTEM" SQL> connect bthomas/* Connected. SQL> create table bthomas.x1 (n number); Table created. SQL>
Querying DBA_TRIGGERS will clarify this…
SQL> select OWNER, TRIGGER_NAME, TRIGGER_TYPE, TRIGGERING_EVENT, 2 TABLE_OWNER, BASE_OBJECT_TYPE 3 from dba_triggers 4 where trigger_name = 'PREVENT_NEW_OBJECTS'; OWNER TRIGGER_NAME TRIGGER_TYPE ------------------------------ ------------------------------ ---------------- TRIGGERING_EVENT -------------------------------------------------------------------------------- TABLE_OWNER BASE_OBJECT_TYPE ------------------------------ ---------------- BTHOMAS PREVENT_NEW_OBJECTS UNDEFINED CREATE SYSTEM SCHEMA SQL>
The user BTHOMAS has CREATE TABLE privilege, thus he gets drop table and alter table privileges which are unaffected by this trigger.
SQL> Show USER User is SYSTEM SQL> create table d2 (n number); create table d2 (n number) * ERROR at line 1: ORA-00604: error occurred at recursive SQL level 1 ORA-20001: No new objects allowed in schema ORA-06512: at line 2 SQL> drop table d1; Table dropped. SQL>
Finally example below shows, any CREATE statement is affected, not just CREATE TABLE.
SQL> create synonym x for y; create synonym x for y * ERROR at line 1: ORA-00604: error occurred at recursive SQL level 1 ORA-20001: No new objects allowed in schema ORA-06512: at line 2 SQL>