2009-01-02 55 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