Batch file SQL加载器-如何将数据文件作为变量传递?

Batch file SQL加载器-如何将数据文件作为变量传递?,batch-file,sql-loader,Batch File,Sql Loader,我有一个SQL加载器命令,我正在从批处理脚本调用该命令。数据文件名不是常量。每次生成和填充文件时,我们都会在其上附加一个时间戳。因此,我的批处理文件在变量Fname中获取此数据文件 SET Fname=dir C:\Temp\TEST_*.dat /b 现在,当从批处理文件运行Sqlldrcommmand时 sqlldr USERID=xyz/xyz@db CONTROL='C:\Temp\TEST.ctl' LOG='C:\Temp\TEST.log' DATA= %Fname% 我得到了

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

SET Fname=dir C:\Temp\TEST_*.dat /b
现在,当从批处理文件运行
Sqlldr
commmand时

sqlldr USERID=xyz/xyz@db CONTROL='C:\Temp\TEST.ctl' LOG='C:\Temp\TEST.log' DATA= %Fname%
我得到了错误

LRM-00112:参数“数据”不允许有多个值
我不能将变量
Fname
括在单引号中。这是行不通的

我查过了

如果我使用上述讨论中指定的方法,并将其作为infle
%Fname%
包含在ctl文件中,我仍然会得到错误,因为变量
Fname
显示为
dir C:\Temp\TEST.*.dat/b
,并且我会得到错误,表示未找到文件


如何解决此问题?

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

@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
一个可能更好的解决方案是根据上次修改日期始终使用文件夹
C:\Temp
中最新的
TEST.*.dat
文件执行命令

@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中的目录,但这是不可能的,因为批处理执行时不知道应用程序可执行文件的存储位置。

谢谢

我使用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
这起作用了

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