Allt från ORGANIZATION
och framåt ses som PL/SQL-kod, inte en del av din dynamiska SQL-sats. Du lägger till tabellnamnet i create table
men sedan inte lägga till resten som en del av den uttalandesträngen. Du måste göra något 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örsta raden har det avslutande semikolonet ersatts med sammanlänkning av en ny strängliteral. Referenserna till variablerna p_tab_name
och DATAFILE
måste brytas ut från det bokstavliga också, vilket kräver fler enstaka citattecken och sammanlänkning; och de enskilda citattecken som faktiskt är en del av uttalandet måste undvikas genom att dubbla dem. Det saknades också flera andra citat. Det som visas ska nu köras.
Jag har också ändrat tabellnamnet som används till bara p_tab_name
, men du måste ange kolumnnamn och datatyper uttryckligen. Det är inte meningsfullt att använda as select * ...
för ett externt bord. Det är inte laglig syntax, heller före organization
eller efter resten om det aktuella uttalandet. Jag antar att du kan extrahera den informationen från all_tab_columns
och bygg den delen dynamiskt också, men om du baserar den på en fast tabell borde du känna till dem ändå.
Din logik för att släppa/skapa är också avstängd - jag tror att du bara vill:
if n>0 then
execute immediate 'drop table ' || p_tab_name;
end if;
execute immediate 'create table ' || p_tab_name || '
...
... så att du inte behöver upprepa skapa-satsen i båda grenarna.
Jag har också rättat ett par andra misstag; PARAMETERS
istället för PARAMETER
; FIELDS
istället för FILEDS
; tog bort TRAILING NULLCOLS
. Försök att utföra kommandot som statisk SQL innan du konverterar det till dynamiskt. Det kan fortfarande finnas andra problem.
Och jag har tagit bort de två senaste beräknade kolumnerna:
DETL_CLMNS_HASH "ORA_HASH( :t4||:t7 )",
KEY_CLMNS_HASH "ORA_HASH(:t1||:t2||:t5)")
ORACLE_LOADER
förare
tillåter inte sådana manipulationer; SQL*Loader gör det men de är inte exakt likadana. Du kan inte heller definiera virtuella kolumner på en extern tabell. Om du använder detta som en iscensättningstabell för att ladda data till en annan (riktig) tabell så kan du beräkna dessa hash under överföringen; annars kan du skapa en vy över denna externa tabell som inkluderar de beräknade kolumnerna.