循环子程序和局部变量的Windows批处理

循环子程序和局部变量的Windows批处理,windows,batch-file,Windows,Batch File,在工作中,我们使用Windows批处理文件通过调度工具运行作业。这是一个旧的工具和方法,但它是有效的。我必须让新工作适应现有技术 对于这个特殊的工作,我需要从文件夹中提取一些文件,并将它们加载到SQLServer数据库表中。对于我加载的每个表,我需要运行一点SQL来更新最近填充的表 所以我有一个for循环来查找文件夹中的文件。如果存在,我将使用SQL server的BCP将数据加载到表中。然后,我使用SQLServer的SQLCMD执行更新 该策略是在使用BCP或SQLCMD将任何问题写入文件时

在工作中,我们使用Windows批处理文件通过调度工具运行作业。这是一个旧的工具和方法,但它是有效的。我必须让新工作适应现有技术

对于这个特殊的工作,我需要从文件夹中提取一些文件,并将它们加载到SQLServer数据库表中。对于我加载的每个表,我需要运行一点SQL来更新最近填充的表

所以我有一个for循环来查找文件夹中的文件。如果存在,我将使用SQL server的BCP将数据加载到表中。然后,我使用SQLServer的SQLCMD执行更新

该策略是在使用BCP或SQLCMD将任何问题写入文件时使用的。通话结束后,我们会检查这些文件,确保没有任何问题

当处理单个文件时,这是相当简单的事情。事实证明,使用FOR循环是不可能的

我设想调用一个子例程,该例程将设置一个变量,for循环中的代码可以检查该变量,如果合适,可以优雅地退出

我们在批处理文件中要做的第一件事是将全局变量设置为0。当批处理作业将控制权返回给“调度程序”时,如果该值不等于0,则作业显示为失败

因此,对代码的解释如下所示

SET g_status=0
SET LOCAL EnableDelayedExpansion
FOR n = 1 to 12
   IF FILE(n) EXISTS (
      Execute BCP....
      Execute SQLCMD....
      CALL check_sql_status
      IF !l_error_status! NEQ 0 ENDLOCAL & SET g_status=!l_error_status!
      IF g_status NEQ 0 GOTO exit_gracefully
      )
NEXT
.
.
GOTO END
REM ========
:check_sql_status
REM======
IF something is wrong (
   SET l_error_status=123

GOTO EOF

REM ========
:exit_gracefully
REM======
ECHO g_status

:End
.
.
不要被上面的“代码”挂断。这只是我尝试将局部变量传递回我感兴趣的全局变量的地方。无论我尝试什么,我都无法让全局变量接受子程序中设置的值


尽管BCP和SQLCMD使用了大量的参数,这些参数可能会混淆而不是帮助,但我会尝试找到这个问题,并在回去工作时发布一些实际的代码。

也许我的知识不足,但我认为这对于for循环或
如果文件(n)存在,这是无效的语法。如果不发布真实代码,很难判断发生了什么。如果出现问题,
sqlcmd
是否退出非零?如果是这样,您可以在这里使用&(成功代码块)| |(失败代码块)
执行
sqlcmd参数。或者您可以
sqlcmd args
然后
如果错误级别1(出现错误)
或类似错误。此外,您正在查找的
for
循环是
for/L%%I in(开始、步骤、结束)
如果存在“文件(%I)”
。在cmd控制台中,
for/?
if/?
获取更多信息。如前所述。。。当您发布psuedo代码时,很难找出代码的错误。一个严重的问题是l_error_状态未初始化。它可能是未定义的,这取决于子程序中发生的情况。。。缺少结束参数。最可能的原因是子例程正在cmd.exe的子实例中运行,该子实例无法在父实例中设置变量。但是如果没有看到一些真正的代码,我们就无法告诉您为什么或者如何最好地修复它。(然而,我冒昧地猜测你不恰当地使用了括号。)我投票结束这个问题。在发布实际代码之前,我们只能猜测问题可能是什么。