Delete all contents in a schema in Oracle

Yes you can. You can drop the user and thus drop the schema objects. The DROP USER statement is used to remove a user from the Oracle database and remove all objects owned by that user.

DROP USER TestDB;

This statement will only run properly and drop the user called TestDB only if TestDB does not own any objects in its schema. Object in the sense tables and views etc. If it contains any objects then after executing the DROP USER statement you will get the below error message

Error starting at line : 1 in command -
DROP USER TestDB
Error report -
SQL Error: ORA-01922: CASCADE must be specified to drop 'TESTDB'
01922. 00000 -  "CASCADE must be specified to drop '%s'"
*Cause:    Cascade is required to remove this user from the system.  The
           user own's object which will need to be dropped.
*Action:   Specify cascade.

If TestDB did own objects in its schema, you would need to run the following DROP USER statement instead:

DROP USER TestDB CASCADE;

This statement will drop all objects owned by TestDB, and all referential integrity constraints on TestDB objects would also be dropped.


The following SQLplus script generates the SQL statements needed to delete all schema objects from the desired user:

set heading off
set pagesize 0
set feedback off

-- wipe out all scheduler jobs
select 'exec dbms_scheduler.drop_job(job_name => '''||j.job_creator||'.'||j.job_name||''');'
from user_scheduler_jobs j
/

-- wipe out all XML schemas
select 'exec dbms_xmlschema.deleteSchema(schemaURL => '''||s.qual_schema_url||''',delete_option => dbms_xmlschema.DELETE_CASCADE_FORCE);'
from user_xml_schemas s
/

-- wipe out all remaining objects
select 'drop '
       ||o.object_type
       ||' '||object_name
       ||case o.object_type when 'TABLE' then ' cascade constraints' when 'TYPE' then ' force' else '' end
       ||';'
from user_objects o
where o.object_type not in ('JOB','LOB','PACKAGE BODY','INDEX','TRIGGER')
and not exists (select 1
                from user_objects r
                where r.object_name = o.object_name 
                and   r.object_type = 'MATERIALIZED VIEW'
                and   o.object_type != 'MATERIALIZED VIEW'
               )
/

-- empty the recycle bin
select 'purge recyclebin;' from dual
/

The script works 100% for me as is - but if for some reason it is not complete for you then it is easily enhanced using a virtual machine (VM) as follows:

  1. log on as [your schema user to empty]
  2. Take a snapshot of your VM
  3. run the above script to create the deletion statements
  4. run the deletion statements (you can ignore any "object does not exist" errors, as some objects will be automatically removed prior to the script removal statement. This occurs as a result of owning objects being removed)
  5. log off
  6. log on as SYS and execute "drop user [your schema user to empty];" -- WITHOUT the cascade option

If step 6 fails then you need to identify the remaining objects preventing your user from being deleted and add them to the above script. Repeat until your user drops (ie. your script is comprehensive) then save your script

Roll back your VM to your snapshot and repeat steps 3 and 4 (using your updated script) - and you should now have a 100% empty schema.


Found the following script on github which worked out-of-the-box (SQL*Plus: Release 12.2.0.1.0 Production):

https://gist.github.com/rafaeleyng/33eaef673fc4ee98a6de4f70c8ce3657

Thanks to the author Rafael Eyng.

Just login into the schema whose objects you want to drop.

BEGIN
   FOR cur_rec IN (SELECT object_name, object_type
                     FROM user_objects
                    WHERE object_type IN
                             ('TABLE',
                              'VIEW',
                              'PACKAGE',
                              'PROCEDURE',
                              'FUNCTION',
                              'SEQUENCE',
                              'TYPE',
                              'SYNONYM',
                              'MATERIALIZED VIEW'
                             ))
   LOOP
      BEGIN
         IF cur_rec.object_type = 'TABLE'
         THEN
            EXECUTE IMMEDIATE    'DROP '
                              || cur_rec.object_type
                              || ' "'
                              || cur_rec.object_name
                              || '" CASCADE CONSTRAINTS';
         ELSE
            EXECUTE IMMEDIATE    'DROP '
                              || cur_rec.object_type
                              || ' "'
                              || cur_rec.object_name
                              || '"';
         END IF;
      EXCEPTION
         WHEN OTHERS
         THEN
            DBMS_OUTPUT.put_line (   'FAILED: DROP '
                                  || cur_rec.object_type
                                  || ' "'
                                  || cur_rec.object_name
                                  || '"'
                                 );
      END;
   END LOOP;
END;
/

There still might be PUBLIC SYNONYMS pointing to the just dropped tables. Following script deletes these as well:

BEGIN
   FOR cur_syn IN (SELECT synonym_name
                     FROM all_synonyms
                    WHERE table_owner = 'MY_USER')
   LOOP
      BEGIN
         EXECUTE IMMEDIATE 'drop public synonym ' || cur_syn.synonym_name ;
      EXCEPTION
         WHEN OTHERS
         THEN
            DBMS_OUTPUT.PUT_LINE ('Failed to drop the public synonym ' || cur_syn.synonym_name || '! ' || sqlerrm);
      END;
   END LOOP;
END;
/

Normally, it is simplest to drop and add the user. This is the preferred method if you have system or sysdba access to the database.

If you don't have system level access, and want to scrub your schema, the following sql will produce a series of drop statments, which can then be executed.

select 'drop '||object_type||' '|| object_name|| DECODE(OBJECT_TYPE,'TABLE',' CASCADE CONSTRAINTS','') || ';'  from user_objects

Then, I normally purge the recycle bin to really clean things up. To be honest, I don't see a lot of use for oracle's recycle bin, and wish i could disable it, but anyway:

purge recyclebin;

This will produce a list of drop statements. Not all of them will execute - if you drop with cascade, dropping the PK_* indices will fail. But in the end, you will have a pretty clean schema. Confirm with:

select * from user_objects

Also, just to add, the Pl/sql block in your question will delete only tables, it doesn't delete all other objects.

ps: Copied from some website, was useful to me. Tested and working like a charm.

Tags:

Sql

Oracle

Plsql