【问题标题】:Creating external tables in Oracle procedure在 Oracle 过程中创建外部表
【发布时间】:2017-04-07 20:36:35
【问题描述】:

我使用的是 Oracle 11g,但在过程中创建外部表时遇到问题。它的创建没有错误,但是当我执行该过程时出现错误。

第一个参数是文件名,第二个参数是逗号,因为我在使用单引号包围逗号时遇到了问题,我在其中指定了以节结尾的字段。 DATA_DIR 已声明。

这是我尝试过的。

CREATE OR REPLACE PROCEDURE LOADTABLE
(
    FILENAME VARCHAR2,
    COMMA VARCHAR
)
AS
BEGIN

    EXECUTE IMMEDIATE 'CREATE TABLE LOAD
    (
       USERNAME VARCHAR2(30)
    )
    ORGANIZATION EXTERNAL
    (
        TYPE ORACLE_LOADER
        DEFAULT DIRECTORY DATA_DIR
        ACCESS PARAMETERS
        ( FIELDS TERMINATED BY :COMMA)
        LOCATION (:FILENAME)
    )' USING IN COMMA, FILENAME;
END;

这就是我调用过程的方式

EXEC LOADTABLE('username.csv',',');

这是我得到的错误

ERROR at line 1:
ORA-00931: missing identifier
ORA-06512: at "DATA_ADMIN.LOADTABLE", line 9
ORA-06512: at line 1

任何帮助将不胜感激。

【问题讨论】:

    标签: oracle plsql dynamic-sql external-tables


    【解决方案1】:

    您只能绑定变量,并且外部表创建语法需要您尝试绑定的元素的文本字面量。

    您必须改用串联:

    CREATE OR REPLACE PROCEDURE LOADTABLE
    (
      FILENAME VARCHAR2,
      COMMA VARCHAR
    )
    AS
    BEGIN
      EXECUTE IMMEDIATE 'CREATE TABLE LOAD
    (
      USERNAME VARCHAR2(30)
    )
    ORGANIZATION EXTERNAL
    (
      TYPE ORACLE_LOADER
      DEFAULT DIRECTORY DATA_DIR
      ACCESS PARAMETERS
      (FIELDS TERMINATED BY ''' || COMMA || ''')
      LOCATION (''' || FILENAME || ''')
    )';
    END;
    /
    
    Procedure LOADTABLE compiled
    
    EXEC LOADTABLE('username.csv',',');
    
    PL/SQL procedure successfully completed.
    

    我已经转义了连接字符串值周围的单引号。在您提到的问题中,您只是传递逗号,因为您“在使用单引号包围逗号时遇到问题”;通过将它们加倍来逃避它们是这样做的方法,所以如果你总是想要一个逗号分隔符,你可以这样做:

    CREATE OR REPLACE PROCEDURE LOADTABLE
    (
      FILENAME VARCHAR2
    )
    AS
    BEGIN
      EXECUTE IMMEDIATE 'CREATE TABLE LOAD
    (
      USERNAME VARCHAR2(30)
    )
    ORGANIZATION EXTERNAL
    (
      TYPE ORACLE_LOADER
      DEFAULT DIRECTORY DATA_DIR
      ACCESS PARAMETERS
      (FIELDS TERMINATED BY '','')
      LOCATION (''' || FILENAME || ''')
    )';
    END;
    /
    
    EXEC LOADTABLE('username.csv');
    

    但是,动态创建(并且可能会丢弃)对象通常不是一个好主意。最好只创建一次外部表,这将使用静态 DDL 完成:

    CREATE TABLE LOAD
    (
      USERNAME VARCHAR2(30)
    )
    ORGANIZATION EXTERNAL
    (
      TYPE ORACLE_LOADER
      DEFAULT DIRECTORY DATA_DIR
      ACCESS PARAMETERS
      (FIELDS TERMINATED BY ',')
      LOCATION ('dummy')
    );
    

    然后只需静态更改表以具有新文件名:

    alter table load location ('username.csv');
    

    或者如果你真的想要一个程序来做:

    CREATE OR REPLACE PROCEDURE LOADTABLE
    (
      FILENAME VARCHAR2
    )
    AS
    BEGIN
      EXECUTE IMMEDIATE 'ALTER TABLE LOAD LOCATION (''' || FILENAME || ''')';
    END;
    /
    
    EXEC LOADTABLE('username.csv');
    

    【讨论】:

    • 在上述情况下,我们正在更改表位置。旧记录已经存在于表中,我们不再需要这些记录。为了避免这种情况,我们可以做些什么..
    • 不确定位置变化与现有数据有何关系,但无论如何,请提出一个新问题来解释您的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 2011-06-01
    相关资源
    最近更新 更多