Alt fra ORGANIZATION
og fremefter bliver set som PL/SQL-kode, ikke en del af din dynamiske SQL-sætning. Du føjer tabelnavnet til create table
men derefter ikke at tilføje resten som en del af den erklæringsstreng. Du skal gøre noget som:
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 || ''')
)';
I den første linje er det afsluttende semikolon blevet erstattet med sammenkædning af en ny streng-literal. Referencerne til variablerne p_tab_name
og DATAFILE
skal også brydes ud fra det bogstavelige, hvilket kræver flere enkelte citater og sammenkædning; og de enkelte citater, der faktisk er en del af udsagnet, skal undgås ved at fordoble dem. Der manglede også forskellige andre citater. Det, der vises, skulle nu køre.
Jeg har også ændret det tabelnavn, der bruges til kun p_tab_name
, men du skal angive kolonnenavnene og datatyperne eksplicit. Det giver ikke mening at bruge as select * ...
til et eksternt bord. Det er ikke lovlig syntaks, heller ikke før organization
eller efter resten, hvis den aktuelle erklæring. Jeg formoder, at du kunne udtrække den information fra all_tab_columns
og byg også den del dynamisk, men hvis du baserer den på en fast tabel, burde du kende dem alligevel.
Din logik til at droppe/oprette er også slået fra - jeg tror, du bare vil:
if n>0 then
execute immediate 'drop table ' || p_tab_name;
end if;
execute immediate 'create table ' || p_tab_name || '
...
... så du ikke behøver at gentage oprette-sætningen i begge grene.
Jeg har også rettet et par andre fejl; PARAMETERS
i stedet for PARAMETER
; FIELDS
i stedet for FILEDS
; fjernede TRAILING NULLCOLS
. Prøv at udføre kommandoen som statisk SQL, før du konverterer den til dynamisk. Der kan stadig være andre problemer.
Og jeg har fjernet de sidste to beregnede kolonner:
DETL_CLMNS_HASH "ORA_HASH( :t4||:t7 )",
KEY_CLMNS_HASH "ORA_HASH(:t1||:t2||:t5)")
ORACLE_LOADER
chauffør
tillader ikke sådanne manipulationer; SQL*Loader gør, men de er ikke helt ens. Du kan heller ikke definere virtuelle kolonner på en ekstern tabel. Hvis du bruger dette som en iscenesættelsestabel til at indlæse data i en anden (rigtig) tabel, så kan du beregne disse hashes under overførslen; ellers kan du oprette en visning over denne eksterne tabel, som inkluderer de beregnede kolonner.