Reputation: 129
The query below will return a statement that can be used to drop all the tables which are present in the current user A's schema (normal scenario).
select 'drop '||object_type||' '|| object_name || ';'
from user_objects
where object_type in ('VIEW','PACKAGE','SEQUENCE', 'PROCEDURE', 'FUNCTION', 'INDEX');
But what if this query is run by the DBA with a SYS or SYSDBA login? What objects are present in the user_objects view when logged in using sys/sysdba user? Will it drop all the tables of all the schemas in the database or will the query throw an error? Intention is to drop only objects of Schema 'A'.
Upvotes: 7
Views: 40740
Reputation: 1728
CREATE OR REPLACE PROCEDURE PROC_ABHISEK_CLEAR_DB_SCHEMA AS
/******************************************************************************
NAME: PROC_ABHISEK_CLEAR_DB_SCHEMA
PURPOSE: Clears Database Schema by dropping vital Oracle Objects
AUTHOR: ABHISEK
DATE: 28-Jan-2021
******************************************************************************/
TYPE list_string is table of varchar2(300);
query_list list_string;
delete_gen_query varchar2(500);
PROGRAM_NAME varchar2(50);
begin
PROGRAM_NAME := 'DB CLEARING PROCESS';
dbms_output.put_line(PROGRAM_NAME||' Started...');
delete_gen_query := q'$select 'drop ' || object_type || ' ' ||
DECODE(object_type, 'TABLE', object_name || ' CASCADE CONSTRAINTS',
object_name)
from user_objects
where object_type in ('TABLE','VIEW','SEQUENCE') order by object_name$';
execute immediate delete_gen_query bulk collect into query_list;
dbms_output.put_line('Total Objects to be deleted: ' || query_list.count );
for cnt in 1..query_list.count
loop
execute immediate query_list(cnt);
end loop;
end PROC_ABHISEK_CLEAR_DB_SCHEMA;
/
Upvotes: 0
Reputation: 1960
FYI, the query below only generates all the sql, then you need to run the generated sql to actually get things done.
Code Snippet (with tables included):
select 'drop '||object_type||' '|| object_name || ';'
from user_objects
where object_type in ('VIEW','PACKAGE','SEQUENCE', 'PROCEDURE', 'FUNCTION', 'INDEX', 'TABLE');
Upvotes: 2
Reputation: 191570
The user_objects
view has the current user's objects, so if run as SYS it would try to drop SYS's objects - very bad news, as it would destroy your database. You can read about the three versions of tthat view in the documentation.
For SYS to see another user's objects you should look at the dba_objects
view instead, filtering on the user you're interested in; and include the target schema (owner) in the drop statement too:
select 'drop ' || object_type || ' "' || owner || '"."' || object_name || '";'
from dba_objects
where object_type in ('VIEW','PACKAGE','SEQUENCE', 'PROCEDURE', 'FUNCTION', 'INDEX')
and owner = 'A';
I've also included wrapping the object name (and less usefully the owner) in double quotes, in case there are any objects that were created with quoted identifiers.
If you included tables in the query and tried to run the output you might get errors from trying to drop dependent obects in the wrong order, i.e. dropping a parent table before its children. There are object types too, but if you ultimately want to drop everything, it might be simpler to drop and recreate the user - capturing and recreating their privileges too.
Upvotes: 6
Reputation: 5298
No when executed as SYS it will destroy your database. Try this. It will prompt 3 times for schema name to be cleared.
Beware this script might get stuck in a infinite loop, if you have curious object type in your schema (like SCHEDULER CHAIN - for example)
set serveroutput on size unlimited
declare
v_ItemCount integer;
begin
SELECT count(*)
INTO v_ItemCount
FROM ALL_OBJECTS AO
WHERE AO.OWNER = '&USER'
AND AO.OBJECT_TYPE NOT IN ('INDEX', 'LOB')
AND AO.OBJECT_NAME NOT LIKE 'BIN$%';
while (v_ItemCount > 0) loop
for v_Cmd in (SELECT 'drop ' || AO.OBJECT_TYPE || ' ' || '"'||AO.OWNER||'"'|| '.' || '"'||AO.OBJECT_NAME||'"' ||
DECODE(AO.OBJECT_TYPE,
'TABLE',
' CASCADE CONSTRAINTS',
'') as DROPCMD,
AO.OWNER,
AO.OBJECT_TYPE,
AO.OBJECT_NAME
FROM ALL_OBJECTS AO
WHERE AO.OWNER = '&USER'
AND AO.OBJECT_TYPE NOT IN ('INDEX', 'LOB')
AND AO.OBJECT_NAME NOT LIKE 'BIN$%')
loop
begin
if v_Cmd.OBJECT_TYPE = 'SCHEDULE' then
DBMS_SCHEDULER.DROP_SCHEDULE('"'||v_Cmd.OWNER||'"'||'.'||'"'||v_Cmd.OBJECT_NAME||'"', true);
ELSIF v_Cmd.OBJECT_TYPE = 'JOB' then
DBMS_SCHEDULER.DROP_JOB('"'||v_Cmd.OWNER||'"'||'.'||'"'||v_Cmd.OBJECT_NAME||'"', true);
ELSIF v_Cmd.OBJECT_TYPE = 'PROGRAM' then
DBMS_SCHEDULER.DROP_PROGRAM('"'||v_Cmd.OWNER||'"'||'.'||'"'||v_Cmd.OBJECT_NAME||'"', true);
else
execute immediate v_Cmd.dropcmd;
end if;
dbms_output.put_line(v_Cmd.dropcmd);
exception
when others then
null; -- ignore errors
end;
end loop;
SELECT count(*)
INTO v_ItemCount
FROM ALL_OBJECTS AO
WHERE AO.OWNER = '&USER'
AND AO.OBJECT_TYPE NOT IN ('INDEX','LOB')
AND AO.OBJECT_NAME NOT LIKE 'BIN$%';
end loop;
execute immediate 'purge dba_recyclebin';
end;
Upvotes: 1