Wie verwende ich CREATE OR REPLACE?

98

Habe ich Recht, wenn ich verstehe, dass CREATE OR REPLACE im Grunde bedeutet: "Wenn das Objekt existiert, lassen Sie es fallen und erstellen Sie es so oder so?"

Wenn ja, was mache ich falsch? Das funktioniert:

CREATE TABLE foo (id NUMBER,
title VARCHAR2(4000) DEFAULT 'Default Title')

Und das nicht (ORA-00922: fehlende oder ungültige Option):

CREATE OR REPLACE TABLE foo (id NUMBER,
title VARCHAR2(4000) DEFAULT 'Default Title')

Mache ich etwas dummes Ich scheine nicht in der Lage zu sein, viel Dokumentation über diese Syntax zu finden.

Jason Baker
quelle

Antworten:

153

Dies funktioniert für Funktionen, Prozeduren, Pakete, Typen, Synonyme, Trigger und Ansichten.

Aktualisieren:

Nachdem ich den Beitrag zum dritten Mal aktualisiert habe, werde ich Folgendes umformulieren:

Dies funktioniert nicht auf Tabellen :)

Und ja, es gibt eine Dokumentation zu dieser Syntax und es gibt keine REPLACEOption für CREATE TABLE.

Quassnoi
quelle
33

Eines der schönen Dinge an der Syntax ist, dass Sie sicher sein können, dass a CREATE OR REPLACEniemals dazu führt, dass Sie Daten verlieren (das meiste, was Sie verlieren, ist Code, den Sie hoffentlich irgendwo in der Quellcodeverwaltung gespeichert haben).

Die äquivalente Syntax für Tabellen lautet ALTER. Dies bedeutet, dass Sie die genauen erforderlichen Änderungen explizit auflisten müssen.

BEARBEITEN: Übrigens, wenn Sie DROP + CREATE in einem Skript ausführen müssen und sich nicht um die falschen Fehler "Objekt existiert nicht" kümmern (wenn der DROP die Tabelle nicht findet), können Sie dies tun Dies:

BEGIN
  EXECUTE IMMEDIATE 'DROP TABLE owner.mytable';
EXCEPTION
  WHEN OTHERS THEN
    IF sqlcode != -0942 THEN RAISE; END IF;
END;
/
Jeffrey Kemp
quelle
23

In Oracle gibt es keine Tabelle zum Erstellen oder Ersetzen.

Sie müssen:

TROPFENTABELLE foo;
TABELLE ERSTELLEN foo (....);
RC.
quelle
10

CREATE OR REPLACE kann nur für Funktionen, Prozeduren, Typen, Ansichten oder Pakete verwendet werden - es funktioniert nicht für Tabellen.

Andy Mikula
quelle
1
CREATE OR REPLACEfunktioniert auch für Synonyme und Trigger
Richard Mitchell
4

Das folgende Skript sollte den Trick unter Oracle ausführen:

BEGIN
  EXECUTE IMMEDIATE 'drop TABLE tablename';
EXCEPTION
  WHEN OTHERS THEN
    IF sqlcode != -0942 THEN RAISE; 
    END IF;
END;
Kavan
quelle
3

Funktioniert nicht mit Tabellen, nur Funktionen usw.

Hier ist eine Seite mit einigen Beispielen .

Nordpol
quelle
3

Eine nützliche Prozedur für Oracle-Datenbanken ohne Verwendung von Ausnahmen (unter Umständen müssen Sie user_tables durch dba_tables ersetzen und / oder den Tablespace in der Abfrage einschränken):

create or replace procedure NG_DROP_TABLE(tableName varchar2)
is
   c int;
begin
   select count(*) into c from user_tables where table_name = upper(tableName);
   if c = 1 then
      execute immediate 'drop table '||tableName;
   end if;
end;
XorNegative
quelle
3
-- To Create or Replace a Table we must first silently Drop a Table that may not exist
DECLARE
  table_not_exist EXCEPTION;
  PRAGMA EXCEPTION_INIT (table_not_exist , -00942);
BEGIN
   EXECUTE IMMEDIATE('DROP TABLE <SCHEMA>.<TABLE NAME> CASCADE CONSTRAINTS');
   EXCEPTION WHEN table_not_exist THEN NULL;
END;
/
Grokster
quelle
Ein bisschen mehr Code als andere Beispiele, aber auch ein bisschen klarer in seinem Zweck
Grokster
1

Wenn Sie im Code arbeiten, suchen Sie zuerst mit der Abfrage SELECT table_name FROM user_tables WHERE table_name = 'XYZ' nach Tabellen in der Datenbank.

Wenn ein Datensatz gefunden wurde, kürzen Sie die Tabelle. Andernfalls erstellen Sie eine Tabelle

Arbeiten Sie wie Erstellen oder Ersetzen.

Pradip Gavali
quelle
1

Sie können CORT ( www.softcraftltd.co.uk/cort ) verwenden. Mit diesem Tool können Sie Tabellen in Oracle erstellen oder ersetzen. Es sieht aus wie:

create /*# or replace */ table MyTable(
  ... -- standard table definition
);

Es bewahrt Daten.

rostig
quelle
1

Also habe ich das benutzt und es hat sehr gut funktioniert: - Es funktioniert eher wie ein DROP, WENN EXISTIERT, aber die Arbeit erledigt

DECLARE
       VE_TABLENOTEXISTS EXCEPTION;
PRAGMA EXCEPTION_INIT(VE_TABLENOTEXISTS, -942);


    PROCEDURE DROPTABLE(PIS_TABLENAME IN VARCHAR2) IS
              VS_DYNAMICDROPTABLESQL VARCHAR2(1024);
                    BEGIN
                       VS_DYNAMICDROPTABLESQL := 'DROP TABLE ' || PIS_TABLENAME;  
                    EXECUTE IMMEDIATE VS_DYNAMICDROPTABLESQL;

                    EXCEPTION
                        WHEN VE_TABLENOTEXISTS THEN
                             DBMS_OUTPUT.PUT_LINE(PIS_TABLENAME || ' NOT EXIST, SKIPPING....');
                        WHEN OTHERS THEN
                             DBMS_OUTPUT.PUT_LINE(SQLERRM);
                    RAISE;
                    END DROPTABLE;

    BEGIN
      DROPTABLE('YOUR_TABLE_HERE');
END DROPTABLE;
/   

Hoffe das hilft auch Verweis: PLS-00103 Fehler in PL / SQL Developer

BGDev
quelle
1

'Tabelle erstellen oder ersetzen' ist nicht möglich. Wie bereits erwähnt, können Sie eine Prozedur schreiben und / oder begin execute sofort verwenden (...). Da ich keine Antwort zum (erneuten) Erstellen der Tabelle sehe, habe ich ein Skript als Antwort eingefügt.

PS: In Übereinstimmung mit dem, was Jeffrey-Kemp erwähnt hat: Dieses Skript speichert KEINE Daten, die bereits in der Tabelle vorhanden sind, die Sie löschen möchten. Aufgrund des Risikos des Datenverlusts dürfen in unserem Unternehmen nur vorhandene Tabellen in der Produktionsumgebung geändert und keine Tabellen gelöscht werden. Wenn Sie die Drop-Table-Anweisung verwenden, wird früher oder später die Firmenpolizei an Ihrem Schreibtisch stehen.

--Create the table 'A_TABLE_X', and drop the table in case it already is present
BEGIN
EXECUTE IMMEDIATE 
'
CREATE TABLE A_TABLE_X
(
COLUMN1 NUMBER(15,0),
COLUMN2  VARCHAR2(255 CHAR),
COLUMN3  VARCHAR2(255 CHAR)
)';

EXCEPTION
WHEN OTHERS THEN
  IF SQLCODE != -955 THEN -- ORA-00955: object name already used
     EXECUTE IMMEDIATE 'DROP TABLE A_TABLE_X';
  END IF;
END;
Cybork
quelle
Müssen Sie mit A_TABLE_EXAMPLE und A_TABLE_X konsistent sein?
Jonathan Leffler
0

Ich würde so etwas tun

  begin
     for i in (select table_name from user_tables where table_name = 'FOO') loop
        execute immediate 'drop table '||i.table_name;
     end loop;
  end;

  execute immediate 'CREATE TABLE FOO (id NUMBER,
                                       title VARCHAR2(4000)) ';
ljupcecar
quelle
-4

Wenn dies für MS SQL ist. Der folgende Code wird immer ausgeführt, unabhängig davon, ob die Tabelle bereits vorhanden ist oder nicht.

if object_id('mytablename') is not null //has the table been created already in the db
Begin
     drop table mytablename
End

Create table mytablename (...
JuniorFlip
quelle
1
Entschuldigung, aber das ist Oracle. :-)
Jason Baker
Ist der Kommentar "// Gibt es Daten in der Tabelle" korrekt?
Jeffrey Kemp
Entschuldigung, ein bisschen besser, die object_id prüft, ob die Tabelle in der Datenbank vorhanden ist. es sollte
heißen