在 Oracle 过程中创建外部表

Posted

技术标签:

【中文标题】在 Oracle 过程中创建外部表【英文标题】:Creating external tables in Oracle procedure 【发布时间】: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

任何帮助将不胜感激。

【问题讨论】:

【参考方案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');

【讨论】:

在上述情况下,我们正在更改表位置。旧记录已经存在于表中,我们不再需要这些记录。为了避免这种情况,我们可以做些什么.. 不确定位置变化与现有数据有何关系,但无论如何,请提出一个新问题来解释您的问题。

以上是关于在 Oracle 过程中创建外部表的主要内容,如果未能解决你的问题,请参考以下文章

oracle 看报错日志怎么看

在 Impala 中创建外部表 - 错误

可以在 Redshift 中的特定目录中创建外部表吗?

在 spark 中创建带有模式的配置单元外部表

在 hive 的外部表中创建分区

Hive中创建S3的外部表