3

我是这个论坛的新手,但请多多包涵。我有 ac# Windows 表单,上面有两个复选框,一个称为 chkThrowError,另一个称为 chkDivideError,两者均未选中。这些控件纯粹是为了控制存储过程的执行。我有一个带有以下代码的命令按钮:

private void cmdError_Click(object sender, EventArgs e)
    {
        int ThrowError = 0;
        int DividByZero = 0;
        if (chkThrowError.Checked)
        {
            ThrowError = 1;
        }
        if (chkDivideError.Checked)
        {
            DividByZero = 1;
        }
        try
        {
            clsBBFinances.TestError(ThrowError,DividByZero);
            MessageBox.Show("Everything is Hunkey Dorey");

        }
        catch (Exception Ex)
        {
            MessageBox.Show(Ex.Message);
        }
    }

clsBBFinances 是我的业务对象,TestError 例程如下:

public static void TestError(int ThrowError, int ThrowDivideError)
    {
        System.Data.SqlClient.SqlDataReader objRs = null;
        string strsql = "";
        bool Success = true;
        string ErrMsg = "";
        int intCount = 0;
        try
        {
            strsql = strsql + "Exec ";
            strsql = strsql + "TestError " + ThrowError.ToString() + " , " + ThrowDivideError.ToString();
            objRs = clsBBFinances.TheDatabase.ExecuteReadOnly(strsql);
            while (objRs.Read())
            {
                intCount++;
                object xxx = objRs[0];

            }
            Success = true;
            ErrMsg = "";
            //intCount = objRs.RecordsAffected;



        }
        catch (Exception ex)
        {
            ErrMsg = ex.Message;
            intCount = 0;
            Success = false;
            throw ex;
        }
        finally
        {
            if (objRs != null)
            {
                if (!objRs.IsClosed)
                {
                    objRs.Close();
                }
            }
        }

    }

请假设语法正确并且我有一个有效的 SQL 连接 (sql2008(R2))

这基本上调用了以下存储过程:

Create PROCEDURE TestError 
(@ThrowError int=0
 ,@ThrowDivideError int= 0
 )
AS
BEGIN

SET NOCOUNT ON;
Declare @x int
Declare @y int

Declare @ErrorNumber int
Declare @ErrorMessage varchar(2000)
Declare @ErrorSeverity int
Declare @ErrorState int
Begin Try

    If isnull(@ThrowError,0) <>   0
    Begin
            RaisError ('Forced Error Raised',16,1)
            Return
    End
    If isnull(@ThrowDivideError,0) <>0
    Begin
          set @x = 5
          Set @y =0
          Select @x/@y as z
    End

End Try
Begin catch
    Select @ErrorNumber = Error_Number()
           ,@ErrorMessage = 'Test Error ' + Error_message()
           ,@Errorseverity= Error_Severity()
           ,@ErrorState = Error_State()

    RaisError (@Errormessage, @ErrorSeverity, @ErrorState)
    --THROW 51000, @Errormessage, @ErrorState;
    Return

End Catch
Select * from   information_Schema.tables





END
GO

基本上,我根据传入的参数引发了一个错误。如果我的第一个参数不为零,我会引发一个自定义错误,如果第一个是 0,第二个是非零,那么我执行除以零来生成我系统错误。如果两者都为零,我会从 Information_Schema.tables 中进行简单的选择,只是为了完成它。存储过程的目的是调用 MY 错误和系统错误。

当我调用该过程并且我的第一个参数设置为 1 时,会引发我的自定义错误,该错误会通过 SQl catch 块并随后被困在我的 c# 中的 catch 块中。

但是,当我在第二个参数设置为 1 的情况下执行它时,除以零错误被捕获在 SQL catch 块中,但它没有被 c# 中的 catch 块捕获。代码继续,好像没有发生错误一样。

我希望能够捕捉到第二个错误。有谁知道如何。请随意粘贴上面的代码并自己尝试。

强制错误我收到消息Test Error Forced Error Raised

除以零我得到消息Everything is Hunkey Dorey,事实并非如此。

请帮助

4

1 回答 1

5

您正在使用 SqlDataReader,它一次只读取一个结果集。异常发生在第二个结果集中。因此,您必须使用 NextResult() 将阅读器移至第二个结果集。然后你遇到了异常......

        var connection = new SqlConnection("Data Source=xxx;Initial Catalog=Test;User Id=xxx;Password=xxx");
        connection.Open();

        try
        {
            SqlCommand command = new SqlCommand();
            command.Connection = connection;
            command.CommandType = CommandType.StoredProcedure;
            command.CommandText = "TestError";
            command.Parameters.AddWithValue("@ThrowDivideError", 1);
            var reader = command.ExecuteReader(CommandBehavior.CloseConnection);
            reader.Read();
            reader.NextResult();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }

        Console.ReadLine();
于 2013-04-16T20:29:54.883 回答