2009-01-02 54 views
1

这是SP ...SQL 2005 SP的返回值返回DBNULL - 我在哪里出错?

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 

而且我尝试使用下面的代码(SqlDataSource的GridView的&组合在VB .NET

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而不是返回值,但只在删除时 - 这种方法适用于更新和插入。

希望我只是有点密集和h大家错过了明显的东西 - 任何想法?

编辑

我仍然有此问题,并已经尝试了所有的选项下面无济于事 - 我很惊讶,没有人有过这个问题吗?

代码添加参数:

<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> 

回答

3

我有点晚了这里的比赛,但对于在这个问题谁绊倒人着想...

如果你在使用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; 
1

当您添加的参数,你设定的方向ReturnValue

0

是的,我做了 - 我使用sqlDataSource控件,它为我嗅探了参数,包括带正确方向设置的返回值。只是为了好玩,确实也从头开始创建,返回VAL方向帕拉姆过,但没有喜悦:(

0

运行这在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 
+0

我检查Management Studio中的SP和它返回正确的返回代码。另外,我正在挑战正确的参数,因为当我在上面的事件中检查参数的名称时,它被称为@RETURN_VALUE,但它的值为DBNUll – 2009-01-06 12:14:53

+0

正如Mark Brittingham所说,为什么在客户端删除参数名称不同码? – gbn 2009-02-22 18:17:16

0

您不显示代码添加参数和执行命令的位置。两者可能都很关键。我知道一种重现此方法 - 如果您的过程也返回行(例如,从DELETE触发器),并且您还没有消耗这些行...基本上,输出/返回参数值关注 TDS流中的网格,所以如果您尚未读取网格(使用ExecuteReader时) - 那么您无法获取更新的参数/返回值。但是,如果您使用ExecuteNonQuery这不应该是一个因素。

0

为什么使用Name =“RETURN_VALUE”作为Delete参数,而Name =“RetVal”作为Update和Insert?如果后两者工作,这是我看的第一个地方。

+0

这只是我使用的最新值 - 它最初是RetVal(我的名字),但在检查Deleted事件中的参数时,它具有系统生成的名称RETURN_VALUE。不幸的是他们都没有工作 - 参数在那里,并命名为RETURN_VALUE,但具有DBNull的值 – 2009-02-22 18:41:49