Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 调用有错误的存储过程,继续并获取完整输出_C#_Sql Server_Stored Procedures_Error Handling_Output - Fatal编程技术网

C# 调用有错误的存储过程,继续并获取完整输出

C# 调用有错误的存储过程,继续并获取完整输出,c#,sql-server,stored-procedures,error-handling,output,C#,Sql Server,Stored Procedures,Error Handling,Output,我想从C#应用程序调用SQL Server SP() 如果在任何数据库中发现任何损坏,将抛出(多个)错误 在SSMS内执行的打印输出包含一个信息丰富的累积输出(日志条目与错误消息混合)。每次错误后,执行都会继续。在SSMS中,您可以使用“输出到文件”来获取包含此内容的文件 从C#开始,我尝试使用cmd.ExecuteNonQuery(),它可以工作,但在第一个错误时就中断了 是否有任何方法可以从C#调用SP而不中断错误,从而最终获得完整的输出 编辑: 为了测试这一点,我找到了一个准备好的已损坏的

我想从C#应用程序调用SQL Server SP()

如果在任何数据库中发现任何损坏,将抛出(多个)错误

在SSMS内执行的
打印
输出包含一个信息丰富的累积输出(日志条目与错误消息混合)。每次错误后,执行都会继续。在SSMS中,您可以使用“输出到文件”来获取包含此内容的文件

从C#开始,我尝试使用
cmd.ExecuteNonQuery()
,它可以工作,但在第一个错误时就中断了

是否有任何方法可以从C#调用SP而不中断错误,从而最终获得完整的输出

编辑: 为了测试这一点,我找到了一个准备好的已损坏的数据库以供下载()

试试这个

CREATE PROCEDURE dbo.test
AS
BEGIN
    PRINT 'a clean db'
    DBCC CHECKDB (someDb) WITH NO_INFOMSGS;
    PRINT 'a bad db'
    DBCC CHECKDB (SomeCorruptDB) WITH NO_INFOMSGS
    PRINT 'one more clean db'
    DBCC CHECKDB (AotherGoodDB) WITH NO_INFOMSGS
END 
GO
EXEC dbo.test;
GO
DROP PROCEDURE dbo.test;
GO
错误消息来自
DBCC CHECKDB
中。SP执行到最后一行

更新 大家好
谢谢你调查此事。进一步的测试表明,C#中抛出的SQL异常已经将所有信息打包在了里面。我被明显的第一个陷阱弄瞎了眼睛。 潜入其中,我发现我的SP实际上被执行到了最后。
SqlException
具有一个
.Errors
属性,该属性反映了找到的所有错误。 还有很多工作要做,但问题解决了。
谢谢你的帮助

尝试在SQL脚本中标识这些部分,并对每个部分使用try-catch,将第一个部分放入try-catch,然后在每个catch块中收集错误信息,在第一个try-catch结束后,在SP中的另一个try-catch块中启动下一个部分

您可以使用以下代码示例来尝试此操作

-- First part of your code
BEGIN TRY
  -- your first code part
  PRINT 0 / 0
END TRY
BEGIN CATCH
  -- collect error information
  -- dont thro error jist collect the information to a variable
  PRINT ERROR_MESSAGE()
END CATCH

-- start next part identified part
BEGIN TRY
  -- your first code part
  PRINT
  2
END TRY
BEGIN CATCH
  -- collect error information
  -- dont thro error jist collect the information to a variable
  PRINT ERROR_MESSAGE()
END CATCH

cmd.ExecuteNonQuery()
的错误是什么? 我认为这与SSMS中的“抛出”错误不同。最有可能的原因是SP在C#中中断


据我所知,SP只是在出现错误(损坏)时返回错误(可能是字符串)。这并不是真正抛出错误,因为它只是按照您的描述继续进行。

PRINT
语句结果和其他信息/警告消息需要一个InfoMessage事件处理程序:

static void test()
{
    try
    {
        var connection = new SqlConnection(connectionString);
        connection.InfoMessage += Connection_InfoMessage;
        var command = new SqlCommand("dbo.test", connection) { CommandType = CommandType.StoredProcedure };
        connection.Open();
        command.ExecuteNonQuery();
    }
    catch (SqlException ex)
    {
        Console.WriteLine(ex.Message);
    }
    Console.ReadLine();
}

private static void Connection_InfoMessage(object sender, SqlInfoMessageEventArgs e)
{
    Console.WriteLine(e.Message);
}

您还可以设置
connection.FireInfoMessageEventOnUserErrors=true
,这样错误也会作为信息消息返回,而不是作为异常引发。这就是SSMS所做的。请注意,在这种情况下,应用程序代码有责任以不同于信息错误的方式处理真实错误,因为不会针对这些错误引发SqlException。

如果您想继续,但要获得sql中处理的异常的详细分析,则需要捕获sql异常

已更新

错误抛出过程示例:

create proc ErrorThrower
as
RAISERROR (N'There was a problem', 15, 1);  
RAISERROR (N'There was a 2nd problem', 15, 1); 
GO
以及一个简单的控制台应用程序,用于建立ADO.NET连接并处理故障:

using System.Data.SqlClient;

static void Main(string[] args)
    {
      var server = ".";
      var database = "tester";

      var connection = $"Server ={server};Database={database};Trusted_Connection=True;";

      var listOfErrors = new List<SqlError>();

      using (SqlConnection cn = new SqlConnection(connection))
      using (SqlCommand cmd = new SqlCommand("exec ErrorThrower", cn))
      {
        cn.Open();

        //handles ONLY SQL Exceptions
        try
        {
          cmd.ExecuteNonQuery();
        }
        catch (SqlException sqlException)
        {
          //Do what you want in your program with the failure of SQL.  I am just echoing it for example purposes, I could log it or do more with it.
          foreach(SqlError error in sqlException.Errors)
          {
             listOfErrors.Add(error);
          }

          Console.WriteLine($"There were {listOfErrors.Count} errors executing");
          listOfErrors.ForEach(x => Console.WriteLine($"\tError was {x.Message}"));
        }

        cn.Close();
      }

      Console.ReadLine();
    }
使用System.Data.SqlClient;
静态void Main(字符串[]参数)
{
var server=“.”;
var database=“tester”;
var connection=$“Server={Server};Database={Database};Trusted_connection=True;”;
var listOfErrors=新列表();
使用(SqlConnection cn=新的SqlConnection(连接))
使用(SqlCommand cmd=newsqlcommand(“exec ErrorThrower”,cn))
{
cn.Open();
//仅处理SQL异常
尝试
{
cmd.ExecuteNonQuery();
}
捕获(SqlException SqlException)
{
//在SQL失败的情况下,在你的程序中做你想做的事情。我只是为了举例的目的而重复它,我可以记录它或者用它做更多的事情。
foreach(sqlException.Errors中的SqlError错误)
{
添加错误列表(错误);
}
WriteLine($“执行了{listOfErrors.Count}个错误”);
ForEach(x=>Console.WriteLine($“\tError was{x.Message}”);
}
cn.Close();
}
Console.ReadLine();
}

你所说的“第一个错误时中断”是什么意思?@DavidG,C#应用程序在
cmd.ExecuteNonQuery
上抛出一个错误,这似乎是发生的第一个错误。SP的其余部分不执行。我需要一个一直执行到最后一行的执行,收集所有输出,让我分析一下(与SSMS中的输出类似)您是说SP在手动运行时会在错误后继续运行吗?因为我很确定这不会发生。@DavidG请参阅我的编辑我知道
T-SQL中的
TRY/CATCH
。。。这些错误是从DBCC CHECKDB中抛出的。我不能改变这个不幸…我只是添加了一个更新,问题解决了。。。Thx用于提示
InfoMessage
。我将立即深入讨论:-)@Shnugo,是的,添加处理程序来记录Ola脚本返回的所有消息可能是个好主意。嗨,我接受了这个,因为它正指向我刚刚找到的解决方案。虽然这并不是解决多个错误的问题,但它实际上是解决方案(请参阅我的更新部分)。显然,还需要处理DBCC和其他子进程之类的冒泡错误集合。有关集合处理例程,请参见更新的示例。