Todo de ORGANIZATION
en adelante se ve como código PL/SQL, no como parte de su declaración SQL dinámica. Está agregando el nombre de la tabla a create table
pero luego no agregar el resto como parte de esa cadena de declaración. Tienes que hacer algo como:
execute immediate 'create table ' || p_tab_name || '
( /* put column names and types here */ )
ORGANIZATION EXTERNAL
(
TYPE ORACLE_LOADER
DEFAULT DIRECTORY DE_DUBFILE
ACCESS PARAMETERS
(
RECORDS DELIMITED BY NEWLINE
CHARACTERSET US7ASCII
BADFILE UPLOAD:''' || p_tab_name || '.bad''
DISCARDFILE UPLOAD:''' || p_tab_name || '.dis''
LOGFILE UPLOAD:''' || p_tab_name || '.log''
FIELDS TERMINATED BY '',''
optionally enclosed by ''"''
MISSING FIELD VALUES ARE NULL
(
t1 ,t2,t3,t4,t5 date mask "YYYYMMDD" ,t6,t7,
t8 ,t9, t10,t11
)
LOCATION (''' || DATAFILE || ''')
)';
En la primera línea, el punto y coma final se reemplazó con la concatenación de un nuevo literal de cadena. Las referencias a variables p_tab_name
y DATAFILE
también debe separarse de ese literal, lo que requiere más comillas simples y concatenación; y las comillas simples que en realidad son parte de la declaración deben escaparse duplicándolas. También faltaban varias otras citas. Lo que se muestra ahora debería ejecutarse.
También cambié el nombre de la tabla que se usa para simplemente p_tab_name
, pero debe especificar los nombres de las columnas y los tipos de datos de forma explícita. No tiene sentido usar as select * ...
para una mesa externa. Esa no es una sintaxis legal, tampoco antes de organization
o después del resto si la declaración actual. Supongo que podrías extraer esa información de all_tab_columns
y construya esa parte dinámicamente también, pero si la está basando en una tabla fija, debería conocerla de todos modos.
Tu lógica para soltar/crear también está desactivada. Creo que solo quieres:
if n>0 then
execute immediate 'drop table ' || p_tab_name;
end if;
execute immediate 'create table ' || p_tab_name || '
...
... para que no tenga que repetir la declaración de creación en ambas ramas.
También he corregido un par de otros errores; PARAMETERS
en lugar de PARAMETER
; FIELDS
en lugar de FILEDS
; eliminado TRAILING NULLCOLS
. Intente ejecutar el comando como SQL estático antes de convertirlo en dinámico. Todavía puede haber otros problemas.
Y eliminé las dos últimas columnas calculadas:
DETL_CLMNS_HASH "ORA_HASH( :t4||:t7 )",
KEY_CLMNS_HASH "ORA_HASH(:t1||:t2||:t5)")
El ORACLE_LOADER
conductor
no permite manipulaciones como esa; SQL*Loader sí, pero no son exactamente iguales. Tampoco puede definir columnas virtuales en una tabla externa. Si está utilizando esto como una tabla de preparación para cargar datos en otra tabla (real), puede calcular esos hash durante la transferencia; de lo contrario, puede crear una vista sobre esta tabla externa que incluya las columnas calculadas.