Tout de ORGANIZATION
est considéré comme du code PL/SQL, et non comme une partie de votre instruction SQL dynamique. Vous ajoutez le nom de la table au create table
mais sans ajouter le reste dans le cadre de cette chaîne d'instructions. Vous devez faire quelque chose comme :
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 || ''')
)';
Dans la première ligne, le point-virgule de fin a été remplacé par la concaténation d'un nouveau littéral de chaîne. Les références aux variables p_tab_name
et DATAFILE
doivent également être séparés de ce littéral, nécessitant davantage de guillemets simples et de concaténation ; et les guillemets simples qui font réellement partie de l'instruction doivent être échappés en les doublant. Il manquait également diverses autres citations. Ce qui est affiché devrait maintenant fonctionner.
J'ai également changé le nom de la table utilisé pour juste p_tab_name
, mais vous devez spécifier explicitement les noms de colonne et les types de données. Cela n'a pas de sens d'utiliser as select * ...
pour une table externe. Ce n'est pas une syntaxe légale, ni avant organization
ou après le reste si la déclaration en cours. Je suppose que vous pourriez extraire ces informations de all_tab_columns
et construisez également cette partie de manière dynamique, mais si vous la basez sur une table fixe, vous devriez quand même les connaître.
Votre logique de suppression/création est également erronée - je pense que vous voulez simplement :
if n>0 then
execute immediate 'drop table ' || p_tab_name;
end if;
execute immediate 'create table ' || p_tab_name || '
...
... afin que vous n'ayez pas à répéter l'instruction de création dans les deux branches.
J'ai également corrigé quelques autres erreurs; PARAMETERS
plutôt que PARAMETER
; FIELDS
plutôt que FILEDS
; supprimé TRAILING NULLCOLS
. Essayez d'exécuter la commande en tant que SQL statique avant de la convertir en dynamique. Il peut encore y avoir d'autres problèmes.
Et j'ai supprimé les deux dernières colonnes calculées :
DETL_CLMNS_HASH "ORA_HASH( :t4||:t7 )",
KEY_CLMNS_HASH "ORA_HASH(:t1||:t2||:t5)")
Le ORACLE_LOADER
chauffeur
ne permet pas de telles manipulations ; SQL*Loader le fait mais ils ne sont pas exactement les mêmes. Vous ne pouvez pas non plus définir de colonnes virtuelles sur une table externe. Si vous l'utilisez comme table intermédiaire pour charger des données dans une autre table (réelle), vous pouvez calculer ces hachages pendant le transfert ; sinon vous pouvez créer une vue sur cette table externe qui inclut les colonnes calculées.