从SQL * Loader控制文件中访问数据文件名

时间:2009-11-09 07:27:54

标签: sql oracle sql-loader

如何从SQL * Loader控制文件中访问输入数据文件名,以便我可以将其与输入文件中的数据一起插入表中?

比方说,我有以下控制文件:

LOAD DATA

APPEND
INTO TABLE STG_AM02_BA_RAW
WHEN (1:2) = 'DT'
(
        SUBSCRIBER_NO                   POSITION(11:18)CHAR, 
        ACCOUNT_NO                      POSITION(19:32)CHAR, 
        SUBSCRIBER_NAME                 POSITION(33:92)CHAR
)

我想做类似的事情:

LOAD DATA

APPEND
INTO TABLE STG_AM02_BA_RAW
WHEN (1:2) = 'DT'
(
        SUBSCRIBER_NO                   POSITION(11:18)CHAR, 
        ACCOUNT_NO                      POSITION(19:32)CHAR, 
        SUBSCRIBER_NAME                 POSITION(33:92)CHAR, 
        INPUTFILE                       INPUTFILENAME()CHAR
)

假设我没有权限编辑将使用此控制文件调用SQL * Loader的shell脚本。

3 个答案:

答案 0 :(得分:1)

我认为在你指定的情况下没有办法解决这个问题,AFAIK没有办法在“数据”部分正确引用文件名。

解决方法的一些想法:

  • 使用单独的SQL语句更新新插入的记录。您可以从调用SQL * Loader的批处理文件构建语句。
  • 修改数据文件以包含文件名(同样,可以从批处理文件中完成)。
  • 让批处理文件构建控制文件以将文件名包含为常量,这样就可以有类似

    的内容

    INPUTFILE CONSTANT“my_data.dat”

希望这有帮助。

答案 1 :(得分:1)

从11g开始,无法直接从SQL * Loader控制文件访问文件名。

您基本上必须从脚本环境中处理它。

如果您无法修改加载脚本,也许您可​​以在数据文件中添加标题记录?

看起来您在位置1:2中有一个记录类型字段 - 您是否可以修改数据文件创建以包含文件名记录类型?

例如,“FN”数据类型:

FN                ...        inputfile.txt
DT     12345678XXX...XXXXXYYYYYYYYYYYYYYYY
DT     12345678XXX...XXXXXYYYYYYYYYYYYYYYY
DT     12345678XXX...XXXXXYYYYYYYYYYYYYYYY
DT     12345678XXX...XXXXXYYYYYYYYYYYYYYYY
DT     12345678XXX...XXXXXYYYYYYYYYYYYYYYY

您的加载脚本可能会更改为:

LOAD DATA

APPEND
INTO TABLE STG_AM02_BA_RAW
WHEN (1:2) = 'FN'
(
        INPUTFILE                       POSITION(1:92)CHAR
)
WHEN (1:2) = 'DT'
(
        SUBSCRIBER_NO                   POSITION(11:18)CHAR, 
        ACCOUNT_NO                      POSITION(19:32)CHAR, 
        SUBSCRIBER_NAME                 POSITION(33:92)CHAR
)

全部取决于您是否可以更新数据文件......

例如,

echo "FNinputfile.txt" > header.txt
cat header.txt inputfile.txt > newinputfile.txt

如果需要针对每个数据行引用文件名,可以将数据加载到多个临时表中:

LOAD DATA
TRUNCATE INTO TABLE STAGE_FILENAME
WHEN (1:2) = 'FN'
(
        INPUTFILE                       POSITION(1:92)CHAR
)
TRUNCATE INTO TABLE STAGE_DATA
WHEN (1:2) = 'DT'
(
        SUBSCRIBER_NO                   POSITION(11:18)CHAR, 
        ACCOUNT_NO                      POSITION(19:32)CHAR, 
        SUBSCRIBER_NAME                 POSITION(33:92)CHAR
)

...并使用SQL将它们连接在一起:

insert into STG_AM02_BA_RAW
    (
    subscriber_no,
    account_no,
    subscriber_name,
    input_filename
    )
select
    d.subscriber_no,
    d.account_no,
    d.subscriber_name,
    f.inputfile
from
    stage_data d,
    inputfile d

如果你有并发负载,这个过程就会失败。

您在评论中说您可以更改数据文件 - 您是否可以将文件更改为文件名附加到每条记录?如果是这样,那么问题就会消失。你只需要包括:

    SUBSCRIBER_NAME                 POSITION(92:*)CHAR

答案 2 :(得分:0)

解决此问题的简便方法是在每个记录的末尾添加一个额外的列,并使用文件名并将该列的位置映射到该字段。