Ist es möglich, alle Inhalte in Schema in Oracle zu löschen? Ich habe dieses Skript gefunden:
Begin
for c in (select table_name from user_tables) loop
execute immediate ('drop table '||c.table_name||' cascade constraints);
end loop;
End;
Aber ich würde gerne wissen, ob es irgendetwas gibt, das alles in dem Schema, Indizes, Tabellen, Einschränkungen usw. ablegt, aber nicht das Schema (drop user ...).
Vielen Dank.
Normalerweise ist es am einfachsten, den Benutzer abzulegen und hinzuzufügen. Dies ist die bevorzugte Methode, wenn Sie System- oder Sysdba-Zugriff auf die Datenbank haben.
Wenn Sie keinen Zugriff auf Systemebene haben und Ihr Schema löschen möchten, erzeugt die folgende SQL eine Reihe von Drop-Statements, die dann ausgeführt werden können.
select 'drop '||object_type||' '|| object_name|| DECODE(OBJECT_TYPE,'TABLE',' CASCADE CONSTRAINTS','') || ';' from user_objects
Dann leeren ich normalerweise den Papierkorb, um die Dinge wirklich zu bereinigen. Um ehrlich zu sein, sehe ich nicht viel für den Papierkorb von Oracle und wünschte, ich könnte ihn deaktivieren, aber trotzdem:
purge recyclebin;
Dadurch wird eine Liste mit Drop-Anweisungen erstellt. Nicht alle werden ausgeführt - wenn Sie die Kaskade ablegen, wird das Löschen der PK_ * -Indizes fehlschlagen. Aber am Ende hast du ein ziemlich sauberes Schema. Bestätigen mit:
select * from user_objects
Nur um hinzuzufügen, löscht der Pl/sql-Block in Ihrer Frage nur Tabellen und nicht alle anderen Objekte.
ps: Von einer Website kopiert, war für mich nützlich. Getestet und arbeitet wie ein Zauber.
Ja, du kannst. Sie können den Benutzer löschen und somit die Schemaobjekte löschen. Die Anweisung DROP USER wird verwendet, um einen Benutzer aus der Oracle-Datenbank und alle Objekte zu entfernen, die diesem Benutzer gehören.
DROP USER TestDB;
Diese Anweisung wird nur ordnungsgemäß ausgeführt, und der Benutzer mit dem Namen TestDB wird nur gelöscht, wenn TestDB keine Objekte in seinem Schema besitzt. Objekt in den Sense-Tabellen und -Ansichten usw. Wenn es Objekte enthält, wird nach Ausführung der DROP USER-Anweisung die folgende Fehlermeldung angezeigt
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.
Wenn TestDB eigene Objekte in seinem Schema hatte, müssten Sie stattdessen die folgende DROP USER-Anweisung ausführen:
DROP USER TestDB CASCADE;
Diese Anweisung löscht alle Objekte, deren Eigentümer TestDB ist, und alle referenziellen Integritätsbedingungen für TestDB-Objekte werden ebenfalls gelöscht.
Auf github wurde das folgende Skript gefunden, das sofort funktioniert hat (SQL * Plus: Release 12.2.0.1.0 Production):
https://Gist.github.com/rafaeleyng/33eaef673fc4ee98a6de4f70c8ce3657
Vielen Dank an den Autor Rafael Eyng.
Melden Sie sich einfach in dem Schema an, dessen Objekte Sie löschen möchten.
BEGIN
FOR cur_rec IN (SELECT object_name, object_type
FROM user_objects
WHERE object_type IN
('TABLE',
'VIEW',
'PACKAGE',
'PROCEDURE',
'FUNCTION',
'SEQUENCE',
'SYNONYM'
))
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;
/
Das habe ich benutzt:
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
Das folgende SQLplus-Skript generiert die SQL-Anweisungen, die zum Löschen aller Schemaobjekte des gewünschten Benutzers erforderlich sind:
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
/
Das Skript funktioniert zu 100% für mich, aber wenn es aus irgendeinem Grund für Sie nicht vollständig ist, kann es mit einer virtuellen Maschine (VM) wie folgt verbessert werden:
Wenn Schritt 6 fehlschlägt, müssen Sie die verbleibenden Objekte identifizieren, die verhindern, dass Ihr Benutzer gelöscht wird, und sie dem obigen Skript hinzufügen. Wiederholen Sie diesen Vorgang, bis Ihr Benutzer abbricht (dh Ihr Skript ist umfassend), und speichern Sie dann das Skript
Machen Sie Ihre VM auf Ihren Snapshot zurück und wiederholen Sie die Schritte 3 und 4 (mit Ihrem aktualisierten Skript) - und Sie sollten jetzt ein zu 100% leeres Schema haben.
Mach einfach mit:
select 'drop '||object_type||' '|| object_name || ';' from user_objects where
object_type in ('VIEW','PACKAGE','SEQUENCE', 'PROCEDURE', 'FUNCTION', 'INDEX')