检索存储过程结果

时间:2014-01-07 15:06:58

标签: sql-server vb.net ado.net

我正在尝试在三个不同的屏幕之间切换用户,具体取决于存储过程在asp.net VB中的BtnView_Click过程中返回的内容。 SP将返回“0,1或NULL”。目前它只返回“1”而不是其他。我在阅读带有IF语句的Reader.Read区域时遇到了麻烦,我想知道是否有一个简单的修复程序,所以它指向一切准确的。

这是我目前拥有的(更新的)

    Sub BtnView_Click(ByVal sender As Object, ByVal e As CommandEventArgs)

    Session.Add("SvarRecord", e.CommandArgument)

    Dim sb As New System.Text.StringBuilder()

    Dim connectionString As String = ConfigurationManager.ConnectionStrings("CS_Connection").ConnectionString
    Using connection As New SqlConnection(connectionString)

        Dim myCommand As New SqlCommand("View", connection)
        myCommand.CommandType = CommandType.StoredProcedure

        Dim sqlRecord As SqlParameter = New SqlParameter("@Name", SqlDbType.VarChar)
        sqlRecord.Value = Session("SvarRecord")
        myCommand.Parameters.Add(sqlRecord)

        connection.Open()



        Using reader As SqlClient.SqlDataReader = myCommand.ExecuteReader
            REM Read() returns True if data can be read
            If reader.Read() Then
                REM IsDbNull checks if given column (by ordinal) contains DbNull.
                REM You need it because you can not convert DbNull to a number. As alternative
                REM you may read it as object and compare by yourself.
                If reader.IsDBNull(0) Then
                    Response.Redirect("Entry.Aspx")
                    REM We are sure it is not DbNull and we can assume it is an integer
                ElseIf reader.GetInt32(0) = 0 Then
                    Response.Redirect("Negatives.Aspx")
                ElseIf reader.GetInt32(0) = 1 Then
                    Response.Redirect("PrevEntry.Aspx")
                End If
            End If
            reader.Close()
        End Using

        connection.Close()
        connection.Dispose()
    End Using

2 个答案:

答案 0 :(得分:3)

您正在比较HasRows属性(指示记录集是否为空的Boolean),而不是存储过程返回的值。

将您的代码更改为:

Using reader As SqlClient.SqlDataReader = myCommand.ExecuteReader
    Rem Read() returns True if data can be read
    If reader.Read() Then
        Rem IsDbNull checks if given column (by ordinal) contains DbNull.
        Rem You need it because you can not convert DbNull to a number.
        Rem As alternative you may read it as object and compare by yourself.
        If reader.IsDbNull(0) Then
            Response.Redirect("Entry.Aspx")
        Rem We are sure it is not DbNull and we can assume it is an integer
        ElseIf reader.GetInt32(0) = 0 Then
            Response.Redirect("Negatives.Aspx")
        ElseIf reader.GetInt32(0) = 1 Then
            Response.Redirect("PrevEntry.Aspx")
        End If
    End If
End Using

这里我假设您的存储过程返回一个整数值。如果不是,您可以使用正确的值进行比较或将其转换为整数。第一种情况(另一种​​If相同):

ElseIf reader.GetString(0) = "0" Then

第二种情况:

ElseIf Convert.ToInt32(reader.GetObject(0)) = 0 Then

关于您的代码的最后一点,正如Jhon in his comment所建议的那样,您的代码可能由于无限多的原因而失败,您最好始终将一次性对象包装在Using语句中,如下所示:

Dim connectionString As String = 
    ConfigurationManager.ConnectionStrings("CS_Connection").ConnectionString)

Using connection As New SqlConnection(connectionString)
    Rem Put here all code that uses connection
End Using

这将确保即使出现错误也将始终释放连接和其他共享(和有限!)资源。 修改编译器不会抱怨BooleanString的比较,因为您没有将OPTION STRICT设置为ON(请参阅{ {3}}了解更多详情。)

答案 1 :(得分:1)

首先,使用Using - 语句来处理/关闭连接以及实现IDisposable的任何其他内容,即使出错也是如此。其次,你应该在全局范围内将OPTION STRICT设置为on,然后这将无法编译,这是一件好事:

If reader.HasRows = "0" Then

该代码存在的问题是HasRowsBoolean,但您要将其与String进行比较。这将导致编译器错误,但OPTION STRICT off允许它。 Boolean将被隐含地转换为String。所以这种比较似乎有效,但事实并非如此。

实际上你必须阅读该字段,你可以使用Get...方法:

If reader.HasRows Then
    If reader.IsDBNull(0) Then
        Response.Redirect("Entry.Aspx")
    ElseIf reader.GetInt32(0) = 1 Then
        Response.Redirect("PrevEntry.Aspx")
    ElseIf reader.GetInt32(0) = 0 Then
        Response.Redirect("Negatives.Aspx")
    End If
End If