【问题标题】:Return value from SQL 2005 SP returns DBNULL - Where am I going wrong?SQL 2005 SP 的返回值返回 DBNULL - 我哪里出错了?
【发布时间】:2009-01-02 15:30:17
【问题描述】:

这是SP...

USE [EBDB]
GO
/****** Object:  StoredProcedure [dbo].[delete_treatment_category]    Script Date: 01/02/2009 15:18:12 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*
RETURNS 0 FOR SUCESS
        1 FOR NO DELETE AS HAS ITEMS
        2 FOR DELETE ERROR
*/

ALTER PROCEDURE [dbo].[delete_treatment_category]
(
    @id INT
)
AS
    SET NOCOUNT ON

    IF EXISTS
    (
        SELECT id
        FROM dbo.treatment_item
        WHERE category_id = @id
    )
    BEGIN
        RETURN 1
    END 
    ELSE
    BEGIN
        BEGIN TRY
            DELETE FROM dbo.treatment_category
            WHERE id = @id
        END TRY

        BEGIN CATCH
            RETURN 2
        END CATCH 

        RETURN 0                        
    END

我正在尝试使用以下代码(VB .NET 中的 sqlDataSource 和 Gridview 组合)获取返回值

Protected Sub dsTreatmentCats_Deleted(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.SqlDataSourceStatusEventArgs) Handles dsTreatmentCats.Deleted
    Select Case CInt(e.Command.Parameters(0).Value)
    Case 0
        'it worked so no action
        lblError.Visible = False
    Case 1
        lblError.Text = "Unable to delete this category because it still has treatments associated with it."
        lblError.Visible = True
    Case 2
        lblError.Text = "Unable to delete this category due to an unexpected error. Please try again later."
        lblError.Visible = True
End Select
End Sub

问题在于 CInt(e.Command.Parameters(0).Value) 行返回 DBNull 而不是返回值,但仅在删除时 - 这种方法适用于更新和插入。

希望我只是有点密集并且错过了一些明显的东西 - 有什么想法吗?

编辑

我仍然遇到此问题,并且尝试了以下所有选项均无济于事 - 我很惊讶没有其他人遇到此问题?

添加参数的代码:

<asp:SqlDataSource ID="dsTreatmentCats" runat="server" 
        ConnectionString="<%$ ConnectionStrings:EBDB %>" 
        DeleteCommand="delete_treatment_category" DeleteCommandType="StoredProcedure" 
        InsertCommand="add_treatment_category" InsertCommandType="StoredProcedure" 
        SelectCommand="get_treatment_categories" SelectCommandType="StoredProcedure" 
        UpdateCommand="update_treatment_category" 
        UpdateCommandType="StoredProcedure" ProviderName="System.Data.SqlClient">

    <DeleteParameters>
        <asp:Parameter Direction="ReturnValue" Name="RetVal" Type="Int32" />
        <asp:Parameter Name="id" Type="Int32" />
    </DeleteParameters>
    <UpdateParameters>
        <asp:Parameter Direction="ReturnValue" Name="RetVal" Type="Int32" />
        <asp:Parameter Name="id" Type="Int32" />
        <asp:Parameter Name="name" Type="String" />
        <asp:Parameter Name="additional_info" Type="String" />
    </UpdateParameters>
    <InsertParameters>
        <asp:Parameter Direction="ReturnValue" Name="RetVal" Type="Int32" />
        <asp:ControlParameter ControlID="txtCat" Name="name" PropertyName="Text" 
            Type="String" />
        <asp:ControlParameter ControlID="txtAddInfo" Name="additional_info" 
            PropertyName="Text" Type="String" />
    </InsertParameters>
</asp:SqlDataSource>

【问题讨论】:

    标签: asp.net sql vb.net tsql sql-server-2005


    【解决方案1】:

    我在这里玩游戏有点晚了,但为了那些偶然发现这个问题的人......

    如果您在 ADO.Net 中使用 ExecuteReader,则在您关闭 Reader 或与数据库的底层连接之前,不会填充返回值。 (See here)

    这不起作用:

    SqlConnection conn = new SqlConnection(myConnectionString);
     SqlCommand cmd = new SqlCommand(mySqlCommand, conn);
    
     //     Set up your command and parameters
    
     cmd.Parameters.Add("@Return", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;
    
     SqlDataReader reader = cmd.ExecuteReader();
     while (reader.Read())
     {
           //     Read your data
     }
    
     int resultCount = (int)cmd.Parameters["@Return"].Value;
     conn.Close();
     return resultCount;
    

    这将:

    SqlConnection conn = new SqlConnection(myConnectionString);
     SqlCommand cmd = new SqlCommand(mySqlCommand, conn);
    
     //     Set up your command and parameters
    
     cmd.Parameters.Add("@Return", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;
    
     SqlDataReader reader = cmd.ExecuteReader();
     while (reader.Read())
     {
           //     Read your data
     }
    
     conn.Close();
     int resultCount = (int)cmd.Parameters["@Return"].Value;
     return resultCount;
    

    【讨论】:

    • 这如何适用于发帖者的问题,鉴于在他的情况下,没有可以关闭的连接对象? (我遇到了同样的问题。)
    【解决方案2】:

    添加参数时,是否将方向设置为ReturnValue

    【讨论】:

      【解决方案3】:

      是的,我做到了 - 我正在使用 sqlDataSource 控件,它为我嗅出参数,包括具有正确方向设置的返回值。只是为了好玩,我也确实从头开始创建了带有 return val 方向的参数,但没有乐趣:(

      【讨论】:

        【解决方案4】:

        在 SQL 工具中运行它以确保存储的过程按预期运行。

        DECLARE @rtn int;
        EXEC @rtn = dbo.delete_treatment_category /*insert valid id here > 2*/;
        SELECT @rtn;
        

        我提到“一个 id > 2”是因为您可能读取了错误的参数。 也就是说,这个存储过程有 2 个参数……一个用于 id,另一个用于返回值。

        IIRC:

        cmd.CommandType = CommandType.StoredProcedure 'cmd is SqlCommand
        
        Dim retValParam as New SqlParameter("@RETURN_VALUE", SqlDbType.Int)
        retValParam.Direction = ParameterDirection.ReturnValue
        cmd.Parameters.Add(retValParam)
        
        'add the ID parameter here
        
        'execute
        
        'look at the @RETURN_VALUE parameter here
        

        【讨论】:

        • 我检查了管理工作室中的 SP,它返回了正确的返回码。此外,我正在挑衅地查看正确的参数,因为当我在上述事件中检查参数的名称时,它被称为 @RETURN_VALUE 但它的值是 DBNUll
        • 正如Mark Brittingham所说,为什么客户端代码中delete的参数名称不同?
        【解决方案5】:

        您不会在添加参数和执行命令的位置显示代码。两者都可能很关键。

        我知道重现这种情况的一种方法 - 如果您的过程还返回行(例如,从 DELETE 触发器),并且您没有使用这些行...基本上,输出/返回参数值如下 TDS 流中的网格,所以如果您还没有读取网格(使用 ExecuteReader 时) - 那么您将无法获得更新的参数/返回值。但如果您使用的是ExecuteNonQuery,这不应该是一个因素。

        【讨论】:

          【解决方案6】:

          为什么对 Delete 参数使用 Name="RETURN_VALUE" 而对 Update 和 Insert 使用 Name="RetVal"?如果后两者有效,那是我要看的第一个地方。

          【讨论】:

          • 这只是我使用的最新值 - 它最初是 RetVal(我的名字),但在检查 Deleted 事件中的参数时,它有一个系统生成的 RETURN_VALUE 名称。不幸的是,它们都不起作用 - 参数在那里并命名为 RETURN_VALUE 但值为 DBNull
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-28
          • 1970-01-01
          • 2014-02-26
          • 2021-12-10
          相关资源
          最近更新 更多