sql >> Databasteknik >  >> RDS >> Oracle

PLS-00103 skapar en extern tabell med dynamisk SQL

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.




  1. Välj information från sista artikeln och gå med i det totala beloppet

  2. MultipleActiveResultSets för postgresql och ado.net enhetsdatamodell

  3. Hur många lika dagar finns mellan två datumintervall, SQL

  4. Uppgradera PostgreSQL från 9.6 till 10.0 på Ubuntu 16.10