sql >> Database >  >> RDS >> Oracle

PLS-00103 een externe tabel maken met dynamische SQL

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.




  1. spring data JPA - mysql - findById() leeg tenzij findAll() eerder is aangeroepen

  2. PL/pgSQL voor alles-in-één dynamische query

  3. Is het mogelijk om een ​​dynamische externe sleutel te hebben, en wat is het beste/juiste om dit te doen?

  4. Hoe tabel in Oracle-procedure af te kappen?