繁体   English   中英

SQL 服务器与错误类型如何处理不冲突

[英]SQL Server and how to handle the type of error without conflict

我使用 SQL Server 2008 和 ASP.NET C# 并且我有一个存储过程,它返回一些计算的行。

我想在执行该过程之前检查参数值,如果参数值错误,我想返回自定义错误消息。

在UI方面,我必须根据错误类型返回不同的文本并使用不同的window。 例子:

  • 参数值错误时出错。
  • 未处理的错误。

我目前在数据库中使用这种 SP,但我尝试使用 state 参数甚至严重性参数来识别错误类型。 但是我与返回与我的参数错误相同的 state 编号的未处理错误存在一些冲突,因此出现了错误的 window。 如果我使用严重性级别,我猜 SP 在某些情况下也可能返回具有相同严重性编号的错误。

我给你一个简单的例子,以便更好地了解:

CREATE PROCEDURE dbo.GetData
    @Date1 date,
    @Date2 date
AS
BEGIN

    -- check the parameters
    IF @Date2 < @Date1
    BEGIN
        RAISERROR(N'Date 2 cannot be less than Date 1', 16, 2); -- <= Here State 2
        return
    END

    -- process here...
    DECLARE @Table1 TABLE ( name nvarchar(50) NOT NULL)

    -- Supposing you have to insert a row with a NULL value
    INSERT INTO @Table1 VALUES (NULL);
    -- Thus, this query returns this error with the state 2 as well!
    --Msg 515, Level 16, State 2, Procedure GetData, Line 21
    --Cannot insert the value NULL into column 'name', table '@Table1'; column does not allow nulls. INSERT fails.

    SELECT 'Record 1';
    SELECT 'Record 2';
END

从 c# 开始:

List<string> data = new List<string>();

protected void Button1_Click(object sender, EventArgs e)
{
    string errorMessage = string.Empty;
    bool isErrorFromChecking = false;

    if (GetValues(ConfigurationManager.ConnectionStrings["TestConnectionString"].ConnectionString,
                new DateTime(2011, 01, 01), new DateTime(2011, 02, 01),
                ref isErrorFromChecking, ref errorMessage))
    {
        Label1.Text = data[0].ToString();
        return;
    }

    if (isErrorFromChecking)
    {
        Label1.Text = errorMessage;
        return;
    }
    Label1.Text = string.Format("Internal Error: {0}.", errorMessage);
}

private bool GetValues(string connectionString, DateTime date1, DateTime date2,
            ref bool isErrorFromChecking, ref string errorMessage)
{
    data = new List<string>();
    try
    {
        using (SqlConnection sqlCon = new SqlConnection(connectionString))
        {
            sqlCon.Open();
            SqlCommand sqlCmd = new SqlCommand();
            sqlCmd.Connection = sqlCon;
            sqlCmd.CommandType = CommandType.StoredProcedure;
            sqlCmd.CommandText = "dbo.GetData";

            sqlCmd.Parameters.AddWithValue("Date1", date1);
            sqlCmd.Parameters.AddWithValue("Date2", date2);

            SqlDataReader reader = sqlCmd.ExecuteReader();
            while (reader.Read())
            {
                data.Add(reader[0].ToString());
            }
            reader.Close();
            sqlCon.Close();
        }
    }
    catch (SqlException ex)
    {
        if (ex.State == 2)
        {
            isErrorFromChecking = true;
            errorMessage = ex.Message;
            return false;
        }
        isErrorFromChecking = false;
        errorMessage = ex.Message;
        return false;
    }
    catch (Exception ex)
    {
        isErrorFromChecking = false;
        errorMessage = ex.Message;
        return false;
    }

    return true;
}

在上面的代码中,日期是正确的,但程序没有返回消息“内部错误:……”,尽管 SP 有错误。

我有一些想法,但我只想知道你的观点和最好的方法。

谢谢。

根据此http://msdn.microsoft.com/en-us/library/ms178592.aspx ,当您自己提供消息字符串时,您将获得 50000 的消息 ID。 我想您可以在 C# 代码中对此进行测试。

或者,您可以在 SP 中指定一个 MsgID(值 > 50000),并根据客户端代码中的 MsgID 提供错误消息。

只需将逻辑一分为二。 我的意思是在一个存储过程中具有“参数检查”逻辑,在另一个 SP 中具有 rest。 在“检查”SP 中,使用 output 参数来获取您想要返回的任何代码或错误文本。

第二个 SP 也可以先调用 SP 以确保它不会收到错误数据。

然后 C# 应首先调用“检查”SP 并查看返回的内容。

替代方法是对错误条件使用 output 参数并返回空数据集。

CREATE PROCEDURE spTest (@param1 int,   @ErrorText varchar(50) OUTPUT )
AS
BEGIN
    SET @ErrorText = NULL
    IF @Param1 = 1 
    BEGIN
        SET @ErrorText = 'I really cant except 1 as a parameter'
        SELECT NULL as QueryPlaceholderCol
    END 
    ELSE
    BEGIN
        SELECT 3.141 AS QueryPlaceholderCol
    END
END

在 T-SQL 中进行测试:

DECLARE @ReturnedError VARCHAR(50)
EXEC spTest 1,@ReturnedError OUTPUT
SELECT CASE WHEN @ReturnedError IS NULL THEN 'Worked Fine' ELSE @ReturnedError END AS Outputs
EXEC spTest 1423,@ReturnedError OUTPUT
SELECT CASE WHEN @ReturnedError IS NULL THEN 'Worked Fine' ELSE @ReturnedError END AS Outputs

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM