从 SQLloader 到外部表 [Oracle]

From SQLoader to External Tables [Oracle]

目前我有一些平面文件,它们是用 SQLoader 加载到数据库中的,但我想用外部 tables 替换 SQLoader 脚本,但我遇到了 "translating" 的问题SQLloader 到外部 tables.

因此,例如我有一个平面文件,如下所示:

~#~col1>|col2>|col3...

我有一个 SQloader .ctl 文件,看起来像这样:

LOAD DATA                                                                       
APPEND
CONTINUEIF NEXT PRESERVE (1:3) <> '~#~'
INTO TABLE my_tab
FIELDS TERMINATED BY ">|"  TRAILING NULLCOLS          
(                                                                               
  col1                 "LTRIM(Trim(:col1),'~#~')",
  col2                 "TRIM(:col2)",                                          
  col3                 "TRIM(:col3)",
  col4                  CONSTANT #$TASKID$#,
  col5                  CONSTANT #$SESSION$#,
  col6                  RECNUM,
  col7                  SEQUENCE(MAX)
)  

目前我已经尝试了很多东西 -

create table my_tab(
   col1    varchar2(100) 
  ,col2    number(38)         
  ,col3    number(38)
  ,... 
)
organization external(
  type oracle_loader
    default directory my_dir
    access parameters(
      records delimited by newline
      fields terminated by '>|' 
      missing field values are null
      reject rows with all null fields
    )
    location('my_file.txt')
 );

所以我有以下问题:

如何在定义外部 table 时调用 TRIM 函数? (甚至可能吗?)或者唯一的方法是创建另一个 view/table 用于数据暂存,并进行所有数据转换,然后将数据插入目标 table?

提前致谢!

假设您的记录总是以 ~#~ 开头,您可以使用几个未映射到 table 定义的虚拟列来使用它:

create table my_tab(
   col1    varchar2(100) 
  ,col2    number(38)         
  ,col3    number(38)
)
organization external(
  type oracle_loader
    default directory my_dir
    access parameters(
      records delimited by newline
      fields terminated by '>|' 
      missing field values are null
      reject rows with all null fields
      (
        colx char(1) terminated by "~",
        coly char(1) terminated by "~",
        col1,
        col2,
        col3
      )
    )
    location('my_file.txt')
 );

没有 trim clause specified 的默认行为是 LDRTRIM,其行为与 SQL*Loader 的 TRIM 相同。您还可以将其设置为 NOTRIM 以指定每列的空白修剪。


如果你想丢弃你的 EOF 标记记录但加载其他所有内容你可以使用 LOAD WHEN option, optionally with NODISCARDFILE 如果你不想保留它们的记录:

...
organization external(
  type oracle_loader
    default directory d42
    access parameters(
      records delimited by newline
      load when (1:15) != "###~~~EOF~~~###"
      nodiscardfile
      fields terminated by '>|' 
...