我正在尝试使用一个过程(没有参数)来删除程序启动过程中位于模式中的所有用户创建的数据库对象,但我真的不确定如何解决这个问题 . 这是我到目前为止所拥有的,但我认为我的方式是错误的 .
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;
/
7 回答
创建上面的函数(自主,因此可以通过函数调用DDL)然后您可以:
当你想要删除所有对象时,请确保你不要尝试删除你正在运行的proc(我不关心procs,这就是为什么我在object_type列表中没有procs或函数)
如果你想丢弃所有你需要一个匿名块
但我需要能够从一个只允许ansi sql(而不是plsql)的工具做到这一点,因此存储过程 .
请享用 .
除非用户很难重新申请权限,否则可能更容易删除用户并重新创建它们 .
谢谢Martin Brambley,
我觉得我们可以通过以下方式简化您的答案 .
你所拥有的是一个良好的开端 .
其余部分如下:
您有一个游标和一个select语句 . 你只需要光标 .
下一步是使用动态PLSQL调用drop语句 . 我'd use the EXECUTE IMMEDIATE statement. Its more elegant and preformance friendly to just select the name of the thing you'重新丢弃并将其作为绑定变量提交给EXECUTE IMMEDIATE .
为了删除调用方法的模式的对象而不是拥有该方法的模式,您必须使用"AUTHID CURRENT_USER" . 有关详细信息,请参阅the Oracle documentation .
要删除的其他内容:包,函数,过程(如果在运行时尝试删除此方法,系统可能会挂起然后超时),Java类,触发器,视图,类型
最后,这显然是一种非常危险的方法,因此您可能需要考虑将其放在脚本而不是存储过程中,这样它就不会留在数据库中供任何人运行 .
你很接近 - 正如其他人已经注意到你需要一个“执行立即”的声明 . 你应该考虑:
不要创建执行此操作的过程,而是将其作为匿名PL / SQL块运行,这样您就不会遇到尝试删除正在运行的过程的问题 .
为TABLE的对象类型添加测试,对于该情况,修改drop语句以包含cascade选项,以通过外键约束处理作为其他表的“父”的表 . 请记住,您可能会按照不考虑阻止丢弃的依赖关系的顺序生成游标列表 .
此外,关于依赖性的主题,最好先删除表(在游标中添加一个DECODE,为该对象类型分配较低的数值,并按此值对光标进行排序) . 如果您具有TYPE类型的Oracle对象,这些对象在表定义中用作列类型,则必须先删除该表 .
如果使用Oracle Advanced Queuing,则必须使用AQ包API调用删除与此相关的对象 . 虽然您可以使用常规DROP TABLE删除Oracle生成的队列支持表,但您将发现自己处于catch-22位置,然后无法删除相关队列,也无法将其添加回来 . 至少版本10g至少你甚至无法在没有将数据库置于特殊模式时删除包含模式
谢谢 Martin Brambley 和 Vijayan Srinivasan !
但是Vijayan Srinivasan的版本不正确,因为“TYPE”类型的依赖对象有时会在丢弃它们时产生错误:
我的版本从Schema中删除所有对象以及其他:
drop程序和功能(期待'DROP_ALL_SCHEMA_OBJECTS')
删除所有作业和dbms_jobs
删除所有db_links
不删除嵌套表,因为不支持嵌套表的DROPing