sql >> Databáze >  >> RDS >> Oracle

PLS-00103 vytvoření externí tabulky s dynamickým SQL

Vše od ORGANIZATION dále je považován za kód PL/SQL, nikoli za součást vašeho dynamického příkazu SQL. Připojujete název tabulky k create table ale pak nepřipojí zbytek jako součást tohoto řetězce příkazu. Musíte udělat něco jako:

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 || ''')    
)';

V prvním řádku byl koncový středník nahrazen zřetězením nového řetězcového literálu. Odkazy na proměnné p_tab_name a DATAFILE musí být také odděleny od tohoto doslovu, což vyžaduje více jednoduchých uvozovek a zřetězení; a jednoduché uvozovky, které jsou ve skutečnosti součástí prohlášení, je třeba uniknout jejich zdvojením. Chyběly i různé další citace. To, co je zobrazeno, by nyní mělo běžet.

Také jsem změnil používaný název tabulky na pouze p_tab_name , ale musíte explicitně zadat názvy sloupců a datové typy. Nemá smysl používat as select * ... pro externí stůl. To není zákonná syntaxe ani před organization nebo po zbytek pokud aktuální výpis. Předpokládám, že byste mohli extrahovat tyto informace z all_tab_columns a dynamicky sestavovat i tuto část, ale pokud ji zakládáte na pevném stole, měli byste je stejně znát.

Vaše logika pro vypouštění/vytváření je také mimo - myslím, že chcete:

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

... takže nemusíte opakovat příkaz create v obou větvích.

Opravil jsem také několik dalších chyb; PARAMETERS spíše než PARAMETER; FIELDS spíše než FILEDS; odstraněny TRAILING NULLCOLS . Zkuste příkaz provést jako statický SQL, než jej převedete na dynamický. Stále mohou existovat další problémy.

A odstranil jsem poslední dva vypočítané sloupce:

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

ORACLE_LOADER řidič nedovoluje takové manipulace; SQL*Loader ano, ale nejsou úplně stejné. Také nemůžete definovat virtuální sloupce na externí tabulce. Pokud to používáte jako pracovní tabulku pro načítání dat do jiné (skutečné) tabulky, můžete tyto hodnoty hash vypočítat během přenosu; jinak můžete vytvořit pohled na tuto externí tabulku, která obsahuje vypočítané sloupce.




  1. Chyba duplicitního klíče MySQL způsobuje nastavení sdíleného zámku na duplicitním indexovém záznamu?

  2. Vypočítejte rozdíl mezi dvěma daty a časy

  3. Více tabulek nebo jedna megatabulka v SQL?

  4. Cygnus neuchovává data v databázi MySql