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

标签 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 脚本。

最佳答案

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

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

如果您无法修改加载脚本,也许您可​​以向数据文件添加一个 header 记录?

看起来您在位置 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

关于sql - 从 SQL*Loader 控制文件中访问数据文件名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1699574/

相关文章:

python - 有没有办法在 Python 中对 1900 年之前的日期使用类似 strftime 的函数?

multithreading - Oracle sqlldr是否并行处理多个INFILE

php - 我需要帮助更新特定用户的 sql 条目

oracle - 如何将数据从一个数据库/表复制到另一个数据库/表

sql - 如何在HSQLDB中使用多行SELECT语句导出数据?

SQL 返回 2008 年第 13 周的结果(未分组)

oracle - 如何获取oracle中的日期部分

oracle - sql*plus 和 sql loader 的区别

sql - 从表中确定 "longest X streak"(SQL Server 2018)

mysql - 需要从两个字段中进行选择,第一个字段是唯一的,基于第二个字段的最高值