ExecuteScalar从存储过程中不返回任何内容

时间:2017-02-15 18:07:19

标签: sql-server vb.net visual-studio stored-procedures executescalar

我有一个简单的存储过程,它使用 type_name (varchar(100))作为输入参数,将 type_id (int)作为OUTPUT参数返回。当我在SqlServer中执行存储过程时,它工作正常并返回相应的 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 会返回 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

我花了几个小时在网上搜索解决方案,发现没有任何帮助。我在一个使用相同编码和逻辑的不同项目中有类似的存储过程和函数,它工作正常(但它返回 varchar 作为OUTPUT参数)。我比较了这两个项目,看看我是否遗漏了一些简单但没有快乐的东西。

1 个答案:

答案 0 :(得分:1)

你真的应该使用Option Strict On并纠正它指出的问题。目前,正在执行数据类型之间的隐式转换,这将使您的代码更慢并且可能容易出错。

我建议如下:

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参数的大小几乎总是好主意,这样数据库就可以重用执行计划,而不是为每个参数长度制定新的执行计划。

请注意,对所有内容使用一个SQL连接通常是一个坏主意:您应该使用连接,然后在立即使用后立即将其丢弃。一开始似乎是一个好主意,但它正在与它的设计方式作斗争(connection pooling负责快速重新打开连接)。

参考:Execute Scalar to trap error in case of no records returned