Oracle PLSQL-删除用户的所有数据库对象
我正试图使用一个过程(没有参数)来删除所有用户创建的数据库对象,这些对象位于启动该过程的模式中,但我真的不确定如何执行此操作。这是我到目前为止得到的,但我认为我走错了方向Oracle PLSQL-删除用户的所有数据库对象,oracle,stored-procedures,plsql,schema,Oracle,Stored Procedures,Plsql,Schema,我正试图使用一个过程(没有参数)来删除所有用户创建的数据库对象,这些对象位于启动该过程的模式中,但我真的不确定如何执行此操作。这是我到目前为止得到的,但我认为我走错了方向 create or replace procedure CLEAN_SCHEMA is cursor schema_cur is select 'drop '||object_type||' '|| object_name|| DECODE(OBJECT_TYPE,'TABLE',' CASCADE CONSTRAINTS
create or replace procedure CLEAN_SCHEMA is
cursor schema_cur is
select 'drop '||object_type||' '|| object_name|| DECODE(OBJECT_TYPE,'TABLE',' CASCADE CONSTRAINTS;',';')
from user_objects;
schema_rec schema_cur%rowtype;
begin
select 'drop '||object_type||' '|| object_name|| DECODE(OBJECT_TYPE,'TABLE',' CASCADE CONSTRAINTS;',';')
into schema_rec
from user_objects;
end;
/
除非用户很难重新应用权限,否则删除用户并重新创建权限可能更容易。这是一个好的开始 以下是剩下的:
- 您有一个游标和一个select语句。你只需要光标
- 下一步是使用动态PLSQL调用drop语句。我会使用executeimmediate语句。只需选择要删除的对象的名称,并将其作为绑定变量提交以立即执行,这样做更优雅、性能更友好
- 为了删除调用该方法的模式的对象,而不是拥有该方法的模式的对象,必须使用“AUTHID CURRENT_USER”。有关更多信息,请参阅
- 其他要删除的内容:包、函数、过程(如果在运行该方法时尝试删除该方法,系统可能会挂起然后超时)、Java类、触发器、视图和类型
最后,这显然是一个非常危险的方法,所以你可能会考虑把它放在脚本中而不是存储过程中,这样它就不会留在数据库中供任何人运行。
你很接近——正如其他人注意到的,你需要为语句执行一个“立即执行”。你应该考虑:
- 与其创建一个过程来执行此操作,不如将其作为一个匿名PL/SQL块来运行,这样就不会出现试图删除正在运行的过程的问题
- 为表的对象类型添加一个测试,在这种情况下,修改drop语句以包含级联选项,以通过外键约束处理作为其他表“父”的表。请记住,您可能会以不考虑依赖关系的顺序生成游标列表,该依赖项将阻止该下降。
- 同样关于依赖项,可能最好先删除表(在游标中添加一个解码,为该对象类型指定一个较低的数值,并按该值排序游标选择)。如果在表定义中有用作列类型的Oracle对象,则必须首先删除该表
- 如果使用Oracle高级队列,则必须通过AQ包API调用删除与此相关的对象。尽管您可以使用常规的删除表删除Oracle生成的用于队列支持的表,但您将发现自己处于第22条军规的位置,无法删除相关队列,也无法将其添加回。至少在10g版本之前,在这种情况下,如果不将数据库置于特殊模式,您甚至无法删除包含模式
select DROP_ALL_SCHEMA_OBJECTS from dual;
如果要删除所有对象,请确保不要尝试删除正在运行的进程(我不关心进程,这就是为什么我在对象类型列表中没有进程或函数)
如果要删除所有内容,需要匿名块
但我需要能够从一个只允许ansi sql(而不是plsql)的工具中实现这一点,因此需要一个存储过程
享受吧。谢谢马丁·布朗布利 我觉得我们可以用以下方式简化你的答案
CREATE OR REPLACE
procedure DROP_ALL_SCHEMA_OBJECTS AS
PRAGMA AUTONOMOUS_TRANSACTION;
cursor c_get_objects is
select object_type,'"'||object_name||'"'||decode(object_type,'TABLE' ,' cascade constraints',null) obj_name
FROM USER_OBJECTS
where object_type in ('TABLE','VIEW','PACKAGE','SEQUENCE','SYNONYM', 'MATERIALIZED VIEW', 'TYPE')
order by object_type;
BEGIN
begin
for object_rec in c_get_objects loop
execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name);
end loop;
end;
END DROP_ALL_SCHEMA_OBJECTS;
/
execute DROP_ALL_SCHEMA_OBJECTS;
感谢马丁·布朗布利和维贾扬·斯里尼瓦桑 但是Vijayan Srinivasan的版本是不正确的,因为类型为“type”的依赖对象在删除它们时有时会产生错误: ORA-02303:无法删除或替换具有类型或表依赖项的类型 “我的版本”从架构中删除所有对象,并附加以下内容:
- 删除过程和函数(除了“删除所有模式对象”)
- 删除所有作业和dbms_作业
- 删除所有数据库链接
- 不要删除嵌套表,因为不支持删除嵌套表
select DROP_ALL_SCHEMA_OBJECTS from dual;
CREATE OR REPLACE
procedure DROP_ALL_SCHEMA_OBJECTS AS
PRAGMA AUTONOMOUS_TRANSACTION;
cursor c_get_objects is
select object_type,'"'||object_name||'"'||decode(object_type,'TABLE' ,' cascade constraints',null) obj_name
FROM USER_OBJECTS
where object_type in ('TABLE','VIEW','PACKAGE','SEQUENCE','SYNONYM', 'MATERIALIZED VIEW', 'TYPE')
order by object_type;
BEGIN
begin
for object_rec in c_get_objects loop
execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name);
end loop;
end;
END DROP_ALL_SCHEMA_OBJECTS;
/
execute DROP_ALL_SCHEMA_OBJECTS;
CREATE OR REPLACE
procedure DROP_ALL_SCHEMA_OBJECTS AS
PRAGMA AUTONOMOUS_TRANSACTION;
cursor c_get_objects is
select uo.object_type object_type_2,'"'||uo.object_name||'"'||decode(uo.object_type,'TABLE' ,' cascade constraints',null) obj_name2
FROM USER_OBJECTS uo
where uo.object_type in ('TABLE','VIEW','PACKAGE','SEQUENCE','SYNONYM', 'MATERIALIZED VIEW', 'FUNCTION', 'PROCEDURE')
and not (uo.object_type = 'TABLE' and exists (select 1 from user_nested_tables unt where uo.object_name = unt.table_name))
and not (uo.object_type = 'PROCEDURE' and uo.object_name = 'DROP_ALL_SCHEMA_OBJECTS')
order by uo.object_type;
cursor c_get_objects_type is
select object_type, '"'||object_name||'"' obj_name
from user_objects
where object_type in ('TYPE');
cursor c_get_dblinks is
select '"'||db_link||'"' obj_name
from user_db_links;
cursor c_get_jobs is
select '"'||object_name||'"' obj_name
from user_objects
where object_type = 'JOB';
cursor c_get_dbms_jobs is
select job obj_number_id
from user_jobs
where schema_user != 'SYSMAN';
BEGIN
begin
for object_rec in c_get_objects loop
execute immediate ('drop '||object_rec.object_type_2||' ' ||object_rec.obj_name2);
end loop;
for object_rec in c_get_objects_type loop
begin
execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name);
end;
end loop;
for object_rec in c_get_dblinks loop
execute immediate ('drop database link '||object_rec.obj_name);
end loop;
for object_rec in c_get_jobs loop
DBMS_SCHEDULER.DROP_JOB(job_name => object_rec.obj_name);
end loop;
commit;
for object_rec in c_get_dbms_jobs loop
dbms_job.remove(object_rec.obj_number_id);
end loop;
commit;
end;
END DROP_ALL_SCHEMA_OBJECTS;
/
execute DROP_ALL_SCHEMA_OBJECTS;
drop procedure DROP_ALL_SCHEMA_OBJECTS;
exit;