Всичко от ORGANIZATION нататък се разглежда като PL/SQL код, а не част от вашия динамичен SQL оператор. Добавяте името на таблицата към create table но след това не добавяне на останалото като част от този низ на изявление. Трябва да направите нещо като:
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 || ''')
)';
В първия ред крайната точка и запетая е заменена с конкатенация на нов низов литерал. Препратките към променливи p_tab_name и DATAFILE трябва да се отделят и от този литерал, изисквайки повече единични кавички и конкатенация; и единичните кавички, които всъщност са част от израза, трябва да бъдат премахнати чрез удвояването им. Липсваха и различни други цитати. Показаното вече трябва да се изпълнява.
Също така промених името на таблицата, което се използва само на p_tab_name , но трябва изрично да посочите имената на колоните и типовете данни. Няма смисъл да използвате as select * ... за външна маса. Това не е легален синтаксис нито преди organization или след остатъка, ако текущото изявление. Предполагам, че можете да извлечете тази информация от all_tab_columns и изградете тази част също динамично, но ако я базирате на фиксирана таблица, трябва да ги знаете така или иначе.
Вашата логика за отпадане/създаване също е изключена - мисля, че просто искате:
if n>0 then
execute immediate 'drop table ' || p_tab_name;
end if;
execute immediate 'create table ' || p_tab_name || '
...
... така че не се налага да повтаряте оператора create и в двата клона.
Коригирах и няколко други грешки; PARAMETERS вместо PARAMETER; FIELDS вместо FILEDS; премахнати TRAILING NULLCOLS . Опитайте се да изпълните командата като статичен SQL, преди да я конвертирате в динамична. Все още може да има други проблеми.
И премахнах последните две изчислени колони:
DETL_CLMNS_HASH "ORA_HASH( :t4||:t7 )",
KEY_CLMNS_HASH "ORA_HASH(:t1||:t2||:t5)")
ORACLE_LOADER драйвер
не допуска подобни манипулации; SQL*Loader го прави, но не са напълно еднакви. Също така не можете да дефинирате виртуални колони на външна таблица. Ако използвате това като междинна таблица за зареждане на данни в друга (реална) таблица, можете да изчислите тези хешове по време на прехвърлянето; в противен случай можете да създадете изглед върху тази външна таблица, която включва изчислените колони.