删除 Oracle 模式中的所有内容
Delete all contents in a schema in Oracle
Oracle中是否可以删除scheme中的所有内容?我找到了这个脚本:
Begin
for c in (select table_name from user_tables) loop
execute immediate ('drop table '||c.table_name||' cascade constraints);
end loop;
End;
但我想知道是否有任何东西可以删除模式、索引、表、约束中的所有内容...但不是模式(删除用户...)。
谢谢。
是的,你可以。您可以删除用户,从而删除架构对象。
DROP USER 语句用于从 Oracle 数据库中删除用户并删除该用户拥有的所有对象。
DROP USER TestDB;
只有当 TestDB 在其架构中不拥有任何对象时,此语句才会 运行 正确并删除名为 TestDB 的用户。意义上的对象表和视图等。
如果它包含任何对象,那么在执行 DROP USER 语句后,您将收到以下错误消息
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.
如果 TestDB 在其架构中确实拥有对象,则您需要 运行 以下 DROP USER 语句:
DROP USER TestDB CASCADE;
此语句将删除 TestDB 拥有的所有对象,并且 TestDB 对象上的所有参照完整性约束也将被删除。
通常,删除和添加用户是最简单的。如果您对数据库具有系统或 sysdba 访问权限,则这是首选方法。
如果您没有系统级访问权限,并且想要清除您的架构,以下 sql 将生成一系列删除语句,然后可以执行这些语句。
select 'drop '||object_type||' '|| object_name|| DECODE(OBJECT_TYPE,'TABLE',' CASCADE CONSTRAINTS','') || ';' from user_objects
然后,我通常会清除回收站以真正清理一切。老实说,我没有看到 oracle 的回收站有多大用处,希望我可以禁用它,但无论如何:
purge recyclebin;
这将生成一个 drop 语句列表。并非所有这些都会执行 - 如果您使用级联删除,删除 PK_* 索引将失败。但最终,您将拥有一个非常干净的模式。确认:
select * from user_objects
此外,补充一下,您问题中的 Pl/sql 块只会删除表格,不会删除所有其他对象。
ps: 从某个网站复制过来的,对我有用。经过测试并且工作得很好。
以下 SQLplus 脚本生成删除所需用户的所有架构对象所需的 SQL 语句:
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
/
该脚本对我来说 100% 正常工作 - 但如果由于某种原因它对您来说不完整,那么可以使用虚拟机 (VM) 轻松增强它,如下所示:
- 以[您的模式用户清空]登录
- 拍摄您的 VM 的快照
- 运行以上脚本创建删除语句
- 运行 删除语句 (您可以忽略任何 "object does not exist" 错误,因为某些对象将在脚本删除语句之前自动删除。这是由于拥有被删除的对象)
- 注销
- 以 SYS 身份登录并执行 "drop user [your schema user to empty];" -- 没有级联选项
如果第 6 步失败,那么您需要识别阻止您的用户被删除的其余对象,并将它们添加到上述脚本中。重复直到您的用户放弃(即您的脚本很全面)然后保存您的脚本
将您的 VM 回滚到您的快照并重复步骤 3 和 4(使用更新后的脚本)- 您现在应该有一个 100% 空的架构。
这是我用的:
set echo off feedback off serverout on
spool drop_all_objects.sql
declare l_object varchar2(32000);
begin
for i in (select object_name, object_type from dba_objects where owner='<owner>') loop
if i.object_type='JOB' then
l_object := 'begin dbms_scheduler.drop_job (job_name => ''<owner>'||i.object_name||'''); end;';
elsif i.object_type='PROGRAM' then
l_object := 'begin dbms_scheduler.drop_program (program_name => ''<owner>'||i.object_name||'''); end;';
elsif i.object_type='RULE' then
l_object := 'begin dbms_rule_adm.drop_rule (rule_name => ''<owner>'||i.object_name||''', force => TRUE); end;';
elsif i.object_type='RULE SET' then
l_object := 'begin dbms_rule_adm.drop_rule_set (rule_set_name => ''<owner>'||i.object_name||''', delete_rules => TRUE); end;';
elsif i.object_type='CHAIN' then
l_object := 'begin dbms_scheduler.drop_chain (chain_name => ''<owner>'||i.object_name||''', force => TRUE); end;';
elsif i.object_type='RULE' then
l_object := 'begin dbms_rule_adm.drop_evaluation_context (evaluation_context_name => ''<owner>'||i.object_name||''', force => TRUE); end;';
else
l_object := 'drop '||i.object_type||'<owner>'||i.object_name||';';
end if;
dbms_output.put_line(i_object);
dbms_output.put_line('/');
end loop;
end;
/
@drop_all_objects
只需选择:
select 'drop '||object_type||' '|| object_name || ';' from user_objects where
object_type in ('VIEW','PACKAGE','SEQUENCE', 'PROCEDURE', 'FUNCTION', 'INDEX')
在 github 上找到了以下脚本,它可以开箱即用(SQL*Plus:Release 12.2.0.1.0 Production):
https://gist.github.com/rafaeleyng/33eaef673fc4ee98a6de4f70c8ce3657
感谢作者 Rafael Eyng。
只需登录到您要删除其对象的架构。
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;
/
仍然可能 PUBLIC SYNONYMS 指向刚刚删除的表。以下脚本也删除了这些:
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;
/
Oracle中是否可以删除scheme中的所有内容?我找到了这个脚本:
Begin
for c in (select table_name from user_tables) loop
execute immediate ('drop table '||c.table_name||' cascade constraints);
end loop;
End;
但我想知道是否有任何东西可以删除模式、索引、表、约束中的所有内容...但不是模式(删除用户...)。
谢谢。
是的,你可以。您可以删除用户,从而删除架构对象。 DROP USER 语句用于从 Oracle 数据库中删除用户并删除该用户拥有的所有对象。
DROP USER TestDB;
只有当 TestDB 在其架构中不拥有任何对象时,此语句才会 运行 正确并删除名为 TestDB 的用户。意义上的对象表和视图等。 如果它包含任何对象,那么在执行 DROP USER 语句后,您将收到以下错误消息
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.
如果 TestDB 在其架构中确实拥有对象,则您需要 运行 以下 DROP USER 语句:
DROP USER TestDB CASCADE;
此语句将删除 TestDB 拥有的所有对象,并且 TestDB 对象上的所有参照完整性约束也将被删除。
通常,删除和添加用户是最简单的。如果您对数据库具有系统或 sysdba 访问权限,则这是首选方法。
如果您没有系统级访问权限,并且想要清除您的架构,以下 sql 将生成一系列删除语句,然后可以执行这些语句。
select 'drop '||object_type||' '|| object_name|| DECODE(OBJECT_TYPE,'TABLE',' CASCADE CONSTRAINTS','') || ';' from user_objects
然后,我通常会清除回收站以真正清理一切。老实说,我没有看到 oracle 的回收站有多大用处,希望我可以禁用它,但无论如何:
purge recyclebin;
这将生成一个 drop 语句列表。并非所有这些都会执行 - 如果您使用级联删除,删除 PK_* 索引将失败。但最终,您将拥有一个非常干净的模式。确认:
select * from user_objects
此外,补充一下,您问题中的 Pl/sql 块只会删除表格,不会删除所有其他对象。
ps: 从某个网站复制过来的,对我有用。经过测试并且工作得很好。
以下 SQLplus 脚本生成删除所需用户的所有架构对象所需的 SQL 语句:
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
/
该脚本对我来说 100% 正常工作 - 但如果由于某种原因它对您来说不完整,那么可以使用虚拟机 (VM) 轻松增强它,如下所示:
- 以[您的模式用户清空]登录
- 拍摄您的 VM 的快照
- 运行以上脚本创建删除语句
- 运行 删除语句 (您可以忽略任何 "object does not exist" 错误,因为某些对象将在脚本删除语句之前自动删除。这是由于拥有被删除的对象)
- 注销
- 以 SYS 身份登录并执行 "drop user [your schema user to empty];" -- 没有级联选项
如果第 6 步失败,那么您需要识别阻止您的用户被删除的其余对象,并将它们添加到上述脚本中。重复直到您的用户放弃(即您的脚本很全面)然后保存您的脚本
将您的 VM 回滚到您的快照并重复步骤 3 和 4(使用更新后的脚本)- 您现在应该有一个 100% 空的架构。
这是我用的:
set echo off feedback off serverout on
spool drop_all_objects.sql
declare l_object varchar2(32000);
begin
for i in (select object_name, object_type from dba_objects where owner='<owner>') loop
if i.object_type='JOB' then
l_object := 'begin dbms_scheduler.drop_job (job_name => ''<owner>'||i.object_name||'''); end;';
elsif i.object_type='PROGRAM' then
l_object := 'begin dbms_scheduler.drop_program (program_name => ''<owner>'||i.object_name||'''); end;';
elsif i.object_type='RULE' then
l_object := 'begin dbms_rule_adm.drop_rule (rule_name => ''<owner>'||i.object_name||''', force => TRUE); end;';
elsif i.object_type='RULE SET' then
l_object := 'begin dbms_rule_adm.drop_rule_set (rule_set_name => ''<owner>'||i.object_name||''', delete_rules => TRUE); end;';
elsif i.object_type='CHAIN' then
l_object := 'begin dbms_scheduler.drop_chain (chain_name => ''<owner>'||i.object_name||''', force => TRUE); end;';
elsif i.object_type='RULE' then
l_object := 'begin dbms_rule_adm.drop_evaluation_context (evaluation_context_name => ''<owner>'||i.object_name||''', force => TRUE); end;';
else
l_object := 'drop '||i.object_type||'<owner>'||i.object_name||';';
end if;
dbms_output.put_line(i_object);
dbms_output.put_line('/');
end loop;
end;
/
@drop_all_objects
只需选择:
select 'drop '||object_type||' '|| object_name || ';' from user_objects where
object_type in ('VIEW','PACKAGE','SEQUENCE', 'PROCEDURE', 'FUNCTION', 'INDEX')
在 github 上找到了以下脚本,它可以开箱即用(SQL*Plus:Release 12.2.0.1.0 Production):
https://gist.github.com/rafaeleyng/33eaef673fc4ee98a6de4f70c8ce3657
感谢作者 Rafael Eyng。
只需登录到您要删除其对象的架构。
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;
/
仍然可能 PUBLIC SYNONYMS 指向刚刚删除的表。以下脚本也删除了这些:
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;
/