sql >> Database teknologi >  >> RDS >> Oracle

PLS-00103 oprettelse af en ekstern tabel med dynamisk SQL

Alt fra ORGANIZATION og fremefter bliver set som PL/SQL-kode, ikke en del af din dynamiske SQL-sætning. Du føjer tabelnavnet til create table men derefter ikke at tilføje resten som en del af den erklæringsstreng. Du skal gøre noget 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ørste linje er det afsluttende semikolon blevet erstattet med sammenkædning af en ny streng-literal. Referencerne til variablerne p_tab_name og DATAFILE skal også brydes ud fra det bogstavelige, hvilket kræver flere enkelte citater og sammenkædning; og de enkelte citater, der faktisk er en del af udsagnet, skal undgås ved at fordoble dem. Der manglede også forskellige andre citater. Det, der vises, skulle nu køre.

Jeg har også ændret det tabelnavn, der bruges til kun p_tab_name , men du skal angive kolonnenavnene og datatyperne eksplicit. Det giver ikke mening at bruge as select * ... til et eksternt bord. Det er ikke lovlig syntaks, heller ikke før organization eller efter resten, hvis den aktuelle erklæring. Jeg formoder, at du kunne udtrække den information fra all_tab_columns og byg også den del dynamisk, men hvis du baserer den på en fast tabel, burde du kende dem alligevel.

Din logik til at droppe/oprette er også slået fra - jeg tror, ​​du bare vil:

if n>0 then                                    
  execute immediate 'drop table ' || p_tab_name; 
end if;
execute immediate 'create table ' || p_tab_name || '
...

... så du ikke behøver at gentage oprette-sætningen i begge grene.

Jeg har også rettet et par andre fejl; PARAMETERS i stedet for PARAMETER; FIELDS i stedet for FILEDS; fjernede TRAILING NULLCOLS . Prøv at udføre kommandoen som statisk SQL, før du konverterer den til dynamisk. Der kan stadig være andre problemer.

Og jeg har fjernet de sidste to beregnede kolonner:

    DETL_CLMNS_HASH "ORA_HASH( :t4||:t7 )",
    KEY_CLMNS_HASH "ORA_HASH(:t1||:t2||:t5)")

ORACLE_LOADER chauffør tillader ikke sådanne manipulationer; SQL*Loader gør, men de er ikke helt ens. Du kan heller ikke definere virtuelle kolonner på en ekstern tabel. Hvis du bruger dette som en iscenesættelsestabel til at indlæse data i en anden (rigtig) tabel, så kan du beregne disse hashes under overførslen; ellers kan du oprette en visning over denne eksterne tabel, som inkluderer de beregnede kolonner.




  1. MYSQL Inner Sammenføj to borde over to nøgler

  2. Serialiserede data i mysql-databasen skal kombineres i et array

  3. Hvorfor får jeg en ORA-01722 (ugyldigt nummer)?

  4. GAE Python - Intet modul ved navn MySQLdb