【发布时间】: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_MSN 和 ACFT_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