sqlcmd错误级别返回异常:VB.NET调用cmd时异常及命令拼接疑问
问题分析与解决方案
首先,你的命令拼接确实存在问题——使用管道符|是错误的选择,这也是导致你在VB.NET中无法正确获取sqlcmd错误级别的核心原因。
为什么管道符不行?
管道符|会将前一个命令(sqlcmd)的输出作为后一个命令(echo)的输入,而且管道两侧的命令会在独立的子进程中运行。这意味着你echo %%ERRORLEVEL%%获取到的并不是sqlcmd执行后的错误级别,而是管道自身或者echo命令的错误级别(通常是0,因为echo本身没出错),这就解释了为什么VB.NET里得到的是0。
正确的命令拼接方式
你需要用命令分隔符来让两个命令按顺序执行,这样第二个命令才能获取到sqlcmd执行后的ERRORLEVEL。常用的分隔符有:
&:不管前一个命令成功与否,都执行后一个命令&&:只有前一个命令成功(ERRORLEVEL=0)时,才执行后一个命令;如果前一个失败,直接跳过(不过你需要获取错误级别,所以用&更合适)
修正后的strCmdText1应该是这样的:
Dim strCmdText1 As String strCmdText1 = "/C sqlcmd -S CD05\SQLEXPRESS2005 -E -b -d AUTO_UPDATION -i H:\Temp1\537-2.sql -o H:\Temp1\Result.txt & echo %%ERRORLEVEL%%>H:\Temp1\errorlevel.txt" System.Diagnostics.Process.Start("CMD.exe", strCmdText1)
更可靠的替代方案:直接获取进程退出码
其实你完全不需要写入文件来获取错误级别,VB.NET的Process对象本身就能直接获取子进程的退出码,这样更高效也更不容易出错:
Dim processStartInfo As New System.Diagnostics.ProcessStartInfo() processStartInfo.FileName = "sqlcmd.exe" processStartInfo.Arguments = "-S CD05\SQLEXPRESS2005 -E -b -d AUTO_UPDATION -i H:\Temp1\537-2.sql -o H:\Temp1\Result.txt" processStartInfo.UseShellExecute = False processStartInfo.CreateNoWindow = True Dim process As System.Diagnostics.Process = System.Diagnostics.Process.Start(processStartInfo) process.WaitForExit() ' 等待命令执行完成 Dim exitCode As Integer = process.ExitCode ' 这里直接获取sqlcmd的错误级别 ' 如果你还是需要写入文件的话 System.IO.File.WriteAllText("H:\Temp1\errorlevel.txt", exitCode.ToString())
这个方案跳过了cmd.exe的中间层,直接调用sqlcmd,能准确获取它的退出码,避免了cmd命令拼接的各种坑。
额外注意点
- 确保你的VB.NET程序有足够的权限读写
H:\Temp1目录,否则写入文件会失败 -b参数是必须的,它让sqlcmd在执行出错时返回非0的错误级别,没有这个参数的话sqlcmd不管成功失败都会返回0
内容的提问来源于stack exchange,提问作者Jeseentha Francis
相关产品推荐
相关产品推荐

