Alles van ORGANIZATION
wordt gezien als PL/SQL-code, niet als onderdeel van uw dynamische SQL-statement. U voegt de tabelnaam toe aan de create table
maar dan de rest niet toevoegen als onderdeel van die instructiereeks. Je moet iets doen als:
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 || ''')
)';
In de eerste regel is de afsluitende puntkomma vervangen door een aaneenschakeling van een nieuwe letterlijke tekenreeks. De verwijzingen naar variabelen p_tab_name
en DATAFILE
moeten ook uit dat letterlijke worden doorbroken, wat meer enkele aanhalingstekens en aaneenschakeling vereist; en de enkele aanhalingstekens die daadwerkelijk deel uitmaken van de verklaring, moeten worden ontsnapt door ze te verdubbelen. Er ontbraken ook verschillende andere citaten. Wat wordt weergegeven, zou nu moeten worden uitgevoerd.
Ik heb ook de tabelnaam die wordt gebruikt veranderd in gewoon p_tab_name
, maar u moet de kolomnamen en gegevenstypen expliciet opgeven. Het heeft geen zin om as select * ...
. te gebruiken voor een externe tafel. Dat is geen juridische syntaxis, ook niet vóór organization
of na de rest als de huidige verklaring. Ik veronderstel dat je die informatie zou kunnen extraheren uit all_tab_columns
en bouw dat onderdeel ook dynamisch op, maar als je het op een vaste tafel baseert, zou je die toch moeten weten.
Je logica om te laten vallen/maken klopt ook niet - ik denk dat je gewoon wilt:
if n>0 then
execute immediate 'drop table ' || p_tab_name;
end if;
execute immediate 'create table ' || p_tab_name || '
...
... zodat u de create-instructie niet in beide branches hoeft te herhalen.
Ik heb ook een paar andere fouten gecorrigeerd; PARAMETERS
in plaats van PARAMETER
; FIELDS
in plaats van FILEDS
; verwijderde TRAILING NULLCOLS
. Probeer de opdracht uit te voeren als statische SQL voordat u deze naar dynamisch converteert. Er kunnen nog andere problemen zijn.
En ik heb de laatste twee berekende kolommen verwijderd:
DETL_CLMNS_HASH "ORA_HASH( :t4||:t7 )",
KEY_CLMNS_HASH "ORA_HASH(:t1||:t2||:t5)")
De ORACLE_LOADER
chauffeur
staat dergelijke manipulaties niet toe; SQL*Loader doet dat wel, maar ze zijn niet precies hetzelfde. U kunt ook geen virtuele kolommen definiëren op een externe tabel. Als je dit gebruikt als een verzameltabel om gegevens in een andere (echte) tabel te laden, dan kun je die hashes berekenen tijdens de overdracht; anders kunt u een weergave maken over deze externe tabel die de berekende kolommen bevat.