导入每个单元格以换行符终止的CSV

时间:2015-11-06 04:25:10

标签: oracle sql-loader

我有CSV文件。数据如下所示:

PRICE_a
123
PRICE_b
500
PRICE_c
1000
PRICE_d
506

我的XYZ表是:

CREATE TABLE XYZ (
DESCRIPTION_1 VARCHAR2(25),
VALUE NUMBER
)

上面的csv可以导入到oracle吗? 如何创建control.ctl文件?

1 个答案:

答案 0 :(得分:1)

这里是如何在不进行任何预处理的情况下完成的。使用CONCATENATE 2子句告诉SQL-Loader将每两行连接在一起。这会构建逻辑记录,但在两个字段之间没有分隔符。没问题,但首先要了解如何读取和处理数据文件。 SQL-Loader将一次读取数据文件的记录,并尝试按从左到右的顺序将每个字段映射到控制文件中列出的字段。请参阅下面的控制文件。由于它读取的连接记录与控制文件中的TEMP匹配,并且TEMP与表中的列不匹配,因此不会尝试插入它。相反,由于它被定义为BOUNDFILLER,这意味着不要尝试对它做任何事情,但保存它以备将来使用。没有更多数据文件字段要尝试匹配,但控制文件接下来列出了与列名DESCRIPTION_1匹配的字段名称,因此它将应用表达式并插入它。

表达式表示将regexp_substr函数应用于保存的字符串:TEMP(我们知道该文件中的整个记录​​)并返回该记录的子字符串,该字符串由零个或多个非数字字符组成。字符串的开头,后跟零个或多个数字字符,直到字符串结尾,并将其插入DESCRIPTION_1列。

然后对VALUE列进行相同的操作,只返回字符串末尾的数字部分,跳过字符串开头的非数字部分。

load data
infile 'xyz.dat'
CONCATENATE 2
into table XYZ
truncate
TRAILING NULLCOLS
(
  TEMP          BOUNDFILLER CHAR(30),
  DESCRIPTION_1 EXPRESSION  "REGEXP_SUBSTR(:TEMP, '^([^0-9]*)[0-9]*$', 1, 1, NULL, 1)",
  VALUE         EXPRESSION  "REGEXP_SUBSTR(:TEMP, '^[^0-9]*([0-9]*)$', 1, 1, NULL, 1)"
)

Bada-boom,bada-bing:

SQL> select *
   from XYZ
   /

DESCRIPTION_1                  VALUE
------------------------- ----------
PRICE_a                          123
PRICE_b                          500
PRICE_c                         1000
PRICE_d                          506

SQL>

请注意,这非常依赖于示例后面的数据,您应该对数据进行一些分析,以确保正则表达式在投入生产之前能够正常工作。如果描述可能包含数字,则需要进行一些调整。如果您可以使用真正的CSV格式的分隔符正确格式化数据,那就更好了。