Oracle SQL管道分隔文件,带有一个逗号分隔列,可以使用SQLLDR进行拆分和加载

时间:2014-11-13 21:09:44

标签: split sql-loader delimited

输入样本数据:

Style|Size|Codes
Modern|9|A224, B153, C166
Retro|8|D532, E533, F122
Vintage|7|G324, H243, I432

使用SQLLDR - 需要此输出:

Style     Size     Code1      Code2      Code3
Modern    9        A224       B153       C166
Retro     8        D532       E533       F122
Vintage   7        G324       H243       I432

1 个答案:

答案 0 :(得分:0)

您可以在途中对数据进行转换。它在控制文件中指定。有关示例,请参阅最近的帖子:SQLLDR CTL: Load date field received in DDMonYYYY to db fields with formats of YYYYMM or MM/DD/YYYY

我会使用REGEXP_SUBSTR从逗号分隔列表中的位置提取各种代码。试一试,让我们知道会发生什么。

看起来您的目标表将包含有限数量的代码列。如果您的数据具有比目标表具有列更多的数据,该怎么办?考虑为项目创建自己的表格代码,以免违反第一范式(每列只有一个值)。

如果来自源文件的代码字符串实际上是描述作为项目的一部分,那么它们很可能保持在一起作为code_description列。这取决于您的应用或报告如何使用此数据。

所有这一切,诀窍是将代码字段定义为BOUNDFILLER。这表示将其视为FILLER而不加载它,但让它在后面的表达式中用作绑定变量。在您的控制文件中尝试此操作:

LOAD DATA
INFILE 'data.txt'
APPEND
INTO TABLE X_TEST
FIELDS TERMINATED BY '|'
TRAILING NULLCOLS
(
 STYLE       CHAR
,SIZE        CHAR
,CODESTRING  BOUNDFILLER
,CODE1      "trim(regexp_substr(:CODESTRING, '([^,]*)(,|$)', 1, 1, NULL, 1))"
,CODE2      "trim(regexp_substr(:CODESTRING, '([^,]*)(,|$)', 1, 2, NULL, 1))"
,CODE3      "trim(regexp_substr(:CODESTRING, '([^,]*)(,|$)', 1, 3, NULL, 1))"
)

正则表达式可以读作"返回零个或多个非逗号字符的第n次出现,后面跟一个逗号或行的结尾,并返回第一个子组(这是少数据)逗号或行的结尾)。只需将其包装在对TRIM()的调用中以删除空格或等待其中一个REGEXP向导提供改进的REGEX。如果只有2个代码,则CODE3将为NULL。