Najlepszym i najbardziej wydajnym sposobem jest wychwycenie wyjątku „nie znaleziono tabeli”: pozwala to uniknąć narzutu sprawdzania, czy tabela istnieje dwukrotnie; i nie ma problemu z tym, że jeśli DROP zawiedzie z innego powodu (może to być ważne) wyjątek jest nadal zgłaszany do osoby dzwoniącej:
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE ' || table_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
DODATEK
W celach informacyjnych znajdują się równoważne bloki dla innych typów obiektów:
Sekwencja
BEGIN
EXECUTE IMMEDIATE 'DROP SEQUENCE ' || sequence_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -2289 THEN
RAISE;
END IF;
END;
Widok
BEGIN
EXECUTE IMMEDIATE 'DROP VIEW ' || view_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
Wyzwalacz
BEGIN
EXECUTE IMMEDIATE 'DROP TRIGGER ' || trigger_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4080 THEN
RAISE;
END IF;
END;
Indeks
BEGIN
EXECUTE IMMEDIATE 'DROP INDEX ' || index_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -1418 THEN
RAISE;
END IF;
END;
Kolumna
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;
Link do bazy danych
BEGIN
EXECUTE IMMEDIATE 'DROP DATABASE LINK ' || dblink_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -2024 THEN
RAISE;
END IF;
END;
Widok zmaterializowany
BEGIN
EXECUTE IMMEDIATE 'DROP MATERIALIZED VIEW ' || mview_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -12003 THEN
RAISE;
END IF;
END;
Rodzaj
BEGIN
EXECUTE IMMEDIATE 'DROP TYPE ' || type_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Przymus
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;
Zadanie harmonogramu
BEGIN
DBMS_SCHEDULER.drop_job(job_name);
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -27475 THEN
RAISE;
END IF;
END;
Użytkownik / schemat
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;
Pakiet
BEGIN
EXECUTE IMMEDIATE 'DROP PACKAGE ' || package_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Procedura
BEGIN
EXECUTE IMMEDIATE 'DROP PROCEDURE ' || procedure_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Funkcjonować
BEGIN
EXECUTE IMMEDIATE 'DROP FUNCTION ' || function_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Przestrzeń tabel
BEGIN
EXECUTE IMMEDIATE 'DROP TABLESPACE' || tablespace_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -959 THEN
RAISE;
END IF;
END;
Synonim
BEGIN
EXECUTE IMMEDIATE 'DROP SYNONYM ' || synonym_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -1434 THEN
RAISE;
END IF;
END;
EXECUTE IMMEDIATE 'DROP TABLE mytable';
zdań (po jednym dla każdej tabeli w skrypcie), czy muszę wstawić jeden moduł obsługi wyjątków dla każdego z nich, czy wystarczy, aby wszystkie sentecy były zawinięte w jednymBEGIN ... EXCEPTION ... END;
bloku?IF OBJECT_ID('TblName') IS NOT NULL DROP TABLE TblName
. Wydaje się, że gadatliwość języka SQL jest proporcjonalna do ceny.Służy to do sprawdzenia, czy istnieje tabela w bieżącym schemacie. Aby sprawdzić, czy dana tabela już istnieje w innym schemacie, musisz użyć
all_tables
zamiastuser_tables
i dodać warunekall_tables.owner = upper('schema_name')
źródło
Szukałem tego samego, ale ostatecznie napisałem procedurę, która mi pomoże:
Mam nadzieję że to pomoże
źródło
chciałem tylko napisać pełny kod, który utworzy tabelę i upuści ją, jeśli już istnieje przy użyciu kodu Jeffreya (uznanie dla niego, nie dla mnie!).
źródło
Za pomocą SQL * PLUS można także użyć polecenia WHENEVER SQLERROR:
Z
CONTINUE NONE
błędem jest zgłaszany, ale skrypt będzie kontynuowany. ZeEXIT SQL.SQLCODE
skryptu zostanie rozwiązana w przypadku wystąpienia błędu.zobacz także: KIEDYKOLWIEK Dokumenty SQLERROR
źródło
W wyroczni nie ma „STOŁU UPADKU, JEŚLI ISTNIEJE”, należy wykonać instrukcję select.
spróbuj tego (nie używam składni Oracle, więc jeśli moje zmienne są ify, proszę wybacz mi):
źródło
Wolę następujące rozwiązanie ekonomiczne
źródło
Inną metodą jest zdefiniowanie wyjątku, a następnie tylko złapanie tego wyjątku, umożliwiając wszystkim innym propagację.
źródło
Jednym ze sposobów jest użycie DBMS_ASSERT.SQL_OBJECT_NAME :
DBFiddle Demo
źródło
Niestety nie, nie ma czegoś takiego jak upuszczenie, jeśli istnieje, lub UTWÓRZ, JEŚLI NIE ISTNIEJE
Możesz napisać skrypt plsql, aby uwzględnić tam logikę.
http://download.oracle.com/docs/cd/B12037_01/server.101/b10759/statements_9003.htm
Nie przepadam za składnią Oracle, ale myślę, że skrypt @ Ericha byłby mniej więcej taki.
źródło
Zawsze możesz sam złapać błąd.
Nadużywanie tego, podobnie jak puste catch () w innych językach, jest uważane za złą praktykę.
Pozdrawiam
K.
źródło
Wolę określić tabelę i właściciela schematu.
Uważaj również na rozróżnianie wielkości liter. (patrz „górna” klauzula poniżej).
Wrzuciłem kilka różnych przedmiotów, aby pokazać, że można ich używać w innych miejscach niż TABELE.
.............
I przykład TABELI:
źródło
// Wykonując ten kod, sprawdza, czy tabela istnieje, a później tworzy tabelę max. to po prostu działa w jednej kompilacji
źródło
A jeśli chcesz, aby był on ponownie dostępny i minimalizował cykle upuszczania / tworzenia, możesz buforować DDL za pomocą dbms_metadata.get_ddl i odtworzyć wszystko za pomocą takiej konstrukcji:
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;
To tylko próbka, wewnątrz powinna być pętla z Typ DDL, nazwa i właściciel są zmiennymi.źródło
Taki blok może ci się przydać.
źródło