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版本之前,在这种情况下,如果不将数据库置于特殊模式,您甚至无法删除包含模式

创建上述函数(这样就可以通过函数调用DDL) 然后你可以:

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_作业
  • 删除所有数据库链接
  • 不要删除嵌套表,因为不支持删除嵌套表
创建或替换 过程将\u所有\u架构\u对象作为 布拉格自治交易; 光标c_get_对象为 选择uo.object_type object_type_2'“| | uo.object_name |'”“| |解码(uo.object_type,'TABLE','cascade constraints',null)obj_name2 来自用户_对象uo 其中uo.object_输入('TABLE','VIEW','PACKAGE','SEQUENCE','SYNONYM','MATERIALIZED VIEW','FUNCTION','PROCEDURE') 而不是(uo.object\u type='TABLE'并且存在(从user\u nested\u tables unt中选择1,其中uo.object\u name=unt.TABLE\u name)) 而不是(uo.object\u type='PROCEDURE'和uo.object\u name='DROP\u ALL\u SCHEMA\u OBJECTS') 按uo.object\u类型排序; 光标c_get_objects_类型为 选择“对象类型”“对象名称”“对象名称” 来自用户对象 其中object_输入('type'); 光标c_get_dblinks为 选择“obj|U名称” 从用户数据库链接; 光标c_get_jobs为 选择''| |对象名称'| |''''对象名称 来自用户对象 其中object_type='JOB'; 游标c_get_dbms_作业为 选择作业对象编号\u id 来自用户作业 其中schema_user!='西斯曼'; 开始 开始 对于c_get_objects循环中的object_rec 立即执行('drop'| | object|rec.object|type|2 |''.| object|rec.obj|u name2); 端环; 对于c_get_objects_type循环中的object_rec 开始 立即执行('drop'| | object|rec.object|type |''.| | object|rec.obj_name); 结束; 端环; 对于c_get_dblinks循环中的object_rec 立即执行('drop database link'| | object_rec.obj_name); 端环; 对于c_get_jobs循环中的object_rec DBMS_SCHEDULER.DROP_JOB(JOB_name=>object_rec.obj_name); 端环; 犯罪 对于c_get_dbms_jobs循环中的object_rec dbms_job.remove(object_rec.obj_number_id); 端环; 犯罪 结束; 结束删除所有模式对象; / 执行DROP\u所有\u SCHEMA\u对象; drop procedure drop_所有模式对象; 出口 哎呀!!!你不是吗
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;