无法将用户定义的Sql RAISERROR(...)冒充到c#exception

时间:2016-10-28 02:17:09

标签: sql-server-2008 c#-4.0

无法将用户定义的Sql RAISERROR(...)冒充为c#例外 证据或线索:Sql生成的错误冒泡到c#,但是Sql用户定义的错误不会冒泡到c#。两者都记录在sql server日志中。

EXEC sp_addmessage   
@msgnum = 50001,   
@severity = 16,  
@msgtext =   N'This is a user defined error message test_2_sp',
@lang = 'us_english';  
DECLARE @FirstNum int = 1
DECLARE @SecondNum int = 0
DECLARE @RowCount int
BEGIN TRY

   --SELECT @FirstNum / @SecondNum -- This sql error (not user defined) always comes through by itself with out try ... catch

   SELECT @FirstNum + @SecondNum as Result
   WHERE @FirstNum = 0 --Un-comment me and watch the error come and go???

   --SET @RowCount = @@ROWCOUNT
   --SELECT @RowCount AS '@RowCount' -- to see @@ROWCOUNT in SSMS

   --RAISERROR('OutSide', 16, 1) WITH Log;

   IF @@ROWCOUNT = 0
        RAISERROR (50001, -1,-1) WITH Log; --https://msdn.microsoft.com/en-us/library/ms178592.aspx

END TRY
BEGIN CATCH
    declare @ErrorMessage nvarchar(max), @ErrorSeverity int, @ErrorState int;
    select @ErrorMessage = ERROR_MESSAGE() + ' LineNo ' + cast(ERROR_LINE() as nvarchar(5)), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE();

    raiserror (@ErrorMessage, @ErrorSeverity, @ErrorState) WITH Log;

END CATCH 
EXEC sp_dropmessage 50001, 'all'; 
END

C#

protected void Page_Load(object sender, EventArgs e)
    {
        string ConnectionStringName = "SQLUTLtest";
        //string con = @"Data...";
        SqlConnection sqlcon = new SqlConnection(ConfigurationManager.ConnectionStrings[ConnectionStringName].ToString());

        using (SqlCommand cmd = new SqlCommand("Test_2_Sp", sqlcon))
        {
            cmd.CommandType = CommandType.StoredProcedure;

            sqlcon.Open();

            try
            {
                SqlDataAdapter adp = new SqlDataAdapter(cmd);

                DataTable dt = new DataTable();
                adp.Fill(dt);
                Response.Write("Hello");
            }
            catch(Exception ex)
            {
                Response.Write(ex.Message);
            }
            finally
            {
                Response.Write("</br>finally");
            }
        }

    }

1 个答案:

答案 0 :(得分:0)

与EE(https://www.experts-exchange.com/questions/28979394/Bubble-user-defined-Sql-RAISERROR-to-c-exception.html)分享相同的回复:

我认为代码也无法捕获SQL标准异常。例如,如果我在执行添加后添加SELECT 1/0(临界除以零错误),代码将继续填充数据表而不会捕获异常。

您可以将C#代码更新为以下内容吗?基本上,我不是只填充DataTable,而是首先尝试获取DataSet。如果已生成异常,则会失败。 (我在WinForms应用程序上尝试了这个,因此MessageBoxes。请求您根据需要更新代码。)

        using (SqlCommand mySqlCommand = new SqlCommand("Test_2_Sp", myCustomConnection))
        {
            mySqlCommand.CommandType = CommandType.StoredProcedure;
            mySqlCommand.Parameters.AddWithValue("@firstnum", "1");
            mySqlCommand.Parameters.AddWithValue("@secondnum", "0");

            myCustomConnection.Open();

            try
            {
                SqlDataAdapter adp = new SqlDataAdapter(mySqlCommand);

                DataSet myDataSet = new DataSet();
                adp.Fill(myDataSet);

                if (myDataSet.Tables.Count > 0)
                {
                    DataTable dt = myDataSet.Tables[0];
                }

                MessageBox.Show("Hello World!");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ouch!");
            }
            finally
            {
                MessageBox.Show("Good Bye!");
            }
        }