SQL LOADER - 如何将数据文件作为变量传递?

时间:2014-09-17 15:20:24

标签: batch-file sql-loader

我有一个SQL加载程序命令,我从批处理脚本调用它。数据文件名不是常量。每次生成和填充文件时,我们都会附加一个时间戳。因此,我的批处理文件将此数据文件放在变量Fname中。

SET Fname=dir C:\Temp\TEST_*.dat /b

现在,当Sqlldr命令从批处理文件

运行时
sqlldr USERID=xyz/xyz@db CONTROL='C:\Temp\TEST.ctl' LOG='C:\Temp\TEST.log' DATA= %Fname%

我收到错误

LRM-00112: multiple values not allowed for parameter 'data'

我无法将变量Fname括在单引号中。这不起作用。

我查看了How can I use a variable in batch script at sqlldr?

如果我使用上面讨论中指定的方法并将其作为 infile %Fname%包含在ctl文件中,我仍然会收到错误,因为变量Fname显示为{ {1}}我收到错误,说找不到文件。

如何解决此问题?

2 个答案:

答案 0 :(得分:1)

下面的简单解决方案始终使用文件夹TEST_*.dat中的第一个C:\Temp文件执行命令。

@echo off
for %%F in ("C:\Temp\TEST_*.dat") do (
    sqlldr USERID=xyz/xyz@db CONTROL='C:\Temp\TEST.ctl' LOG='C:\Temp\TEST.log' "DATA=%%F"
    goto AfterLoop
)
:AfterLoop

一个或许更好的解决方案是根据最后修改日期始终使用文件夹TEST_*.dat中找到的最新C:\Temp文件执行命令。

@echo off
for /F "delims=" %%F in ('dir "C:\Temp\TEST_*.dat" /B /O-D /TW 2^>nul') do (
    sqlldr USERID=xyz/xyz@db CONTROL='C:\Temp\TEST.ctl' LOG='C:\Temp\TEST.log' "DATA=%%F"
    goto AfterLoop
)
:AfterLoop

可以将找到的文件的名称分配给FOR循环内的环境变量,并运行AfterLoop下面的命令。但这需要额外的代码来检查文件夹中是否找到至少1个文件。

这些批处理代码段是使用帮助信息输出开发的,方法是在命令提示符窗口for /?dir /?中运行。

2^>nul正在将命令dir的错误输出重定向到设备NUL,如果在文件夹中找不到文件以禁止此特殊用例的不需要的错误消息。

我的最后提示:

在批处理文件中,始终指定要使用完整路径和文件扩展名运行的应用程序(如果是路径/文件名中的空格,则使用双引号),以避免依赖于环境变量 PATH 中的目录,除了这是不可能,因为批处理执行时不知道应用程序可执行文件的存储位置。

答案 1 :(得分:0)

谢谢。

我使用了for循环代码

@echo off
for %%F in ("C:\Temp\TEST_*.dat") do (
    sqlldr USERID=xyz/xyz@db CONTROL='C:\Temp\TEST.ctl' LOG='C:\Temp\TEST.log' "DATA=%%F"
    goto AfterLoop
)
:AfterLoop

这很有用。

我没有多个文件的问题,因为我每次加载它后,我将文件移动到另一个文件夹。所以在任何给定的点上我都希望只有一个文件。