如何通过 C# 从 "SQLCMD" 获取错误?

How to get error from "SQLCMD" through c#?

运行 SqlCmd 实用程序使用 C# 这样:

// Calls the sqlcmd                
ProcessStartInfo info = new ProcessStartInfo(
  "sqlcmd", 
 @" -S VDSS218 -i D:\Ravi\Blank_Database_Creation_script.sql");

info.UseShellExecute = false;
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
info.RedirectStandardOutput = true;

Process proc = new Process();

proc.StartInfo = info;
proc.Start();

现在,如果在 C# 运行 时脚本中发生任何错误,那么如何在 C# 中获取 SQL 异常。

监听事件:ErrorDataReceived

proc.ErrorDataReceived += new DataReceivedEventHandler(method);

在 MSDN 上查看完整示例:

https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.errordatareceived?view=netframework-4.7.2

首先声明一个class作为执行结果:

  public sealed class ExecutionSqlCmdResult {
    public  ExecutionSqlCmdResult(string stdOut, string stdErr, int exitCode)
      : base() {

      Out = string.IsNullOrWhiteSpace(stdOut) ? "" : stdOut;
      Error = string.IsNullOrWhiteSpace(stdErr) ? "" : stdErr;
      ExitCode = exitCode;
    }

    public string Out {
      get;
    }

    public string Error {
      get;
    }

    public int ExitCode {
      get;
    }
  }

然后我们可以把

  public static ExecutionSqlCmdResult ExecuteSqlCmd(string command) {
    ProcessStartInfo sqlCmdInfo = new ProcessStartInfo() {
      UseShellExecute = false,
      CreateNoWindow = true,
      WindowStyle = ProcessWindowStyle.Hidden,
      RedirectStandardError = true,
      RedirectStandardOutput = true,
      Arguments = command,
      FileName = "sqlcmd",
      StandardErrorEncoding = Encoding.UTF8,
      StandardOutputEncoding = Encoding.UTF8,
    };

    using (Process sqlCmdProcess = new Process()) {
      sqlCmdProcess.StartInfo = sqlCmdInfo;
      sqlCmdProcess.Start();

      StringBuilder sbOut = new StringBuilder();
      StringBuilder sbErr = new StringBuilder();

      sqlCmdProcess.OutputDataReceived += (sender, e) => {
        if (e.Data != null)
          sbOut.Append(e.Data);
      };

      sqlCmdProcess.ErrorDataReceived += (sender, e) => {
        if (e.Data != null)
          sbErr.Append(e.Data);
      };

      sqlCmdProcess.BeginErrorReadLine();
      sqlCmdProcess.BeginOutputReadLine();

      sqlCmdProcess.WaitForExit();

      return new ExecutionSqlCmdResult(sbOut.ToString(), sbErr.ToString(), sqlCmdProcess.ExitCode);
    }
  }

用法

var result = ExecuteSqlCmd(@" -S VDSS218 -i D:\Ravi\Blank_Database_Creation_script.sql");

//TODO: inspect result.Out, result.Error and result.ExitCode