Лучший и самый эффективный способ - перехватить исключение «таблица не найдена»: это позволяет избежать ненужных проверок, если таблица существует дважды; и не страдает от проблемы, заключающейся в том, что если DROP завершается неудачей по какой-либо другой причине (которая может быть важной), исключение по-прежнему передается вызывающей стороне:
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE ' || table_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
ADDENDUM
Для справки вот эквивалентные блоки для других типов объектов:
Последовательность
BEGIN
EXECUTE IMMEDIATE 'DROP SEQUENCE ' || sequence_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -2289 THEN
RAISE;
END IF;
END;
Посмотреть
BEGIN
EXECUTE IMMEDIATE 'DROP VIEW ' || view_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
Курок
BEGIN
EXECUTE IMMEDIATE 'DROP TRIGGER ' || trigger_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4080 THEN
RAISE;
END IF;
END;
Индекс
BEGIN
EXECUTE IMMEDIATE 'DROP INDEX ' || index_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -1418 THEN
RAISE;
END IF;
END;
колонка
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;
Ссылка на базу данных
BEGIN
EXECUTE IMMEDIATE 'DROP DATABASE LINK ' || dblink_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -2024 THEN
RAISE;
END IF;
END;
Материализованный вид
BEGIN
EXECUTE IMMEDIATE 'DROP MATERIALIZED VIEW ' || mview_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -12003 THEN
RAISE;
END IF;
END;
Тип
BEGIN
EXECUTE IMMEDIATE 'DROP TYPE ' || type_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
скованность
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;
Планировщик заданий
BEGIN
DBMS_SCHEDULER.drop_job(job_name);
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -27475 THEN
RAISE;
END IF;
END;
Пользователь / Схема
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;
пакет
BEGIN
EXECUTE IMMEDIATE 'DROP PACKAGE ' || package_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Процедура
BEGIN
EXECUTE IMMEDIATE 'DROP PROCEDURE ' || procedure_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
функция
BEGIN
EXECUTE IMMEDIATE 'DROP FUNCTION ' || function_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Табличное
BEGIN
EXECUTE IMMEDIATE 'DROP TABLESPACE' || tablespace_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -959 THEN
RAISE;
END IF;
END;
Синоним
BEGIN
EXECUTE IMMEDIATE 'DROP SYNONYM ' || synonym_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -1434 THEN
RAISE;
END IF;
END;
EXECUTE IMMEDIATE 'DROP TABLE mytable';
предложений (по одному для каждой таблицы в сценарии), должен ли я поместить один обработчик исключений для каждого или достаточно, чтобы обернуть все предложения в одинBEGIN ... EXCEPTION ... END;
блок?IF OBJECT_ID('TblName') IS NOT NULL DROP TABLE TblName
. Кажется, многословность языка SQL пропорциональна цене.Это для проверки, существует ли таблица в текущей схеме. Для проверки того, существует ли данная таблица в другой схеме, вам нужно использовать
all_tables
вместо нееuser_tables
и добавить условиеall_tables.owner = upper('schema_name')
источник
Я искал то же самое, но я закончил тем, что написал процедуру, чтобы выручить меня:
Надеюсь это поможет
источник
Я просто хотел опубликовать полный код, который создаст таблицу и удалит ее, если она уже существует, используя код Джеффри (спасибо ему, а не мне!).
источник
С SQL * PLUS вы также можете использовать команду WHENEVER SQLERROR:
С
CONTINUE NONE
ошибкой сообщается, но скрипт продолжится. ПриEXIT SQL.SQLCODE
этом скрипт будет прерван в случае ошибки.см. также: КОГДА-ЛИБО SQLERROR Docs
источник
В оракуле нет DROP TABLE IF EXISTS, вам нужно будет выполнить оператор select.
попробуйте это (я не разбираюсь в синтаксисе оракула, поэтому, если мои переменные ify, пожалуйста, прости меня):
источник
Я предпочитаю следующее экономическое решение
источник
Другой метод - определить исключение, а затем только перехватить это исключение, позволяя распространяться всем остальным.
источник
Одним из способов является использование DBMS_ASSERT.SQL_OBJECT_NAME :
DBFiddle Demo
источник
К сожалению, нет, нет такой вещи, как отбрасывание, если существует, или СОЗДАТЬ, ЕСЛИ НЕ СУЩЕСТВУЕТ
Вы можете написать сценарий plsql, чтобы включить туда логику.
http://download.oracle.com/docs/cd/B12037_01/server.101/b10759/statements_9003.htm
Я не сильно разбираюсь в синтаксисе Oracle, но я думаю, что сценарий @ Erich будет примерно таким.
источник
Вы всегда можете поймать ошибку самостоятельно.
Чрезмерно злоупотреблять этим считается плохой практикой, подобно пустым catch () в других языках.
С уважением
К
источник
Я предпочитаю указывать таблицу и владельца схемы.
Также следите за чувствительностью к регистру. (см. «верхний» пункт ниже).
Я добавил несколько различных объектов, чтобы показать, что их можно использовать в других местах, кроме ТАБЛИЦ.
.............
И ТАБЛИЦА пример:
источник
// Делая этот код, проверяет, существует ли таблица, и позже она создает таблицу max. это просто работает в одной компиляции
источник
И если вы хотите сделать его повторно вводимым и минимизировать циклы удаления / создания, вы можете кэшировать DDL с помощью dbms_metadata.get_ddl и заново создавать все, используя такую конструкцию, как эта:
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;
это всего лишь пример, внутри должен быть цикл с Тип DDL, имя и владелец являются переменными.источник
Такой блок может быть полезен для вас.
источник