PLS-00103使用动态SQL创建外部表

时间:2015-08-20 09:02:31

标签: oracle plsql

我正在尝试动态创建外部表,但我收到错误消息PLS-00103: Encountered the symbol "EXTERNAL"。我也在外部表定义中使用ora_hash;请告诉我这是获得ora_hash价值的正确方法。

create or replace procedure CHECKTABLEEXIST1 (p_tab_name in varchar2,DATAFILE in varchar2) --user_tables.table_name%type)                                    
is                                     
tab_name varchar2(100) := p_tab_name;                                    
n Number(3);                                    
ext_table varchar(100) := tab_name|| ' as select * from xyz WHERE 1=0';                                    
begin                                    
select  count(*) into n from tab where TName=upper(tab_name);                                    

--dbms_output.put_line(n);                                    

if n=0 then                                    
execute immediate 'create table ' || ext_table ;                                    
else                                    
execute immediate 'drop table ' || tab_name;                                    
execute immediate 'create table ' || ext_table;                                    
ORGANIZATION EXTERNAL 
(
TYPE ORACLE_LOADER
DEFAULT DIRECTORY DE_DUBFILE
ACCESS PARAMETER 
    (
    RECORDS DELIMITED BY NEWLINE
    CHARACTERSET US7ASCII
    BADFILE     'UPLOAD':'p_tab_name.bad'
    DISCARDFILE 'UPLOAD':'p_tab_name.dis'
    LOGFILE     'UPLOAD':'p_tab_name.log'
    FILEDS TERMINATED BY ',' 
    optionally enclosed by '"'
    TRAILING NULLCOLS 
    MISSING FIELD VALUES ARE NULL
    (
    t1 ,t2,t3,t4,t5 date "YYYYMMDD" ,t6,t7,
    t8 ,t9 ,
    DETL_CLMNS_HASH "ORA_HASH( :t4||:t7 )",
    KEY_CLMNS_HASH "ORA_HASH(:t1||:t2||:t5)", t10,t11)
    )

LOCATION (DATAFILE)    

);
end if;

end;                                    

我收到错误消息:

LINE/COL ERROR                                                            
-------- -----------------------------------------------------------------
16/14    PLS-00103: Encountered the symbol "EXTERNAL" when expecting one o
         f the following:

   := . ( @ % ;

1 个答案:

答案 0 :(得分:0)

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_nameDATAFILE的引用也必须从该文字中删除,需要更多的单引号和连接;并且实际上是声明一部分的单引号需要通过加倍来转义。还有其他各种报价丢失。现在应该播放什么。

我还将所使用的表名更改为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 || '
...

...所以你不必在两个分支中重复创建语句。

我还纠正了其他几个错误; PARAMETERS而不是PARAMETER; FIELDS而不是FILEDS;已移除TRAILING NULLCOLS。尝试在将命令转换为动态之前将该命令作为静态SQL执行。可能还有其他问题。

我删除了最后两个计算列:

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

ORACLE_LOADER driver不允许这样的操纵; SQL * Loader确实如此,但它们并不完全相同。您也无法在外部表上定义虚拟列。如果您将此作为临时表将数据加载到另一个(实际)表中,那么您可以在传输过程中计算这些哈希值;否则,您可以在此外部表上创建一个包含计算列的视图。