validar usuario una tabla sobre permisos multiple existe esquema dinamico dar columns borrar 10g sql oracle sql-drop

sql - usuario - pivot oracle columns to rows



Oracle: si la tabla existe (15)

Con SQL * PLUS también puede usar el comando WHENEVER SQLERROR:

WHENEVER SQLERROR CONTINUE NONE DROP TABLE TABLE_NAME; WHENEVER SQLERROR EXIT SQL.SQLCODE DROP TABLE TABLE_NAME;

Con CONTINUE NONE se informa un error, pero el script continuará. Con EXIT SQL.SQLCODE el script terminará en el caso de un error.

Véase también: WHEREVER SQLERROR Docs

Estoy escribiendo algunos scripts de migración para una base de datos Oracle, y esperaba que Oracle tuviera algo similar a la estructura IF EXISTS MySQL.

Específicamente, cada vez que quiero colocar una tabla en MySQL, hago algo como

DROP TABLE IF EXISTS `table_name`;

De esta manera, si la tabla no existe, el DROP no produce un error y la secuencia de comandos puede continuar.

¿Tiene Oracle un mecanismo similar? Me doy cuenta de que podría usar la siguiente consulta para verificar si existe una tabla o no

SELECT * FROM dba_tables where table_name = ''table_name'';

pero la sintaxis para unir eso junto con un DROP me está escapando.


He estado buscando lo mismo pero terminé escribiendo un procedimiento para ayudarme:

CREATE OR REPLACE PROCEDURE DelObject(ObjName varchar2,ObjType varchar2) IS v_counter number := 0; begin if ObjType = ''TABLE'' then select count(*) into v_counter from user_tables where table_name = upper(ObjName); if v_counter > 0 then execute immediate ''drop table '' || ObjName || '' cascade constraints''; end if; end if; if ObjType = ''PROCEDURE'' then select count(*) into v_counter from User_Objects where object_type = ''PROCEDURE'' and OBJECT_NAME = upper(ObjName); if v_counter > 0 then execute immediate ''DROP PROCEDURE '' || ObjName; end if; end if; if ObjType = ''FUNCTION'' then select count(*) into v_counter from User_Objects where object_type = ''FUNCTION'' and OBJECT_NAME = upper(ObjName); if v_counter > 0 then execute immediate ''DROP FUNCTION '' || ObjName; end if; end if; if ObjType = ''TRIGGER'' then select count(*) into v_counter from User_Triggers where TRIGGER_NAME = upper(ObjName); if v_counter > 0 then execute immediate ''DROP TRIGGER '' || ObjName; end if; end if; if ObjType = ''VIEW'' then select count(*) into v_counter from User_Views where VIEW_NAME = upper(ObjName); if v_counter > 0 then execute immediate ''DROP VIEW '' || ObjName; end if; end if; if ObjType = ''SEQUENCE'' then select count(*) into v_counter from user_sequences where sequence_name = upper(ObjName); if v_counter > 0 then execute immediate ''DROP SEQUENCE '' || ObjName; end if; end if; end;

Espero que esto ayude


La forma mejor y más eficiente es capturar la excepción "tabla no encontrada": esto evita la sobrecarga de verificar si la tabla existe dos veces; y no tiene el problema de que si el DROP falla por alguna otra razón (que podría ser importante), la excepción aún se presenta al llamante:

BEGIN EXECUTE IMMEDIATE ''DROP TABLE '' || table_name; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;

ADDENDUM 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 THEN RAISE; END IF; END;

Enlace a la 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 THEN RAISE; END IF; END;

Trabajo programador

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;


Lamentablemente no, no hay tal cosa como soltar si existe, o CREAR SI NO EXISTE

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

declare cant integer begin select into cant count(*) from dba_tables where table_name=''Table_name''; if count>0 then BEGIN DROP TABLE tableName; END IF; END;


No hay un ''DROP TABLE IF EXISTS'' 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ónenme):

declare @count int select @count=count(*) from all_tables where table_name=''Table_name''; if @count>0 BEGIN DROP TABLE tableName; END


Otro método es definir una excepción y luego capturar esa excepción, permitiendo que todos los demás se propaguen.

Declare eTableDoesNotExist Exception; PRAGMA EXCEPTION_INIT(eTableDoesNotExist, -942); Begin EXECUTE IMMEDIATE (''DROP TABLE myschema.mytable''); Exception When eTableDoesNotExist Then DBMS_Output.Put_Line(''Table already does not exist.''); End;


Prefiero especificar la tabla y el propietario del esquema.

Cuidado con la sensibilidad de los casos también. (ver la cláusula "superior" a continuación).

Tiré un par de objetos diferentes para mostrar que se pueden usar en lugares además de TABLAS.

.............

declare v_counter int; begin select count(*) into v_counter from dba_users where upper(username)=upper(''UserSchema01''); if v_counter > 0 then execute immediate ''DROP USER UserSchema01 CASCADE''; end if; end; / CREATE USER UserSchema01 IDENTIFIED BY pa$$word DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp QUOTA UNLIMITED ON users; grant create session to UserSchema01;

Y un ejemplo de TABLA:

declare v_counter int; begin select count(*) into v_counter from all_tables where upper(TABLE_NAME)=upper(''ORDERS'') and upper(OWNER)=upper(''UserSchema01''); if v_counter > 0 then execute immediate ''DROP TABLE UserSchema01.ORDERS''; end if; end; /


Prefiero seguir la solución económica

BEGIN FOR i IN (SELECT NULL FROM USER_OBJECTS WHERE OBJECT_TYPE = ''TABLE'' AND OBJECT_NAME = ''TABLE_NAME'') LOOP EXECUTE IMMEDIATE ''DROP TABLE TABLE_NAME''; END LOOP; END;


Siempre podrías atrapar el error tú mismo.

begin execute immediate ''drop table mytable''; exception when others then null; end;

Se considera una mala práctica abusar de esto, similar a las capturas vacías en otros idiomas.

Saludos
K


Un bloque como este podría ser útil para ti.

DECLARE table_exist INT; BEGIN SELECT Count(*) INTO table_exist FROM dba_tables WHERE owner = ''SCHEMA_NAME'' AND table_name = ''EMPLOYEE_TABLE''; IF table_exist = 1 THEN EXECUTE IMMEDIATE ''drop table EMPLOYEE_TABLE''; END IF; END;


Una forma es usar DBMS_ASSERT.SQL_OBJECT_NAME :

Esta función verifica que la cadena del parámetro de entrada es un identificador de SQL calificado de un objeto SQL existente.

DECLARE V_OBJECT_NAME VARCHAR2(30); BEGIN BEGIN V_OBJECT_NAME := DBMS_ASSERT.SQL_OBJECT_NAME(''tab1''); EXECUTE IMMEDIATE ''DROP TABLE tab1''; EXCEPTION WHEN OTHERS THEN NULL; END; END; /

Demostración de DBFiddle


Y si desea que sea reenterable y minimice los ciclos de soltar / crear, puede almacenar el DDL utilizando dbms_metadata.get_ddl y volver a crear todo utilizando 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; 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 dentro con el tipo de DDL, el nombre y el propietario son variables.


solo quería publicar un código completo que cree una tabla y la suelte si ya existe usando el código de Jeffrey (¡felicitaciones a él, no a mí!).

BEGIN BEGIN EXECUTE IMMEDIATE ''DROP TABLE tablename''; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; EXECUTE IMMEDIATE ''CREATE TABLE tablename AS SELECT * FROM sourcetable WHERE 1=0''; END;


BEGIN EXECUTE IMMEDIATE ''DROP TABLE "IMS"."MAX" ''; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; EXECUTE IMMEDIATE '' CREATE TABLE "IMS"."MAX" ( "ID" NUMBER NOT NULL ENABLE, "NAME" VARCHAR2(20 BYTE), CONSTRAINT "MAX_PK" PRIMARY KEY ("ID") USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "SYSAUX" ENABLE ) SEGMENT CREATION IMMEDIATE PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "SYSAUX" ''; END;

// Al hacer este código, comprueba si la tabla existe y luego crea la tabla max. Esto simplemente funciona en una sola compilación.


declare c int; begin select count(*) into c from user_tables where table_name = upper(''table_name''); if c = 1 then execute immediate ''drop table table_name''; end if; end;

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 all_tables lugar de user_tables y agregar la condición all_tables.owner = upper(''schema_name'')