TABLAS EXTERNAS Indice 1.- Visión General 2.- Aplicaciones y beneficios de las Tablas Externas 3.- Historia y Evolución (9i, 10g, 11gR2) 4.- Sintaxis y uso 4.1 Creación y modificación 4.2 Uso del Driver ORACLE_LOADER 4.3 Uso del Driver ORACLE_DATAPUMP 4.4 Definir tablas externas con SQL*Loader 4.5 Uso con un preprocesador 4.6 Privilegios 4.7 Vistas del Diccionario. 5.- Transformación de datos PIPELINED, usando tablas externas 1.- Visión General Las tablas externas son tablas cuyos datos se almacenan fuera de la base de datos en ficheros planos o binarios. Complementan la funcionalidad de carga de datos de SQL*Loader, o de transmisión de datos/carga de DATAPUMP. Son similares a las tablas SQL normales, pero no residen en la base de datos, por lo tanto su organización es externa. Se pueden consultar directamente y también en paralelo usando SQL. De hecho, la tabla externa actúa como una vista. Los metadatos de la tabla externa, son creados en el diccionario de la base de datos usando la sentencia CREATE TABLE … ORGANIZATION EXTERNAL. No se permiten operaciones de manipulación de datos en la misma (DML), ni tampoco creación de índices sobre sus datos. Los datos existen fuera de la base de datos. Una vez que la definición de la tabla externa (metadatos) exista en el diccionario, puede ser seleccionada, incluso en paralelo, produciéndose entonces el proceso de extracción de las fuentes externas, especificadas en los metadatos de la misma. Se puede realizar una operación de tipo CREATE TABLE tabla_convencional … AS SELECT FROM tabla_externa , permitiendo una variación del proceso de extracción y carga. También podemos extraer datos de tablas convencionales y rellenar una tabla externa de tipo DATAPUMP (unload), mover el/los ficheros donde estos datos externos han sido creados y crear los metadatos de esa tabla externa en otra base de datos diferente, facilitando el proceso de transmisión/carga de datos entre bases de datos. Para poder usarlas, es preciso conocer el formato de los ficheros de texto y de los registros que la componen, si el driver que utilizamos es ORACLE_LOADER. Si utilizamos ficheros binarios, es preciso conocer ORACLE_DATAPUMP. 2.- Aplicaciones y beneficios de las Tablas Externas Las tablas externas, nos permiten usar datos externos como si fueran una “tabla virtual”, y por lo tanto pueden ser consultadas o unidas a tablas normales, sin necesidad de cargar sus datos en tablas convencionales o tablas intermedias. Es decir, cada vez que son accedidas, la información se almacena en memoria de usuario (PGA). Veamos algunas características: - El paralelismo transparente, no está limitado por el número de ficheros que lee la tabla externa. - No es preciso almacenar los datos en áreas intermedias o de “stage” para las aplicaciones de tipo ETL en los datawarehouse. - Son muy útiles, cuando una fuente externa, tiene que ser unida o “joined” con objetos de la base de datos y luego transformada. - También son útiles cuando el volumen de datos es grande, y no se consultan permanentemente. - Complementa las funcionalidades de SQL*Loader en el paralelismo transparente y en las capacidades de inserción directa. 3.- Historia y Evolución (9i, 10g, 11gR2) La primera versión de las tablas externas, aparece en los años 2001 y 2002, con Oracle Database Release 9i (r1 y r2). Inicialmente sólo permitía el uso del driver ORACLE_LOADER, y el tipo de ficheros que se podían leer, eran sólo de texto (los mismos que SQL*Loader). En la versión 9, con el driver ORACLE_LOADER, era preciso tener privilegios de lectura (READ) sobre un objeto de tipo DIRECTORY, donde residían los ficheros de texto con los datos. La segunda versión, aparece en torno al año 2006, con Oracle Database Release 10g (r2). Es en este momento cuando se introduce el uso del driver ORACLE_DATAPUMP, que permite crear un fichero binario, con datos procedentes de todo tipo de tablas, para la descarga/transporte a otras bases de datos. También se permite la posibilidad de trabajar con la cláusula PROJECT COLUMN REFERENCED o PROJECT COLUMN ALL, que determina cómo el driver valida los datos procedentes de los ficheros donde residen las fuentes de datos. En la versión 10, se mantienen los mismos privilegios, pero si queremos rellenar una tabla externa sobre un fichero binario que resida en un objeto DIRECTORY, es preciso tener privilegios de escritura (WRITE) sobre el objeto DIRECTORY. La tercera versión se produce en a finales del 2009, con la aparición de Oracle Database 11g R2. Esta versión incluye la posibilidad de invocar a un preprocesador (programa), que trate/manipule los ficheros externos, antes de ser leídos. En concreto, se puede invocar a gunzip, a un fichero .sh (shell) o .bat (lotes). Es decir, los datos a leer pueden estar comprimidos, y en el momento de ser accedidos, se invoca al preprocesador que los descomprime y transfiere. En esta versión, es necesario un permiso especial, sobre el DIRECTORY donde reside el preprocesador: EXECUTE. 4.- Sintaxis y uso 4.1 Creación y modificación CREATE: Para crear una tabla externa, utilizamos el comando SQL CREATE TABLE … ORGANIZATION EXTERNAL, con los siguientes atributos: - TYPE: Tipo de tabla externa. Puede ser ORACLE_LOADER (defecto), o ORACLE_DATAPUMP - DEFAULT DIRECTORY: Directorio por defecto donde residen los ficheros que son leídos/escritos por las tablas externas. - ACCESS PARAMETERS: Describen las fuentes de datos externas que implementan el tipo de tabla externa específico. - LOCATION: Nombres de los ficheros donde residen los datos externos. ALTER: Para modificar una tabla externa utilizamos el comando SQL ALTER TABLE, como en las tablas regulares. ALTER TABLE Descripción Examplo REJECT LIMIT Cambia el límite de registros rechazados o máximo de errores permitidos ALTER TABLE admin_ext_employees REJECT LIMIT 100; PROJECT COLUMN Determina cómo el access driver valida las filas en las consultas que se realicen contra la tabla externa: • PROJECT COLUMN REFERENCED: el access driver procesa solo la lista de columnas que están en la SELECT de la consulta. Este valor puede dar una visión inconsistente de las filas, cuando se consultan otras columnas de la misma tabla externa. • PROJECT COLUMN ALL: el access driver procesa TODAS las columnas definidas en la tabla externa (aunque la consulta sólo seleccione una). Éste valor siempre proporciona una visión consistente de los datos cuando se consultan tablas externas. Es el valor por defecto. ALTER TABLE admin_ext_employees PROJECT COLUMN REFERENCED; DEFAULT DIRECTORY Cambia la especificación del directorio por defecto. ALTER TABLE admin_ext_employees DEFAULT DIRECTORY admin_dat2_dir; ACCESS PARAMETERS Permite cambiar los parámetros de acceso a la tabla externa, sin tener que recrearla. ALTER TABLE admin_ext_employees ACCESS PARAMETERS (FIELDS TERMINATED BY ';'); LOCATION Permite cambiar los nombres de las Fuentes de datos (ficheros externos), sin tener que recrearla. ALTER TABLE admin_ext_employees LOCATION ('empxt3.txt', ALTER TABLE admin_ext_employees PROJECT COLUMN ALL; 'empxt4.txt'); PARALLEL Igual que en tablas regulares. Cambia el grado de paralelismo. ADD COLUMN Igual que en tablas regulares. Añade una columna a la tabla externa. No se permiten columnas virtuales. MODIFY COLUMN Igual que en tablas regulares. Modifica una columna de la tabla externa. No se permiten columnas virtuales. SET UNUSED Se transforma de forma transparente en una sentencia ALTER TABLE DROP COLUMN. Como las tablas externas consisten solo en metadatos en ALTER TABLE Descripción Examplo la base de datos, el comando DROP COLUMN lo realiza de forma equivalente al SET UNUSED. DROP COLUMN Igual que en tablas regulares. Borra una columna de una tabla externa. RENAME TO Igual que en tablas regulares. renombrar una tabla externa. Permite 4.2 Uso del Driver ORACLE_LOADER Ejemplo para crear una tabla externa de tipo ORACLE_LOADER. 1.- Identificar el formato del fichero plano: El fichero empxt1.dat contiene los siguientes datos de muestra: El fichero empxt2.dat contiene los siguientes datos de muestra: 2.- Crear los objetos DIRECTORY y dar permisos: 3.- Crear la tabla externa en el esquema HR: 4.- Probamos que devuelve datos y lo creado en los directorios bad y log: 5.- Cargar los datos de la tabla externa, en una tabla convencional, en paralelo. 4.3 Uso del Driver ORACLE_DATAPUMP Este tipo de driver, permite la descarga/carga de datos sobre ficheros binarios. La tabla externa es creada con una sentencia SQL CREATE TABLE AS SELECT … y los registros devueltos por la sentencia SELECT , son escritos en un dumpfile (fichero binario) en formato DATAPUMP. En este ejemplo, vemos como rellenar la tabla externa emp_ext, utilizando un subconjunto de datos procedentes de las tablas employees y departments. En el ejemplo, los empleados que trabajan en los departamentos de Marketing y Purchasing, son descargados en el fichero emp1.exp sobre el directorio al que apunte admin_dat_dir. Comprobemos el fichero en el S.O. y consultemos la tabla externa. 4.4 Definir tablas externas con SQL*Loader Si tenemos un fichero de control (.ctl) , SQL*Loader, puede generar un fichero de log, con comandos SQL que permitan lo siguiente: - Crear metadatos para la tabla externa. - Insertar datos en la tabla destino - Borrar los metadatos de la tabla externa. Veamos un ejemplo: - Creamos una tabla convencional en el esquema hr llamada dept: - Creaamos un fichero fi carrga_dep.cctl para sim mular la caarga en deept. Veam mos su coontenido. - Invooquemos a sqlldr paara generarr el log file con los comandoss paraa generar la tabla externa y el directorioo. - Veam mos qué contiene c carga_dep p.sql Ahora podríamos ejecutar los comandos sql generados en el fichero carga_dep.sql, para crear directorio/tabla externa, cargar datos en dept procedentes de la tabla externa y finalmente borrar el directorio/tabla externa. 4.5 Uso con un Preprocesador En Oracle Database 11g R2, la sintaxis del driver ORACLE_LOADER, ha sido mejorada, para permitir la especificación de un programa que procese o trate los ficheros de datos que van a ser leídos por la tabla externa. Con esta nueva prestación, se introduce también un nuevo privilegio EXECUTE, para los objetos de tipo DIRECTORY. Al leer los datos de la tabla externa con un preprocesador, el driver ORACLE_LOADER creará un proceso que ejecute un programa que a su vez, procese los ficheros de datos de la tabla externa. Este programa ha de residir en un DIRECTORY, de ahí el privilegio EXECUTE. Sólo un usuario al que se le haya concedido el privilegio EXECUTE sobre el DIRECTORY, tendrá permisos de ejecutar programas en él. Hay algunas implicaciones de seguridad al usar preprocesadores. Como el programa que va a ser ejecutado, corre bajos las credenciales que tiene en el SO el usuario ORACLE, el preprocesador también puede acceder a cualquier fichero del SO al que puede acceder el usuario ORACLE. El DBA debe verificar que el preprocesador, no dañe ningún fichero ni del SO ni de la base de datos. Ejemplo de Preprocesamiento en LINUX La tabla sales_transactions_ext es la tabla externa. El directorio exec_file_dir es el DIRECTORY sobre el que el usuario ha de tener privilegio EXECUTE. 'gunzip' es el nombre del programa preprocesador de los datos, que a su vez puede ser invocado con diferentes opciones. El fichero 'sh_sales.dat.gz' es el fichero externo, que será descomprimido por la utilidad GNU zip. gzip (GNU zip) es una utilidad de compresión que reemplaza a la utilidad compress. Ha sido adoptada por el proyecto GNU, y es muy popular en Internet. Gzip produce ficheros con extensión .gz . gunzip puede descomprimir los ficheros creados con los comandos gzip, compress o pack. Los ficheros de log/bad, se encuentran el directorios diferentes de preprocesor. Ejem mplo de prreprocesam miento enn WINDOW WS: En el e ejemploo de Winddows, la taabla a carg gar tiene una sola coolumna dee tipo VAR RCHAR2. El fichero batch bar.bat b ess el prograama que ppreprocesaa las filass. Va a coonvertir laa cadena de d caracterres del ficchero de eentrada, “h hello wordd” en “Hello Word”. El con ntenido del d ficheero .bat es Lo que q hace el transfo formar hw w en HW.. El símbolo @ al principio o del ficheero, es evvitar que los datoss del fich hero de enntrada se muestren n por panttalla. En Window ws, los argumenttos de los ficherros .bat son referrenciados con % (%1) ( en ved v de $ ($1), quee se usa en Linux con ficheeros.sh . Vam mos a realiizar el missmo ejempplo para in nsertar reggistros en EMP PLOYEES S, pero coomprimienndo los ficheros .datt con gzip:: - Vem mos dóndee residen los l fichero os, y los coomprimim mos: - Borramos la antigua tabla admin_ext_employees. - Damos permiso EXECUTE, sobre el directorio donde residen el preprocesador gunzip. - Creamos un preprocesador llamado uncompress.sh, para invocar a gunzip -c (cuando se llama a un programa con opciones, es necesario hacerlo a través de ShellScript). El script precisa permisos de ejecución y el path absoluto a binario gunzip. $1 recibe los argumentos de LOCATION. - Creaamos de laa tabla extterna, ahorra con preeprocesadoor, en el esquuena HR. - Probbamos quee funcionaa el prepro ocesador, selecciona s ando datoss. 4.6 Privilegio P os Paraa poder acceder a tabblas exterrnas creadaas por otroos usuarioos necesitaamos los siguientes s privilegioos: - SEL LECT en laa definicióón de la taabla. - REA AD sobre el e directorrio que con ntiene el/llos ficheroos de datos. - WRIITE sobree el directoorio para los l ficheroos de tipo B BAD y LO OG. Ejem mplo: 4.7 Vistas del Diccionario. Las más importantes son las siguientes: DBA_EXTERNAL_TABLES: Contiene los atributos de todas las tablas externas del sistema. • OWNER: Dueño de la tabla externa • NAME: Nombre de la tabla externa • TYPE_OWNER: Dueño del tipo de implementación • TYPE_NAME: Nombre del tipo de implementación • DEFAULT_DIRECTORY_OWNER: Dueño del directorio por defecto de la tabla externa • DEFAULT_DIRECTORY_NAME: Nombre del directorio por defecto de la tabla externa • REJECT_LIMIT: Límite de registros rechazados DBA_EXTERNAL_LOCATIONS: Contiene la lista de ficheros planos y sus directorios correspondientes. • OWNER: Dueño de la table externa • TABLE_NAME: Nombre de la table externa • LOCATION: Nombre del fichero plano • DIRECTORY_OWNER: Dueño del directorio de la table externa • DIRECTORY_NAME: Nombre del directorio de la tabla externa DBA_DIRECTORIES también es importante, porque puede mostrar los PATHS asignados a directorios a través de variables como DATA_DIR o LOG_DIR, durante la creación de la tabla externa. 5.- Transformación de datos PIPELINED, usando tablas externas El flujo de un proceso ETL (Extracción, Transformación y Carga) en un datawarehouse, puede ser remodelado, para que el flujo de datos y su transformación se conviertan en un proceso más escalable y no interrumpido (como sucede en la transformación multistage). En este tipo de procesos, se leen, transforman y cargan los datos a través de un solo proceso. Veamos un ejemplo de este estilo, usando TABLE FUNCTIONS. Las TABLE FUNTIONS son funciones que pueden producir un conjunto de filas como output, así como leer un consulto de filas como input. Soportan ejecución de tipo PIPELINED y PARALLEL, usando PL/SQL, C o JAVA. Se usan en la clausula FROM de una sentencia SELECT. - Creamos un tipo de dato objeto para la especificación de la fila: CREATE OR REPLACE TYPE rec_sales_type IS OBJECT ( PROD_ID NUMBER, CUST_ID NUMBER, TIME_ID DATE , CHANNEL_ID number, PROMO_ID NUMBER , QUANTITY_SOLD NUMBER(3), AMOUNT_SOLD NUMBER (10,2)); - Creamos un tipo de dato tabla, con ese tipo de dato objeto. CREATE OR REPLACE TYPE table_sales_type IS TABLE OF rec_sales_type; - Creamos la TABLE FUNCTION. En el ejemplo, la función “manipulation”, consulta la tabla externa SH.SALES_DELTA_XT y transforma el resultado durante la carga. La tabla externa tiene una columna, CHANNEL_ID en formato texto. Se transforma a formato numérico, y dependiendo del valor de entrada, se asignan diferentes canales de salida (ej. 1 o 99). CREATE OR REPLACE FUNCTION manipulation RETURN table_sales_type PIPELINED IS out_rec rec_sales_type := rec_sales_type(null,null,null,null,null,null ,null); BEGIN FOR in_rec IN (SELECT * FROM sh.sales_delta_xt) LOOP out_rec.prod_id := in_rec.prod_id; out_rec.time_id := in_rec.time_id; out_rec.cust_id := in_rec.cust_id; out_rec.promo_id := in_rec.promo_id; out_rec.channel_id := CASE in_rec.channel_id WHEN 'S' THEN to_number('1') ELSE to_number('99') END; out_rec.amount_sold := in_rec.amount_sold; out_rec.quantity_sold := in_rec.quantity_sold; PIPE ROW (out_rec); END LOOP; RETURN; END; - Invocar a la TABLE FUNCTION con una sentencia SELECT. SELECT * FROM TABLE(manipulation); - Llamar a la TABLE FUNCTION desde una subconsulta: INSERT /*+ APPEND, PARALLEL(sales) */ INTO sales SELECT * FROM TABLE(manipulation); Las funciones de tipo pipelined (tubería), se pueden usar en la cláusula FROM de una sentencia SELECT. Las filas resultantes son recuperadas iterativamente desde la implementación de la TABLE FUNCTION. Múltiples llamadas a la TABLE FUNCTION, ya sea en la misma consulta o en consultas separadas, provocan muchas ejecuciones de la implementación de la función, sin buffering o reutilización de filas.