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.

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.


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

23

W Oracle nie ma tworzenia ani zastępowania tabeli.

Musisz:

DROP TABLE foo;
UTWÓRZ TABELĘ foo (....);

10

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


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;


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;

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

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.


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.


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


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;

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)) ';

-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 (...

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.