【问题标题】:How can I capture a SQL Stored Procedure Error triggered by RAISEERROR() in .asmx file?如何在 .asmx 文件中捕获由 RAISEERROR() 触发的 SQL 存储过程错误?
【发布时间】:2009-07-09 15:41:21
【问题描述】:

我是非常 .NET 新手。到目前为止,我所做的只是通过复制和粘贴现有代码(按照我的上级的指示)将一些 SQL 存储过程调用实现为 WebServices。

我正在通过Database.ExecuteNonQuery() 调用一些命令。在 SQL 存储过程中,我正在根据传入的 LoginId 执行一些安全检查(用户只能编辑他们是所有者的项目)。如果安全检查失败,我将调用 RAISEERROR() 来触发错误,但我的 .asmx 文件并未将此视为异常,而是直接退出存储过程。

我的 asmx 文件:

[WebMethod]
public XmlDocument UpdateSomeItem(Int32 ItemIdNmb, String Foo)
{
    try
    {

        // Create the Database object, using the default database service. The
        // default database service is determined through configuration.
        Database db = DatabaseFactory.CreateDatabase();
        DbParameter param;

        string sqlCommand = "updateSomeItem";
        DbCommand dbCommand = db.GetStoredProcCommand(sqlCommand);

        db.AddInParameter(dbCommand, "ItemIdNmb", DbType.Int32, ItemIdNmb);
        db.AddInParameter(dbCommand, "Foo", DbType.String, Foo);
        db.AddInParameter(dbCommand, "UpdateLoginIdNmb", DbType.Int32, SessionLoginIdNmb);

        #region Return Parameter
        param = dbCommand.CreateParameter();
        param.ParameterName = "Return";
        param.Direction = ParameterDirection.ReturnValue;
        param.DbType = DbType.Int32;

        dbCommand.Parameters.Add(param);
        #endregion

        // Execute the Command
        db.ExecuteNonQuery(dbCommand);

        myDataSet = new DataSet();

        myDataSet.DataSetName = "DataSet";
        myDataSet.Tables.Add(errorDataTable);

        statusDataRow["Status"] = "Success";
        statusDataTable.Rows.Add(statusDataRow);
        myDataSet.Tables.Add(statusDataTable);

        returncodeDataRow["ReturnCode"] = dbCommand.Parameters["Return"].Value;
        returncodeDataTable.Rows.Add(returncodeDataRow);
        myDataSet.Tables.Add(returncodeDataTable);

        xmlReturnDoc.LoadXml(myDataSet.GetXml());

        return xmlReturnDoc;
    }
    // THIS IS WHERE I WANT MY RAISE ERROR TO GO
    catch (Exception e) 
    {
        return ReturnClientError(e, "someerror");
    }
}

My SQL 存储过程:

CREATE PROCEDURE updateSomeItem
(
    @ItemIdNmb             INT,
    @Foo                   VARCHAR(100),
    @UpdateLoginIdNmb      INT
)

AS

SET NOCOUNT ON

/* If the user performing the action did not create the Item in question, 
    raise an error. */
IF NOT EXISTS
    (
    SELECT 1
    FROM Items
    WHERE IdNmb = @ItemIdNmb
        AND LoginIdNmb = @UpdateLoginIdNmb
    )
    RAISERROR (
        'User action not allowed - User is not the owner of the specified Item', 
        10, 
        1)

UPDATE Items
SET Foo = @Foo
WHERE IdNmb = @ItemIdNmb

RETURN 0

SET NOCOUNT OFF
GO

【问题讨论】:

    标签: .net sql stored-procedures asmx raiseerror


    【解决方案1】:

    问题是错误严重性太低了。严重性 1 - 10 被视为信息消息,不会中断 C# 应用程序的流程。

    可以在Remus Rusanuanswer 中找到更详尽的解释。

    【讨论】:

    • 谢谢@ahsteele。这是有道理的。我更改了逻辑以在我描述的条件下返回不同的代码,并在我的 C# 中处理返回代码(见下文)。
    【解决方案2】:

    我用以下内容更新了我的存储过程:

    /* If the user performing the action did not create the Item in question, 
        return a code other than 0. */
    IF NOT EXISTS
        (
        SELECT 1
        FROM Items
        WHERE IdNmb = @ItemIdNmb
            AND LoginIdNmb = @UpdateLoginIdNmb
        )
        RETURN 1
    

    我在我的 .asmx 文件中这样处理:

    int returnValue = (int)dbCommand.Parameters["Return"].Value;
    
    if (returnValue == 0)
        statusDataRow["Status"] = "Success";
    /* Stored Procedure will return a value of "1" if the user is 
        attempting to update an Item that they do not own. */
    else
        statusDataRow["Status"] = "Error";
    
    statusDataTable.Rows.Add(statusDataRow);
    myDataSet.Tables.Add(statusDataTable);
    
    returncodeDataRow["ReturnCode"] = dbCommand.Parameters["Return"].Value;
    returncodeDataTable.Rows.Add(returncodeDataRow);
    myDataSet.Tables.Add(returncodeDataTable);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-27
      • 2015-07-21
      • 1970-01-01
      • 1970-01-01
      • 2011-01-02
      • 2012-11-18
      • 2010-12-09
      相关资源
      最近更新 更多