ExecuteScalar returns 存储过程中没有任何内容
ExecuteScalar returns nothing from stored procedure
我有一个简单的存储过程,它 returns type_id (int) 作为 OUTPUT 参数使用 type_name (varchar(100)) 作为输入参数。当我在 SqlServer 中执行存储过程时,它工作正常并且 returns 适当的 type_id.
CREATE PROCEDURE [dbo].[intake_types_select_by_type_name]
@type_name varchar(100),
@type_id integer OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON
SELECT @type_id = type_id
FROM intake_types
WHERE type_name = @type_name
END
但是,当我从 VisualStudio 中的函数调用存储过程时,参数 @type_id returns Nothing.
Public Shared Function sp_intake_types_select_by_type_name(ByVal conn As DBConnection, ByVal caseName As String) As Integer
Dim sp As SqlCommand = conn.GetStoredProcedure("intake_types_select_by_type_name")
With sp.Parameters
.Add("@type_name", SqlDbType.VarChar, ParameterDirection.Input).Value = caseName
.Add("@type_id", SqlDbType.Int)
.Item("@type_id").Direction = ParameterDirection.Output
End With
sp.ExecuteScalar()
If Not IsDBNull(sp.Parameters("@type_id").Value) Then
Return sp.Parameters("@type_id").Value
Else
Return Nothing
End If
End Function
我花了几个小时在网上搜索解决方案,但没有找到任何帮助。我在另一个项目中有一个类似的存储过程和函数,它使用相同的编码和逻辑并且工作正常(但是它 returns a varchar 作为 OUTPUT 参数)。我比较了这两个项目,看看我是否缺少一些简单但没有乐趣的东西。
您确实应该使用 Option Strict On
并更正它指出的问题。目前,正在执行数据类型之间的隐式转换,这会使您的代码变慢,并且可能 error-prone.
我建议如下:
CREATE PROCEDURE [dbo].[intake_types_select_by_type_name]
@type_name varchar(100)
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
SELECT type_id
FROM intake_types
WHERE type_name = @type_name
END
以及调用它的函数:
Option Strict On
' ....'
Public Shared Function sp_intake_types_select_by_type_name(ByVal conn As DBConnection, ByVal caseName As String) As Integer
Dim sp As SqlCommand = conn.GetStoredProcedure("intake_types_select_by_type_name")
sp.Parameters.Add("@type_name", SqlDbType.VarChar, 100).Value = caseName
Dim result As Object = sp.ExecuteScalar()
If result Is Nothing Then
Return -1 ' check for -1 in the calling code '
Else
Return CInt(result)
End If
End Function
指定 SQL 参数的大小几乎总是一个好主意,这样数据库就可以 re-use 执行计划,而不是为每个参数长度制定一个新的执行计划。
请注意,对所有内容都使用一个 SQL 连接通常不是一个好主意:您应该先使用该连接,然后在立即使用完后立即将其处理掉。起初这似乎是个好主意,但它违背了它的设计方式(connection pooling 处理快速 re-opening 的连接)。
参考:Execute Scalar to trap error in case of no records returned.
我有一个简单的存储过程,它 returns type_id (int) 作为 OUTPUT 参数使用 type_name (varchar(100)) 作为输入参数。当我在 SqlServer 中执行存储过程时,它工作正常并且 returns 适当的 type_id.
CREATE PROCEDURE [dbo].[intake_types_select_by_type_name]
@type_name varchar(100),
@type_id integer OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON
SELECT @type_id = type_id
FROM intake_types
WHERE type_name = @type_name
END
但是,当我从 VisualStudio 中的函数调用存储过程时,参数 @type_id returns Nothing.
Public Shared Function sp_intake_types_select_by_type_name(ByVal conn As DBConnection, ByVal caseName As String) As Integer
Dim sp As SqlCommand = conn.GetStoredProcedure("intake_types_select_by_type_name")
With sp.Parameters
.Add("@type_name", SqlDbType.VarChar, ParameterDirection.Input).Value = caseName
.Add("@type_id", SqlDbType.Int)
.Item("@type_id").Direction = ParameterDirection.Output
End With
sp.ExecuteScalar()
If Not IsDBNull(sp.Parameters("@type_id").Value) Then
Return sp.Parameters("@type_id").Value
Else
Return Nothing
End If
End Function
我花了几个小时在网上搜索解决方案,但没有找到任何帮助。我在另一个项目中有一个类似的存储过程和函数,它使用相同的编码和逻辑并且工作正常(但是它 returns a varchar 作为 OUTPUT 参数)。我比较了这两个项目,看看我是否缺少一些简单但没有乐趣的东西。
您确实应该使用 Option Strict On
并更正它指出的问题。目前,正在执行数据类型之间的隐式转换,这会使您的代码变慢,并且可能 error-prone.
我建议如下:
CREATE PROCEDURE [dbo].[intake_types_select_by_type_name]
@type_name varchar(100)
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
SELECT type_id
FROM intake_types
WHERE type_name = @type_name
END
以及调用它的函数:
Option Strict On
' ....'
Public Shared Function sp_intake_types_select_by_type_name(ByVal conn As DBConnection, ByVal caseName As String) As Integer
Dim sp As SqlCommand = conn.GetStoredProcedure("intake_types_select_by_type_name")
sp.Parameters.Add("@type_name", SqlDbType.VarChar, 100).Value = caseName
Dim result As Object = sp.ExecuteScalar()
If result Is Nothing Then
Return -1 ' check for -1 in the calling code '
Else
Return CInt(result)
End If
End Function
指定 SQL 参数的大小几乎总是一个好主意,这样数据库就可以 re-use 执行计划,而不是为每个参数长度制定一个新的执行计划。
请注意,对所有内容都使用一个 SQL 连接通常不是一个好主意:您应该先使用该连接,然后在立即使用完后立即将其处理掉。起初这似乎是个好主意,但它违背了它的设计方式(connection pooling 处理快速 re-opening 的连接)。
参考:Execute Scalar to trap error in case of no records returned.