Всичко от 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 го прави, но не са напълно еднакви. Също така не можете да дефинирате виртуални колони на външна таблица. Ако използвате това като междинна таблица за зареждане на данни в друга (реална) таблица, можете да изчислите тези хешове по време на прехвърлянето; в противен случай можете да създадете изглед върху тази външна таблица, която включва изчислените колони.