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

fv2wmkja  于 2023-03-22  发布在  Oracle
关注(0)|答案(4)|浏览(136)

如何从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
)

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

4dc9hkyq

4dc9hkyq1#

从11 g开始,无法直接从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
fwzugrvs

fwzugrvs2#

我不认为有一种方法,在这种情况下,你指定,AFAIK没有办法正确引用文件名中的“数据”部分。
解决方案的几个想法:

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

INPUTFILE CONSTANT“my_data.dat”
希望这个有用。

t9aqgxwy

t9aqgxwy3#

解决这个问题的简单方法是在每个记录的末尾添加一个额外的列,并将该列的位置Map到字段。

x8diyxa7

x8diyxa74#

我知道这是超级旧的,但我仍然在2023年来到这里,仍然没有答案,所以我是这样做的。
我修改了我的.ctl文件以使用通用文件名作为输入:

INFILE '[path to data files]\myfile.dat'

然后,我创建了一个带有DO循环的批处理文件,以遍历所有数据文件名:

FOR %%X in ("[path to data files]\*.[your extension]") DO (
copy /Y %%~dpnX [path to batch files]\myfile.dat
[path to your batch file that runs sqlldr]\load_my_data.bat
)

我在大约10-15分钟内加载了1218个数据文件和125万多一点的行。

相关问题