A maneira melhor e mais eficiente é capturar a exceção "tabela não encontrada": isso evita a sobrecarga de verificar se a tabela existe duas vezes; e não sofre com o problema de que, se o DROP falhar por algum outro motivo (isso pode ser importante), a exceção ainda será gerada para o chamador:
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE ' || table_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
ADENDO
Para referência, aqui estão os blocos equivalentes para outros tipos de objetos:
Seqüência
BEGIN
EXECUTE IMMEDIATE 'DROP SEQUENCE ' || sequence_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -2289 THEN
RAISE;
END IF;
END;
Visão
BEGIN
EXECUTE IMMEDIATE 'DROP VIEW ' || view_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
Desencadear
BEGIN
EXECUTE IMMEDIATE 'DROP TRIGGER ' || trigger_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4080 THEN
RAISE;
END IF;
END;
Índice
BEGIN
EXECUTE IMMEDIATE 'DROP INDEX ' || index_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -1418 THEN
RAISE;
END IF;
END;
Coluna
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 banco de dados
BEGIN
EXECUTE IMMEDIATE 'DROP DATABASE LINK ' || dblink_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -2024 THEN
RAISE;
END IF;
END;
Visão materializada
BEGIN
EXECUTE IMMEDIATE 'DROP MATERIALIZED VIEW ' || mview_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -12003 THEN
RAISE;
END IF;
END;
Tipo
BEGIN
EXECUTE IMMEDIATE 'DROP TYPE ' || type_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Restrição
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;
Trabalho do Agendador
BEGIN
DBMS_SCHEDULER.drop_job(job_name);
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -27475 THEN
RAISE;
END IF;
END;
Usuário / Esquema
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;
Pacote
BEGIN
EXECUTE IMMEDIATE 'DROP PACKAGE ' || package_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Procedimento
BEGIN
EXECUTE IMMEDIATE 'DROP PROCEDURE ' || procedure_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Função
BEGIN
EXECUTE IMMEDIATE 'DROP FUNCTION ' || function_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Tablespace
BEGIN
EXECUTE IMMEDIATE 'DROP TABLESPACE' || tablespace_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -959 THEN
RAISE;
END IF;
END;
Sinônimo
BEGIN
EXECUTE IMMEDIATE 'DROP SYNONYM ' || synonym_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -1434 THEN
RAISE;
END IF;
END;
EXECUTE IMMEDIATE 'DROP TABLE mytable';
frases (uma para cada tabela no script), preciso colocar um manipulador de exceções para cada uma ou será suficiente para agrupar todas as senteces em umBEGIN ... EXCEPTION ... END;
bloco?IF OBJECT_ID('TblName') IS NOT NULL DROP TABLE TblName
. Parece que a verbosidade de uma linguagem SQL é proporcional ao preço.Isso é para verificar se existe uma tabela no esquema atual. Para verificar se uma determinada tabela já existe em um esquema diferente, você teria que usar em
all_tables
vez deuser_tables
e adicionar a condiçãoall_tables.owner = upper('schema_name')
fonte
Eu estava procurando o mesmo, mas acabei escrevendo um procedimento para me ajudar:
Espero que isto ajude
fonte
só queria postar um código completo que criará uma tabela e a largará, se ela já existir, usando o código de Jeffrey (parabéns a ele, não a mim!).
fonte
Com o SQL * PLUS, você também pode usar o comando WHENEVER SQLERROR:
Com
CONTINUE NONE
um erro é relatado, mas o script continuará. ComEXIT SQL.SQLCODE
o script será encerrado no caso de um erro.veja também: WHENEVER SQLERROR Docs
fonte
Não há 'DROP TABLE IF EXISTS' no oracle, você precisaria fazer a instrução select.
tente isso (não gosto da sintaxe do oracle, portanto, se minhas variáveis forem duvidosas, por favor, me perdoe):
fonte
Eu prefiro seguir solução econômica
fonte
Outro método é definir uma exceção e capturar apenas essa exceção, permitindo a propagação de todas as outras.
fonte
Uma maneira é usar DBMS_ASSERT.SQL_OBJECT_NAME :
DBFiddle Demo
fonte
Infelizmente não, não existe drop, se existir, ou CREATE SE NÃO EXISTIR
Você pode escrever um script plsql para incluir a lógica lá.
http://download.oracle.com/docs/cd/B12037_01/server.101/b10759/statements_9003.htm
Não gosto muito do Oracle Syntax, mas acho que o script do @ Erich seria algo parecido com isto.
fonte
Você sempre pode pegar o erro sozinho.
É considerado uma prática inadequada usar em excesso isso, semelhante a catch () vazio em outros idiomas.
Atenciosamente
K
fonte
Prefiro especificar a tabela e o proprietário do esquema.
Cuidado também com a distinção entre maiúsculas e minúsculas. (veja a cláusula "superior" abaixo).
Joguei alguns objetos diferentes para mostrar que podem ser usados em outros lugares além de TABLEs.
.............
E um exemplo de TABLE:
fonte
// Fazendo esse código, verifica se a tabela existe e depois cria a tabela no máximo. isso simplesmente funciona em compilação única
fonte
E se você quiser torná-lo re-digitado e minimizar os ciclos de descartar / criar, poderá armazenar em cache o DDL usando dbms_metadata.get_ddl e recriar tudo usando uma construção como esta:
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;
Esta é apenas uma amostra, deve haver um loop interno com Tipo DDL, nome e proprietário sendo variáveis.fonte
Um bloco como esse pode ser útil para você.
fonte