La forma mejor y más eficiente es detectar la excepción "tabla no encontrada": esto evita la sobrecarga de verificar si la tabla existe dos veces; y no sufre el problema de que si el DROP falla por alguna otra razón (que podría ser importante) la excepción aún se eleva a la persona que llama:
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE ' || table_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
ADENDA
Para referencia, aquí están los bloques equivalentes para otros tipos de objetos:
Secuencia
BEGIN
EXECUTE IMMEDIATE 'DROP SEQUENCE ' || sequence_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -2289 THEN
RAISE;
END IF;
END;
Ver
BEGIN
EXECUTE IMMEDIATE 'DROP VIEW ' || view_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
Desencadenar
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;
Columna
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;
Enlace de base de datos
BEGIN
EXECUTE IMMEDIATE 'DROP DATABASE LINK ' || dblink_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -2024 THEN
RAISE;
END IF;
END;
Vista 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;
Restricción
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;
Programador de trabajo
BEGIN
DBMS_SCHEDULER.drop_job(job_name);
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -27475 THEN
RAISE;
END IF;
END;
Usuario / 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;
Paquete
BEGIN
EXECUTE IMMEDIATE 'DROP PACKAGE ' || package_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Procedimiento
BEGIN
EXECUTE IMMEDIATE 'DROP PROCEDURE ' || procedure_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Función
BEGIN
EXECUTE IMMEDIATE 'DROP FUNCTION ' || function_name;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -4043 THEN
RAISE;
END IF;
END;
Espacio de tabla
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';
oraciones (una para cada tabla en el guión), ¿tengo que poner un controlador de excepción para cada una o es suficiente para envolver todas las oraciones en unBEGIN ... EXCEPTION ... END;
bloque?IF OBJECT_ID('TblName') IS NOT NULL DROP TABLE TblName
. Parece que la verbosidad de un lenguaje SQL es proporcional al precio.Eso es para verificar si existe una tabla en el esquema actual. Para verificar si una tabla dada ya existe en un esquema diferente, tendría que usar en
all_tables
lugar deuser_tables
y agregar la condiciónall_tables.owner = upper('schema_name')
fuente
He estado buscando lo mismo pero terminé escribiendo un procedimiento para ayudarme:
Espero que esto ayude
fuente
solo quería publicar un código completo que crearía una tabla y la soltaría si ya existe usando el código de Jeffrey (¡felicitaciones a él, no a mí!).
fuente
Con SQL * PLUS también puede usar el comando WHENEVER SQLERROR:
Con
CONTINUE NONE
un error se informa, pero el script continuará. ConEXIT SQL.SQLCODE
el script se terminará en caso de error.ver también: CUANDO SQLERROR Docs
fuente
No hay 'TABLA DE GOTAS SI EXISTE' en Oracle, tendría que hacer la declaración de selección.
intente esto (no estoy al tanto de la sintaxis de Oracle, así que si mis variables son dudosas, por favor perdóneme):
fuente
Prefiero seguir la solución económica
fuente
Otro método es definir una excepción y luego capturar esa excepción dejando que todos los demás se propaguen.
fuente
Una forma es usar DBMS_ASSERT.SQL_OBJECT_NAME :
DBFiddle Demo
fuente
Lamentablemente no, no existe tal cosa como soltar si existe, o CREAR SI NO EXISTE
Podría escribir un script plsql para incluir la lógica allí.
http://download.oracle.com/docs/cd/B12037_01/server.101/b10759/statements_9003.htm
No me gusta mucho la sintaxis de Oracle, pero creo que el script de @ Erich sería algo como esto.
fuente
Siempre puede detectar el error usted mismo.
Se considera una mala práctica abusar de esto, similar a la captura vacía () en otros idiomas.
Saludos
K
fuente
Prefiero especificar la tabla y el propietario del esquema.
Tenga cuidado con la mayúsculas y minúsculas también. (ver cláusula "superior" a continuación).
Lancé un par de objetos diferentes para mostrar que se puede usar en lugares además de TABLEs.
.............
Y un ejemplo de TABLA:
fuente
// Al hacer este código, verifica si la tabla existe y luego crea la tabla max. esto simplemente funciona en una sola compilación
fuente
Y si desea que sea reingresable y minimizar los ciclos de caída / creación, puede almacenar en caché el DDL usando dbms_metadata.get_ddl y volver a crear todo usando una construcción 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;
Esto es solo una muestra, debe haber un bucle adentro con Tipo DDL, nombre y propietario siendo variables.fuente
Un bloque como este podría serle útil.
fuente