Windows 批处理文件的错误处理&;Sqlcmd

Windows 批处理文件的错误处理&;Sqlcmd,windows,error-handling,batch-file,sqlcmd,Windows,Error Handling,Batch File,Sqlcmd,我有一个批处理文件,它使用sqlcmd运行一些SELECT查询,将结果放入文本文件,然后将这些文件上载到FTP服务器。这一切都是按它应该的方式进行的,这就是我喜欢的工作方式 不过,我一直在想万一发生错误我会怎么做。假设有人更改了我正在访问的数据库的数据结构,但没有通知我。如果我运行一个sqlcmd SELECT语句并将结果放入一个文本文件中,我只会得到一个包含错误的文本文件,该文件将直接转到FTP,就好像没有任何错误一样。(我已经测试过了。) 我希望能够检查来自sqlcmd的错误——超时、错误的

我有一个批处理文件,它使用sqlcmd运行一些SELECT查询,将结果放入文本文件,然后将这些文件上载到FTP服务器。这一切都是按它应该的方式进行的,这就是我喜欢的工作方式

不过,我一直在想万一发生错误我会怎么做。假设有人更改了我正在访问的数据库的数据结构,但没有通知我。如果我运行一个sqlcmd SELECT语句并将结果放入一个文本文件中,我只会得到一个包含错误的文本文件,该文件将直接转到FTP,就好像没有任何错误一样。(我已经测试过了。)

我希望能够检查来自sqlcmd的错误——超时、错误的凭证、错误的查询等等,我只是不确定这是如何做到的,或者“最佳实践”是什么。我总是可以尝试对输出文本文件进行爬网,并搜索我认为可能发生的错误,但这是有问题的,原因有很多


任何人都有这方面的经验可以分享吗?

您可以检查从
SQLCMD
返回的
errorlevel
,查看它是否失败

    sqlcmd -b <yourscript>
    IF ERRORLEVEL 1 goto err_handler
    goto done
    :err_handler
    REM handle the error here

    :done 
    REM script completion code here
sqlcmd-b
如果错误级别1转到错误处理程序
好了
:err\u处理器
REM在这里处理错误
:完成
REM脚本完成代码在这里

我可能会先在SQL中输入返回值,如下所示:

DECLARE @IsBored bit = 1

... do work ...

SELECT 0 -- Success!
sqlcmd -b -S ServerName -E -d DbName -q "EXIT(EXEC dbo.YourProc)" 
       -o "C:\Logs\output.log" -u
您可以进一步使用TRY/CATCH块来捕获错误并返回错误代码。使用SQLCMD,您可以使用SQL中的返回代码作为应用程序的退出代码,如下所示:

DECLARE @IsBored bit = 1

... do work ...

SELECT 0 -- Success!
sqlcmd -b -S ServerName -E -d DbName -q "EXIT(EXEC dbo.YourProc)" 
       -o "C:\Logs\output.log" -u
如果您使用调度器之类的工具来管理SQLCMD调用,则可以根据SQLCMD返回的代码来执行操作。由于您只是使用批处理文件,我认为您可以这样做:

@ECHO OFF
sqlcmd -b -S ServerName -E -d DbName -q "EXIT(EXEC dbo.YourProc)" 
       -o "C:\Logs\output.log" -u
IF %ERRORLEVEL% NEQ 0 ECHO "Error"

祝你好运

我用python构建了一个小型语言来解决类似的问题。使用子流程库,您可以通过sqlcmd运行代码,然后获取输出和任何错误代码。在将输出放入文本文件之前对其进行解析,如有必要,请检查错误修复状态。这些状态可以修改代码或选项,然后通过sqlcmd重试发送它们。如果其他方法都失败了,就给人发电子邮件

当然,因为我是这样使用python的,所以我根本不需要sqlcmd,只使用odbc python库直接连接到数据库。如果发生灾难性故障,我可以回滚事务,以交互模式运行,或者通过命令文件等

不过那是一堆工作。对于更简单的错误检查,只需在管道中添加一个过滤器,比如grep或awk。或者使用flex推出自己的产品

for %%G in (*.sql) do (sqlcmd /S %sqlhost% /d %sqldbname% -E -b -i "%%G" >> output.txt if ERRORLEVEL 1 exit)

上面的代码将循环遍历文件夹中的所有*.sql。如果在任何脚本中遇到错误,错误将被记录在output.txt文件中,并将立即停止批处理过程。

请注意,您需要在SQLCMD调用中添加“-b”标志,以使其生成错误级别。至少是这样。@user910683-谢谢你的评论,我更新了答案以反映你的建议。我在Jenkins中使用sqlcmd.exe,但它不会将sql错误冒泡为作业失败。将-b开关与IF%ERRORLEVEL%NEQ 0一起使用回显“Error”,它会触发一封失败的电子邮件。荣誉