Jak używać funkcji UTWÓRZ LUB ZAMIEŃ?

98

Czy mam rację rozumiejąc, że STWÓRZ LUB ZAMIEŃ zasadniczo oznacza „jeśli obiekt istnieje, upuść go, a następnie utwórz w dowolny sposób?”

Jeśli tak, co robię źle? To działa:

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

A to nie jest (ORA-00922: brak lub nieprawidłowa opcja):

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

Robię coś głupiego? Wydaje się, że nie mogę znaleźć dużej dokumentacji na temat tej składni.

Jason Baker
źródło

Odpowiedzi:

154

Działa to na funkcje, procedury, pakiety, typy, synonimy, wyzwalacze i widoki.

Aktualizacja:

Po zaktualizowaniu postu po raz trzeci przeformułuję to:

To nie działa na stołach :)

I tak, istnieje dokumentacja dotycząca tej składni i nie ma REPLACEopcji dla CREATE TABLE.

Quassnoi
źródło
33

Jedną z fajnych rzeczy w składni jest to, że możesz być pewien, że a CREATE OR REPLACEnigdy nie spowoduje utraty danych (najwięcej stracisz to kod, który, miejmy nadzieję, przechowujesz gdzieś w kontroli źródła).

Równoważna składnia dla tabel to ALTER, co oznacza, że ​​musisz jawnie wyliczyć dokładne zmiany, które są wymagane.

EDYCJA: Nawiasem mówiąc, jeśli musisz wykonać DROP + CREATE w skrypcie i nie przejmujesz się fałszywymi błędami „obiekt nie istnieje” (gdy DROP nie znajduje tabeli), możesz to zrobić to:

BEGIN
  EXECUTE IMMEDIATE 'DROP TABLE owner.mytable';
EXCEPTION
  WHEN OTHERS THEN
    IF sqlcode != -0942 THEN RAISE; END IF;
END;
/
Jeffrey Kemp
źródło
23

W Oracle nie ma tworzenia ani zastępowania tabeli.

Musisz:

DROP TABLE foo;
UTWÓRZ TABELĘ foo (....);
RC.
źródło
10

CREATE OR REPLACE może być używany tylko w funkcjach, procedurach, typach, widokach lub pakietach - nie będzie działać na tabelach.

Andy Mikula
źródło
1
CREATE OR REPLACEdziała również dla synonimów i wyzwalaczy
Richard Mitchell
4

Poniższy skrypt powinien załatwić sprawę na Oracle:

BEGIN
  EXECUTE IMMEDIATE 'drop TABLE tablename';
EXCEPTION
  WHEN OTHERS THEN
    IF sqlcode != -0942 THEN RAISE; 
    END IF;
END;
Kavan
źródło
3

Nie działa z tabelami, tylko funkcjami itp.

Oto strona z kilkoma przykładami .

biegun północny
źródło
3

Przydatna procedura dla baz danych Oracle bez użycia wyjątków (w pewnych okolicznościach musisz zamienić user_tables na dba_tables i / lub ograniczyć przestrzeń tabel w zapytaniu):

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
źródło
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
źródło
Trochę więcej kodu niż inne przykłady, ale także trochę jaśniejszy w jego celu
grokster
1

Jeśli robisz w kodzie, najpierw sprawdź tabelę w bazie danych za pomocą zapytania SELECT nazwa_tabeli FROM user_tables WHERE nazwa_tabeli = 'XYZ'

jeśli znaleziono rekord, obetnij tabelę, w przeciwnym razie utwórz tabelę

Działa jak Utwórz lub Zastąp.

Pradip Gavali
źródło
1

Możesz użyć CORT ( www.softcraftltd.co.uk/cort ). To narzędzie umożliwia TWORZENIE LUB WYMIENIANIE tabeli w Oracle. To wygląda jak:

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

Zachowuje dane.

Zardzewiały
źródło
1

Więc używam tego i działa bardzo dobrze: - działa bardziej jak DROP, JEŚLI ISTNIEJE, ale wykonuje swoją pracę

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;
/   

Mam nadzieję, że to pomoże. Również odniesienie: PLS-00103 Błąd w PL / SQL Developer

BGDev
źródło
1

„Utwórz lub zamień tabelę” nie jest możliwe. Jak powiedzieli inni, możesz napisać procedurę i / lub użyć natychmiastowego rozpoczęcia wykonywania (...). Ponieważ nie widzę odpowiedzi na temat tego, jak (ponownie) utworzyć tabelę, jako odpowiedź wstawiłem skrypt.

PS: zgodnie z tym, o czym wspomniał jeffrey-kemp: ten poniżej skrypt NIE zapisze danych, które są już obecne w tabeli, którą zamierzasz upuścić. Ze względu na ryzyko utraty danych w naszej firmie można zmieniać tylko istniejące tabele w środowisku produkcyjnym, a nie wolno usuwać tabel. Korzystając z wyciągu z tabeli drop table, prędzej czy później dostaniesz policję firmy stojącą przy Twoim biurku.

--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
źródło
Czy musisz być spójny z A_TABLE_EXAMPLE i A_TABLE_X?
Jonathan Leffler
0

Zrobiłbym coś takiego

  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
źródło
-4

Jeśli to jest dla MS SQL .. Poniższy kod będzie zawsze działał bez względu na to, czy tabela już istnieje, czy nie.

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
źródło
1
Przepraszam, ale to jest Wyrocznia. :-)
Jason Baker
czy komentarz „// czy w tabeli są dane” jest poprawny?
Jeffrey Kemp
przepraszam, trochę lepiej, parametr object_id sprawdza, czy tabela istnieje w bazie danych. Powinien powiedzieć // czy tabela została już utworzona w db
JuniorFlip