sql >> Base de Datos >  >> RDS >> Oracle

¿Obtener la ubicación y el nombre de archivo de una tabla externa?

No conozco ninguna forma de capturar el nombre del archivo dentro de los parámetros de acceso. Como solución alternativa, en lugar de modificar los archivos originales, puede usar un preprocesador para agregar el nombre del archivo sobre la marcha. Si tenía dos archivos, diga file_1.csv que contiene a,b,1 y file_2.csv que contiene c,d,2 , podría tener un pequeño script de shell como append_filename.sh :

#!/bin/bash
while read line
do
  printf "%s,%s\n" "${line}" "${1##*/}"
done < $1

que puede verificar hace algo útil llamando directamente al script:

$ ./append_filename.sh file_1.csv
a,b,1,file_1.csv

Luego puede definir su tabla externa para llamarla a través del preprocessor cláusula, algo como:

create table e42 (
  col1 varchar2(10),
  col2 varchar2(10),
  col3 number,
  filename varchar2(30)
)
organization external (
  type oracle_loader
  default directory d42
  access parameters (
    records delimited by newline
    preprocessor 'append_filename.sh'
    fields terminated by ','
  )
  location ('file_1.csv', 'file_2.csv')
);

Table E42 created.

Luego, el nombre del archivo se selecciona automáticamente:

select * from e42;

COL1       COL2             COL3 FILENAME                     
---------- ---------- ---------- ------------------------------
a          b                   1 file_1.csv                    
c          d                   2 file_2.csv                    

Eliminé la ruta del directorio para que solo vea el nombre del archivo; puede conservar la ruta completa si lo prefiere, pero puede que no sea necesario y podría revelar los detalles del sistema operativo a las personas que solo pueden consultar la tabla. Tenga en cuenta las pautas de seguridad; Lo mantuve simple aquí al usar un directorio para todo, pero debe colocar el preprocesador en otro lugar. Y, por supuesto, esto supone una plataforma Unix-y o herramientas GNU; algo similar debería ser posible con un archivo por lotes si está utilizando Windows.

Este enfoque de lectura línea por línea será relativamente lento para archivos grandes; con un archivo de prueba de 1,5 millones de filas al agregar el nombre del archivo tomó alrededor de 80 segundos en mi plataforma. Otras herramientas integradas serán más rápidas; esta versión con sed toma poco más de un segundo para el mismo archivo:

#!/bin/bash
sed -e 's!$!,'"${1##*/}"'!' $1

Podrías probar otra alternativa como awk también; probablemente necesite probar algunos para ver qué funciona mejor (o lo suficientemente rápido) en su entorno.