Der beste und effizienteste Weg besteht darin, die Ausnahme "Tabelle nicht gefunden" abzufangen: Dadurch wird der Aufwand für die Überprüfung vermieden, ob die Tabelle zweimal vorhanden ist. und leidet nicht unter dem Problem, dass die Ausnahme immer noch für den Anrufer ausgelöst wird, wenn der DROP aus einem anderen Grund ausfällt (der möglicherweise wichtig ist):
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE ' || table_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
ADDENDUM
Als Referenz sind hier die entsprechenden Blöcke für andere Objekttypen:
Reihenfolge
BEGIN
EXECUTE IMMEDIATE 'DROP SEQUENCE ' || sequence_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -2289 THEN
RAISE;
END IF;
END;
Aussicht
BEGIN
EXECUTE IMMEDIATE 'DROP VIEW ' || view_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
Auslösen
BEGIN
EXECUTE IMMEDIATE 'DROP TRIGGER ' || trigger_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4080 THEN
RAISE;
END IF;
END;
Index
BEGIN
EXECUTE IMMEDIATE 'DROP INDEX ' || index_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -1418 THEN
RAISE;
END IF;
END;
Säule
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE ' || table_name
|| ' DROP COLUMN ' || column_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -904 AND SQLCODE != -942 THEN
RAISE;
END IF;
END;
Datenbanklink
BEGIN
EXECUTE IMMEDIATE 'DROP DATABASE LINK ' || dblink_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -2024 THEN
RAISE;
END IF;
END;
Materialisierte Ansicht
BEGIN
EXECUTE IMMEDIATE 'DROP MATERIALIZED VIEW ' || mview_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -12003 THEN
RAISE;
END IF;
END;
Art
BEGIN
EXECUTE IMMEDIATE 'DROP TYPE ' || type_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Zwang
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE ' || table_name
|| ' DROP CONSTRAINT ' || constraint_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -2443 AND SQLCODE != -942 THEN
RAISE;
END IF;
END;
Scheduler-Job
BEGIN
DBMS_SCHEDULER.drop_job(job_name);
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -27475 THEN
RAISE;
END IF;
END;
Benutzer / Schema
BEGIN
EXECUTE IMMEDIATE 'DROP USER ' || user_name;
/* you may or may not want to add CASCADE */
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -1918 THEN
RAISE;
END IF;
END;
Paket
BEGIN
EXECUTE IMMEDIATE 'DROP PACKAGE ' || package_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Verfahren
BEGIN
EXECUTE IMMEDIATE 'DROP PROCEDURE ' || procedure_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Funktion
BEGIN
EXECUTE IMMEDIATE 'DROP FUNCTION ' || function_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Tablespace
BEGIN
EXECUTE IMMEDIATE 'DROP TABLESPACE' || tablespace_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -959 THEN
RAISE;
END IF;
END;
Synonym
BEGIN
EXECUTE IMMEDIATE 'DROP SYNONYM ' || synonym_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -1434 THEN
RAISE;
END IF;
END;
EXECUTE IMMEDIATE 'DROP TABLE mytable';
Sätze hinzufüge (einen für jede Tabelle im Skript), muss ich für jeden einen Ausnahmebehandler einfügen, oder reicht es aus, alle Senteces in einenBEGIN ... EXCEPTION ... END;
Block zu packen ?IF OBJECT_ID('TblName') IS NOT NULL DROP TABLE TblName
. Es scheint, dass die Ausführlichkeit einer SQL-Sprache proportional zum Preis ist.Hiermit wird überprüft, ob eine Tabelle im aktuellen Schema vorhanden ist. Um zu überprüfen, ob eine bestimmte Tabelle bereits in einem anderen Schema vorhanden ist, müssen Sie
all_tables
stattdessenuser_tables
die Bedingung verwenden und hinzufügenall_tables.owner = upper('schema_name')
quelle
Ich habe nach dem gleichen gesucht, aber am Ende habe ich ein Verfahren geschrieben, das mir hilft:
Hoffe das hilft
quelle
Ich wollte nur einen vollständigen Code veröffentlichen, der eine Tabelle erstellt und löscht, wenn er bereits mit Jeffreys Code existiert (ein großes Lob an ihn, nicht an mich!).
quelle
Mit SQL * PLUS können Sie auch den Befehl WHENEVER SQLERROR verwenden:
Wenn
CONTINUE NONE
ein Fehler gemeldet wird, wird das Skript fortgesetzt. MitEXIT SQL.SQLCODE
dem Skript wird im Fehlerfall beendet.Siehe auch: WENN SQLERROR-Dokumente
quelle
In Oracle gibt es keine 'DROP TABLE IF EXISTS'. Sie müssten die select-Anweisung ausführen.
Versuchen Sie dies (ich bin nicht mit der Orakelsyntax vertraut. Wenn meine Variablen also ify sind, verzeihen Sie mir bitte):
quelle
Ich folge lieber einer wirtschaftlichen Lösung
quelle
Eine andere Methode besteht darin, eine Ausnahme zu definieren und diese Ausnahme dann nur abzufangen, damit sich alle anderen verbreiten können.
quelle
Eine Möglichkeit ist die Verwendung von DBMS_ASSERT.SQL_OBJECT_NAME :
DBFiddle Demo
quelle
Leider nein, es gibt keinen Tropfen, falls vorhanden, oder ERSTELLEN, WENN NICHT EXISTIEREN
Sie könnten ein plsql-Skript schreiben, um die Logik dort einzuschließen.
http://download.oracle.com/docs/cd/B12037_01/server.101/b10759/statements_9003.htm
Ich mag Oracle Syntax nicht besonders, aber ich denke, @ Erichs Skript wäre so etwas.
quelle
Sie können den Fehler jederzeit selbst abfangen.
Es wird als schlechte Praxis angesehen, dies zu überbeanspruchen, ähnlich wie bei leeren catch () in anderen Sprachen.
Grüße
K.
quelle
Ich bevorzuge es, die Tabelle und den Schemabesitzer anzugeben.
Achten Sie auch auf die Groß- und Kleinschreibung. (siehe "obere" Klausel unten).
Ich habe ein paar verschiedene Objekte hineingeworfen, um zu zeigen, dass es neben TABELLEN auch an anderen Orten verwendet werden kann.
.............
Und ein Tabellenbeispiel:
quelle
// Überprüft mit diesem Code, ob die Tabelle vorhanden ist, und erstellt später die Tabelle max. Dies funktioniert einfach in einer einzigen Kompilierung
quelle
Und wenn Sie es wieder eingeben möchten und Drop / Create-Zyklen minimieren möchten, können Sie die DDL mit dbms_metadata.get_ddl zwischenspeichern und alles mit einem Konstrukt wie dem folgenden neu erstellen:
declare v_ddl varchar2(4000); begin select dbms_metadata.get_ddl('TABLE','DEPT','SCOTT') into v_ddl from dual; [COMPARE CACHED DDL AND EXECUTE IF NO MATCH] exception when others then if sqlcode = -31603 then [GET AND EXECUTE CACHED DDL] else raise; end if; end;
Dies ist nur ein Beispiel, es sollte eine Schleife mit enthalten DDL-Typ, Name und Eigentümer sind Variablen.quelle
Ein Block wie dieser könnte für Sie nützlich sein.
quelle