Oracle
 sql >> база данни >  >> RDS >> Oracle

PLS-00103 създаване на външна таблица с динамичен SQL

Всичко от ORGANIZATION нататък се разглежда като PL/SQL код, а не част от вашия динамичен SQL оператор. Добавяте името на таблицата към create table но след това не добавяне на останалото като част от този низ на изявление. Трябва да направите нещо като:

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

В първия ред крайната точка и запетая е заменена с конкатенация на нов низов литерал. Препратките към променливи p_tab_name и DATAFILE трябва да се отделят и от този литерал, изисквайки повече единични кавички и конкатенация; и единичните кавички, които всъщност са част от израза, трябва да бъдат премахнати чрез удвояването им. Липсваха и различни други цитати. Показаното вече трябва да се изпълнява.

Също така промених името на таблицата, което се използва само на p_tab_name , но трябва изрично да посочите имената на колоните и типовете данни. Няма смисъл да използвате as select * ... за външна маса. Това не е легален синтаксис нито преди organization или след остатъка, ако текущото изявление. Предполагам, че можете да извлечете тази информация от all_tab_columns и изградете тази част също динамично, но ако я базирате на фиксирана таблица, трябва да ги знаете така или иначе.

Вашата логика за отпадане/създаване също е изключена - мисля, че просто искате:

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

... така че не се налага да повтаряте оператора create и в двата клона.

Коригирах и няколко други грешки; PARAMETERS вместо PARAMETER; FIELDS вместо FILEDS; премахнати TRAILING NULLCOLS . Опитайте се да изпълните командата като статичен SQL, преди да я конвертирате в динамична. Все още може да има други проблеми.

И премахнах последните две изчислени колони:

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

ORACLE_LOADER драйвер не допуска подобни манипулации; SQL*Loader го прави, но не са напълно еднакви. Също така не можете да дефинирате виртуални колони на външна таблица. Ако използвате това като междинна таблица за зареждане на данни в друга (реална) таблица, можете да изчислите тези хешове по време на прехвърлянето; в противен случай можете да създадете изглед върху тази външна таблица, която включва изчислените колони.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle - литералът не съвпада с грешка в низа за форматиране

  2. Вмъкване на нови колони в средата на таблица?

  3. Настройка на производителността на SQL за Oracle много ИЛИ срещу IN ()

  4. Java SQL изключение:Затворен набор от резултати:следващ, въпреки че нито връзката, нито наборът от резултати не се затварят

  5. Oracle PL/SQL версия 12.2.0.1.0 срещу 12.1.0.2.0 - незабавно изпълнение с параметри