【问题标题】:A working stored procedure returns null value only when called from asp.net仅当从 asp.net 调用时,有效的存储过程才返回空值
【发布时间】:2015-02-10 21:04:33
【问题描述】:

我创建了以下存储过程来将数据插入表中。

ALTER PROCEDURE [dbo].[Sp_AddAircraft] 
-- Add the parameters for the stored procedure here
    @ACFT_Reg varchar(50), 
    @ACFT_MSN int,
    @ACFT_Manufacturer varchar(50),
    @ACFT_Type_P1 varchar(50),
    @ACFT_Type_P2 int,
    @ACFT_DOM date,
    @ACFT_ETOPS bit,
    @ACFT_TOT float,
    @ACFT_TOC int

AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

-- Insert statements for procedure here
IF EXISTS(SELECT * FROM Aircraft
          WHERE ACFT_MSN = @ACFT_MSN 
            And ACFT_Manufacturer = @ACFT_Manufacturer)
    Return (5)
ELSE
    INSERT INTO [Aircraft] 
        ([ACFT_Reg], [ACFT_MSN], [ACFT_Manufacturer], [ACFT_Type_P1],
         [ACFT_Type_P2], [ACFT_DOM], [ACFT_ETOPS], [ACFT_TOT], [ACFT_TOC])
    VALUES (@ACFT_Reg, @ACFT_MSN, @ACFT_Manufacturer, @ACFT_Type_P1,
            @ACFT_Type_P2, @ACFT_DOM, @ACFT_ETOPS, @ACFT_TOT, @ACFT_TOC)
    Return (1)
END

我检查唯一约束(ACFT_MSNACFT_Manufacturer 的组合),如果存在,则存储过程返回值 5,如果不存在,则返回值 1 并插入新记录。

该过程在 SQL Server 2008 Management Studio 中运行良好。

当我从 asp.net 调用它时,浏览器会抛出这个错误

“从 'DBNull' 类型转换为 'Short' 类型无效。”

Return 参数在 DataSource 中定义如下:

<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NileAirConnectionString1 %>" 
         InsertCommand="Sp_AddAircraft" InsertCommandType="StoredProcedure" OnInserted="SqlDataSource1_Inserted" 
         ProviderName="<%$ ConnectionStrings:NileAirConnectionString1.ProviderName %>">
            <InsertParameters>
                <asp:Parameter Name="ACFT_Reg" Type="String" />
                <asp:Parameter Name="ACFT_MSN" Type="Int32" />
                <asp:Parameter Name="ACFT_Manufacturer" Type="String" />
                <asp:Parameter Name="ACFT_Type_P1" Type="String" />
                <asp:Parameter Name="ACFT_Type_P2" Type="Int32" />
                <asp:Parameter DbType="Date" Name="ACFT_DOM" />
                <asp:Parameter Name="ACFT_ETOPS" Type="Boolean" />
                <asp:Parameter Name="ACFT_TOT" Type="Double" />
                <asp:Parameter Name="ACFT_TOC" Type="Int32" />
                <asp:Parameter Name="R" Type="Int16" Direction="ReturnValue" />
            </InsertParameters>
        </asp:SqlDataSource>

我在 SqlDataSource1_Inserted 事件中读取参数如下:

Protected Sub SqlDataSource1_Inserted(sender As Object, e As SqlDataSourceStatusEventArgs)
    Dim G As Int16
    G = e.Command.Parameters("@R").Value
    If G = 5 Then
        Lbl_ACFT_Doublication.CssClass = "WarningMessages"
        Lbl_ACFT_Doublication.Text = "Aircraft already exists"
    ElseIf G = 1 Then
        Lbl_ACFT_Doublication.CssClass = "AckMessages"
        Lbl_ACFT_Doublication.Text = "Aircraft was added succesfully"
    End If
End Sub

【问题讨论】:

  • 存储过程的 ReturnValue 是一个 int。您不应该在过程代码中使用 Return。我将删除您程序中的返回并删除“R”参数,它可能会正常工作。
  • 如果您想在已有记录的情况下获取该返回值,那么您应该 RETURN 5 而不是 SELECT 5。第二个不会在 ReturnValue 参数中传递。
  • 您有 SELECT (5) 的行,将其更改为 SELECT 5 AS R 和您有 RETURN (1) 的行,将其更改为 SELECT 1 AS R,如在您当前的存储过程中没有名为 R 的东西,因此 VB 代码在其中获取 NULL 并将其转换为 Int16 会引发异常。并且在 else 部分使用 BEGIN 和 END,因为它将有 2 个命令(插入和选择)
  • Sean Lange,感谢您的帮助,但如果我从存储过程中删除 Return,它将正常工作并在成功时返回 0。问题是我需要从存储过程中获得一个返回值,才能使用它向用户显示错误消息,以告知插入成功完成或表中已存在数据。
  • 史蒂夫,非常感谢。我将 SELECT 更改为 RETURN 并仍然收到相同的错误。

标签: asp.net sql-server vb.net stored-procedures


【解决方案1】:

检查插入的输入变量。其中之一未设置为可以隐式转换为所需类型的内容。确保插入参数的所有源控件都不是 null/Nothing

【讨论】:

  • 我检查了所有内容,但一无所获。到现在还是有问题。查不出原因。我尝试了另一个具有相同代码和过程的新网站,但它给了我另一个错误“此 SqlParameterCollection 不包含具有 ParameterName '@R' 的 SqlParameter。”
  • 将返回值参数设为零的DefaultValue
  • 在您的代码 G = e.Command.Parameters("@R").Value 中验证 Value 不为空。并非您的 sp 中的所有返回路径(如发布的那样)都有返回值
  • 我正在通过有关两条路径的数据进行测试,无论是否重复数据。所以 SP 应该返回 5 或 1 但它返回 null。
  • Select 5Return 5 不同。 Select 返回一个数据集,Return 是执行存储过程的返回值。 Return 使用您的 R 参数 - Select 不使用
【解决方案2】:

一个老问题,但它让我很生气;这可能是问题所在:

&lt;asp:Parameter Name="ACFT_Type_P1" Type="String" /&gt; 缺少 Size="50"

我也遇到了同样的问题;我的inserted 正在触发,但存储过程没有执行,我的返回值始终为 NULL。因为我在检查返回值时崩溃了,所以我没有看到抱怨缺少字符串大小的错误消息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-16
    相关资源
    最近更新 更多