Возвращаемое значение из SQL 2005 SP возвращает DBNULL - Где я иду не так? - PullRequest
1 голос
/ 02 января 2009

Это 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

И я пытаюсь получить возвращаемое значение, используя код ниже (комбинированный 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 вместо возвращаемого значения, но только при удалении - этот подход прекрасно работает как с обновлениями, так и с вставками.

Надеюсь, я просто немного хладнокровен и пропустил что-то очевидное - есть идеи?

Редактировать

У меня все еще есть эта проблема, и я попробовал все варианты ниже, но безрезультатно - я удивлен, что ни у кого больше не было этой проблемы?

Код для добавления параметров:

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

Ответы [ 6 ]

3 голосов
/ 06 мая 2009

Я немного опаздываю к игре здесь, но ради людей, которые сталкиваются с этим вопросом ...

Если вы используете ExecuteReader в ADO.Net, возвращаемое значение не будет заполнено до тех пор, пока вы не закроете Reader или соответствующее подключение к базе данных. ( см. Здесь )

Это не будет работать:

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 голос
/ 02 января 2009

Когда вы добавили параметр, вы установили направление ReturnValue ?

0 голосов
/ 21 февраля 2009

Почему вы используете Name = "RETURN_VALUE" для параметра Delete, а Name = "RetVal" для Update и Insert? Если последние два сработают, это первое место, на которое я посмотрю.

0 голосов
/ 21 февраля 2009

Вы не показываете код, куда вы добавляете параметры и выполняете команду. Оба могут быть критическими.

Я знаю один способ воспроизведения этого - если ваша процедура также возвращает строки (например, из триггера DELETE), и вы не использовали эти строки ... в основном, значения параметров out / return следуют сетки в потоке TDS, поэтому, если вы еще не прочитали сетки (при использовании ExecuteReader) - вы не можете получить обновленные параметры / возвращаемое значение. Но если вы используете ExecuteNonQuery, это не должно быть фактором.

0 голосов
/ 06 января 2009

Запустите это в инструментах SQL, чтобы убедиться, что хранимый процесс ведет себя как положено.

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

Я упоминаю "id> 2", потому что вы можете читать неправильный параметр. То есть этот хранимый процесс имеет 2 параметра ... один для идентификатора, а другой для возвращаемого значения.

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 голосов
/ 02 января 2009

Да, я сделал - я использую элемент управления sqlDataSource, который выявлял параметры для меня, включая возвращаемое значение с правильным набором направления. Просто для забавы я также создал параметр с нуля с обратным валом, но без радости: (

...