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

Lea e importe archivos CSV en Oracle PL/SQL de manera eficiente

El ejemplo se proporciona a continuación para leer e importar archivos CSV archivo (delimitado por comas) en PLSQL. Hay un paquete en Oracle Forms "D2k_Delimited_String" que usamos para leer e importar archivos delimitados por comas (o cualquier delimitador), también he escrito una publicación en Oracle Forms para leer archivos delimitados con este paquete, el siguiente es el enlace https:/ /www.foxinfotech.in/2013/02/reading-and-importing-comma-delimited.html. El mismo paquete que convertí en paquete de base de datos para leer el archivo CSV en PLSQL de manera eficiente, cambié el nombre del paquete a "Plsql_Delimited_String". El siguiente es un ejemplo dado para importar un archivo csv en PL SQL con la ayuda de esta función de paquete Get_String, el siguiente es el uso de esta función:

Plsql_Delimited_String.Getstring ([cadena que contiene texto delimitado, la fila completa],
[ocurrencia],
[falso predeterminado booleano no terminado],
[delimitador]);

En el siguiente procedimiento, el usuario pasará un nombre de archivo que debe estar en la ubicación del directorio creada en el objeto de directorio de Oracle, en este ejemplo se usa el objeto de directorio 'SU_DIRECTORIO', cámbielo con su objeto de directorio y copie el archivo delimitado en esa ubicación y luego pase el nombre del archivo a este procedimiento.

CREAR O REEMPLAZAR PROCEDIMIENTO Import_Emp_File (P_FILENAME IN VARCHAR2,
o_msg OUT VARCHAR2)
IS
Infile UTL_FILE.File_Type;
Linebuf VARCHAR2 (4000);
V_Getstring VARCHAR2 (100 );

-- Matriz de valores de campo
TIPO Fieldvalue ES TABLA DE VARCHAR2 (100)
ÍNDICE POR BINARY_INTEGER;

Field_Position Valor de campo;

Total_Rec_Count NÚMERO :=0;
Total_Rec_NÚMERO Procesado :=0;
COMENZAR
Infile :=UTL_FILE.Fopen ('SU_DIRECTORIO', P_FILENAME, 'R');

LOOP
---
UTL_FILE.Get_Line (Infile, Linebuf);
-- agregar tubería adicional al final de la línea para leer todos los campos

Buf de línea :=Buf de línea || '|';

-- Supongamos que el archivo contiene seis cadenas delimitadas con barra vertical (|)
FOR I IN 1 .. 6
LOOP
Field_Position (I) :=
Plsql_Delimited_String.Getstring (Linebuf ,
I,
FALSO,
'|');
FIN DEL BUCLE;

COMENZAR
Total_Rec_Count :=Total_Rec_Count + 1;

-- una tabla de ejemplo
INSERTAR EN EMP (EMPLOYEE_NUMBER,
FIRST_NAME,
LAST_NAME,
DATE_OF_JOIN,
EMP_TYPE,
DATE_OF_REGN)
VALORES (posición_campo (1),
posición_campo (2),
posición_campo (3),
posición_campo (4),
posición_campo (5),
posición_campo (6) );

Total_Rec_Processed :=Total_Rec_Processed + 1;
EXCEPCIÓN
CUANDO OTROS
ENTONCES
-- ignorando el error durante la inserción de la base de datos
NULL;
FIN;
FIN DEL BUCLE;

IF UTL_FILE.is_open (infile)
THEN
UTL_FILE.Fclose (Infile);
END IF;
EXCEPTION
CUANDO NO_DATA_FOUND
THEN
IF UTL_FILE.is_open (archivo interno)
THEN
UTL_FILE.Fclose (archivo interno);
END IF;

IF total_rec_processed> 0
THEN
COMMIT;
END IF;
CUANDO OTROS
THEN
IF UTL_FILE.is_open (infile)
THEN
UTL_FILE.Fclose (Infile);
END IF;

o_msg :=SQLERRM;
END;
/La siguiente es la fuente del paquete de PLSQL_DELIMITED_STRING utilizada en este ejemplo, instale este paquete en su esquema. El paquete contiene muchas otras funciones de utilidad que se pueden usar para leer el archivo csv usando PLSQL:

CREAR O REEMPLAZAR PAQUETE plsql_Delimited_String ES

función Contador (Fuente_cadena en varchar2,
Sin terminar en booleano predeterminado FALSO,
Delimitador en varchar2 predeterminado ',') número de retorno;
Procedimiento PutString( Fuente_cadena en salida varchar2,
Cadena_para_agregar en varchar2,
Field_position en número,
Sin terminación en valor booleano predeterminado FALSO,
Delimitador en varchar2 predeterminado ',');
Procedimiento PutNumber( Source_string in out varchar2,
number_to_add in number,
Field_position in number,
UnTerpressed in Boolean default FALSE,
Delimiter in varchar2 default ',');
Procedimiento PutDate( Source_string in out varchar2,
Fecha_para_agregar en fecha,
Posición_de campo en número,
Sin terminar en Bo olean predeterminado FALSO,
Delimitador en varchar2 predeterminado ',');
función GetString( Source_string en varchar2,
Field_position en número,
Sin terminar en booleano predeterminado FALSO,
Delimitador en varchar2 por defecto ',') devuelve varchar2;
función GetNumber( Source_string en varchar2,
Field_position en número,
Sin terminar en booleano por defecto FALSO,
Delimitador en varchar2 por defecto ', ') número de retorno;
función GetDate( Source_string in varchar2,
Field_position in number,
UnTerpressed in Boolean default FALSE,
Delimiter in varchar2 default ',') return date;
función Localizar( Source_string en varchar2,
Search_String en varchar2,
Sin terminar en Boole un FALSO predeterminado,
Delimitador en varchar2 predeterminado ',') número de retorno;
función Localizar( Source_string en varchar2,
Buscar_fecha en fecha,
Sin terminar en booleano predeterminado FALSO,
Delimitador en varchar2 por defecto ',') número de retorno;
función Localizar( Source_string en varchar2,
Buscar_número en número,
Sin Terminar en booleano por defecto FALSO,
Delimitador en varchar2 por defecto ',') número de retorno;
END plsql_Delimited_String;
/

CREAR O REEMPLAZAR EL CUERPO DEL PAQUETE plsql_Delimited_String
IS
FUNCIÓN Contador (Source_string IN VARCHAR2,
Sin terminar IN BOOLEAN DEFAULT FALSE,
Delimiter IN VARCHAR2 DEFAULT ',')
DEVOLVER NÚMERO
ES
iModifier PLS_INTEGER :=0;
iOldSize PLS_INTEGER :=LENGTH (Source_string);
BEGIN
IF Unterminated
THEN
iModifier :=1;
FIN SI;

RETURN (iOldSize - LENGTH (REPLACE (Source_string, Delimiter)))
+ iModifier;
END Counter;

PROCEDIMIENTO PutString (Source_string IN OUT VARCHAR2,
String_to_add IN VARCHAR2,
Field_position IN NUMBER,
Sin terminar IN BOOLEAN DEFAULT FALSE,
Delimiter IN VARCHAR2 DEFAULT ',')
IS
iStrLen PLS_INTEGER :=LENGTH (Source_String);
iStrFragLen PLS_INTEGER :=LENGTH (String_to_add);
iPtrStart PLS_INTEGER :=0;
iPtrEnd PLS_INTEGER :=0;
> vcSepBuffer VARCHAR2 (2000);
iCounter PLS_INTEGER;
BEGIN
-- 1. ¿La cadena tiene longitud cero?
IF iStrLen =0
THEN
IF Field_Position> 1
THEN
FOR iCounter IN 2 .. Field_Position
LOOP
vcSepBuffer :=vcSepBuffer || Delimitador;
FIN DEL BUCLE;
FIN SI;

Fuente_cadena :=vcSepBuffer || Cadena_a_añadir;

SI NO No Terminado
ENTONCES
Source_string :=Source_String || Delimiter;
iStrLen :=LENGTH (Source_string);
END IF;
ELSE
-- 2. Hacer frente a cadenas no terminadas
IF Unterminated
THEN
Cadena_fuente :=Cadena_fuente || Delimitador;
END IF;

-- 3. Localice el separador nth-1
IF Field_Position> 1
THEN
LOOP
iPtrStart :=
(INSTR (Source_string || vcSepBuffer,
Delimitador,
1,
Field_Position - 1)
- 1)
+ LONGITUD (Delimitador);
SALIR CUANDO iPtrStart> 0;
vcSepBuffer :=vcBúferSep || Delimitador;
FINALIZAR BUCLE;

SI vcSepBuffer NO ES NULO
ENTONCES
iPtrEnd :=iStrLen;
ELSE
iPtrEnd :=
INSTR (Source_string,
Delimiter,
1 ,
Posición_del_campo);

IF iPtrEnd =0
THEN
iPtrEnd :=iStrLen;
END IF;
END IF;
ELSE
iPtrStart :=0;
iPtrEnd :=
INSTR (Source_string,
Delimiter,
1,
Field_Position);

SI iPtrEnd =0
ENTONCES
iPtrEnd :=iStrLen;
END IF;
END IF;

-- 3. Reconstruya la cadena
Cadena_fuente :=
SUBSTR (Cadena_fuente, 1, iPtrStart)
|| vcSepBuffer
|| Cadena_para_añadir
|| Delimitador
|| SUBSTR (Fuente_cadena, iPtrEnd + LONGITUD (Delimitador));

-- 4. Clasifique la terminación
IF No Terminado
THEN
Source_string :=
SUBSTR (Source_String,
1,
(LENGTH (Source_string) - LENGTH (Delimitador)));
END IF;
END IF;
END PutString;

PROCEDIMIENTO PutNumber (Source_string IN OUT VARCHAR2,
number_to_add IN NUMBER,
Field_position IN NUMBER,
Sin terminar IN BOOLEAN DEFAULT FALSE,
Delimiter IN VARCHAR2 DEFAULT ',')
ES
BEGIN
-- 1. Simplemente haga conversiones de tipos de datos y llame a la variante varchar2 de put..
plsql_Delimited_String.PutString (Source_string,
TO_CHAR (number_to_add),
Field_position,
Sin terminar,
Delimitador);
END PutNumber;

PROCEDIMIENTO PutDate (Source_string IN OUT VARCHAR2,
Date_to_add IN DATE,
Field_position IN NUMBER,
Sin terminar IN BOOLEAN DEFAULT FALSE,
Delimiter IN VARCHAR2 DEFAULT ',')
ES
BEGIN
-- 1. Simplemente realice conversiones de tipos de datos y llame a la versión varchar2 de put..
plsql_Delimited_String.
PutString (Source_string,
TO_CHAR (date_to_add, ' DD-MON-AAAA HH24:MI:SS'),
Posición_campo,
Sin terminar,
Delimitador);
END PutDate;

FUNCTION GetString (Source_string IN VARCHAR2,
Field_position IN NUMBER,
Sin terminar IN BOOLEAN DEFAULT FALSE,
Delimiter IN VARCHAR2 DEFAULT ',')
RETURN VARCHAR2
IS
iPtrEnd PLS_INTEGER :=0;
iPtrStart PLS_INTEGER :=0;
vcSourceStrCopy VARCHAR2 (2000) :=Source_string;
BEGIN
IF No Terminado
THEN
vcSourceStrCopy :=vcSourceStrCopy || Delimitador;
END IF;

IF Field_Position> 1
THEN
iPtrStart :=
INSTR (vcSourceStrCopy,
Delimiter,
1,
Field_Position - 1)
+ LONGITUD (Delimitador);
ELSE
iPtrStart :=1;
END IF;

iPtrEnd :=
INSTR (vcSourceStrCopy,
Delimiter,
1,
Field_Position);
RETURN SUBSTR (vcSourceStrCopy, iPtrStart, (iPtrEnd - iPtrStart));
FIN ObtenerCadena; /* Versión de la cadena */

FUNCIÓN GetNumber (Source_string IN VARCHAR2,
Field_position IN NUMBER,
Sin terminar IN BOOLEAN DEFAULT FALSE,
Delimiter IN VARCHAR2 DEFAULT ',')
RETURN NUMBER
IS
iRc PLS_INTEGER;
BEGIN
RETURN TO_NUMBER (GetString (Source_string,
Field_Position,
UnTerpressed,
Delimiter));
END GetNumber; /* Versión del número */

FUNCIÓN GetDate (Source_string IN VARCHAR2,
Field_position IN NUMBER,
Sin terminar IN BOOLEAN DEFAULT FALSE,
Delimiter IN VARCHAR2 DEFAULT ',')
RETURN DATE
IS
BEGIN
RETURN TO_DATE (GetString (Source_string,
Field_Position,
UnTerpressed,
Delimiter), 'DD-MON-YYYY HH24:MI:SS');
FIN Obtener Fecha; /* Fecha Versión */

FUNCIÓN Localizar (Source_string IN VARCHAR2,
Search_String IN VARCHAR2,
Sin terminar IN BOOLEAN DEFAULT FALSE,
Delimiter IN VARCHAR2 DEFAULT ',')
DEVOLVER NÚMERO
ES
iHit PLS_INTEGER :=0;
iCounter PLS_INTEGER;
vcCompare VARCHAR2 (2000);
BEGIN
FOR iCounter IN 1 .. Counter (Source_String, UnTerpressed, Delimiter)
LOOP
IF GetString (Source_String,
iCounter,
Sin terminar,
Delimitador) =Search_String
THEN
iHit :=iCounter;
SALIR;
FIN SI;
FIN DEL BUCLE;

VOLVER iHit;
FIN Localizar;

FUNCIÓN Localizar (Source_string IN VARCHAR2,
Search_date IN DATE,
Sin terminar IN BOOLEAN DEFAULT FALSE,
Delimiter IN VARCHAR2 DEFAULT ',')
RETURN NUMBER
IS
BEGIN
RETURN Localice (Source_string,
TO_CHAR (Search_date, 'DD-MON-YYYY HH24:MI:SS'),
Sin terminar,
Delimitador);
FIN Localizar; /* Fecha Versión */

FUNCIÓN Localizar (Source_string IN VARCHAR2,
Search_number IN NUMBER,
Sin terminar IN BOOLEAN DEFAULT FALSE,
Delimiter IN VARCHAR2 DEFAULT ',')
DEVOLVER NÚMERO
ES
BEGIN
RETURN Localizar (Fuente_cadena,
TO_CHAR (Buscar_número),
Sin terminar,
Delimitador);
FIN Localizar; /* Versión del número */
FIN; /* Cuerpo */
/