批量加载Oracle中的UDT列

时间:2011-10-31 15:03:03

标签: oracle csv sql-loader

我有一个具有以下结构的表:

create table my_table (
    id integer,
    point Point -- UDT made of two integers (x, y)
)

我有一个包含以下数据的CSV文件:

#id, point
1|(3, 5)
2|(7, 2)
3|(6, 2)

现在我想将这个CSV批量加载到我的表中,但是我无法找到有关如何在Oracle sqlldr util中处理UDT的任何信息。在使用UDT列时是否可以使用批量加载工具?

2 个答案:

答案 0 :(得分:0)

我不知道sqlldr是否可以这样做,但我个人会使用外部表。

将文件作为外部表附加(该文件必须位于数据库服务器上),然后将外部表的内容插入到目标表中,将UDT转换为两个值。以下select from dual应该可以帮助您进行翻译:

select
  regexp_substr('(5, 678)', '[[:digit:]]+', 1, 1) x_point,
  regexp_substr('(5, 678)', '[[:digit:]]+', 1, 2) y_point
from dual;

更新

在sqlldr中,您可以使用标准SQL表达式转换字段:

LOAD DATA
  INFILE 'data.dat'
  BADFILE 'bad_orders.txt'
  APPEND
  INTO TABLE test_tab
  FIELDS TERMINATED BY "|"
  (  info,
     x_cord "regexp_substr(:x_cord, '[[:digit:]]+', 1, 1)",
  )

上面的控制文件将提取字段中的第一个数字,如(3,4),但我找不到提取第二个数字的方法 - 即我不确定是否可以在输入文件插入两列。

如果外部表不适合您,我建议(1)在加载前转换文件,使用sed,awk,Perl等,或者(2)将文件SQLLDR转换为临时表,然后再进行第二个过程转换数据并插入到最终表中。另一种选择是查看文件是如何生成的 - 您是否可以生成文件,以便在文件的两个字段中重复需要转换的字段,例如:

data|(1, 2)|(1, 2)

也许其他人会想办法让sqlldr做你想做的事。

答案 1 :(得分:0)

经过更多研究后解决了这个问题,因为Oracle SQL * Loader具有此功能,并且通过指定column object来使用它,以下是解决方案:

LOAD DATA
INFILE *
INTO TABLE my_table
FIELDS TERMINATED BY "," OPTIONALLY ENCLOSED BY '"'
TRAILING NULLCOLS
(
    id,
    point column object
    (
        x,
        y
    )
)
BEGINDATA
1,3,5
2,7,2
3,6,2