SqlHelper.ExecuteReader() 在找不到结果时抛出异常

SqlHelper.ExecuteReader() throws an exception when no results found

我有一个声明如下的 SqlDataReader:

Dim myReader As SqlDataReader
myReader = SqlHelper.ExecuteReader(ConnectionString, "storedProcedure1", CInt(myTextBox.Text))

后来我用的结果是这样的:

If myReader.HasRows Then
    While myReader.Read()
            Row = Table1.NewRow()
            Row.Item("REF") = myReader.GetString(0)
            Row.Item("CD") = myReader.GetString(1)
            Row.Item("NAME") = myReader.GetString(2)
            Row.Item("KEY") = myReader.GetDecimal(3)
            Row.Item("STRING") = myReader.GetString(0) & " - " & myReader.GetString(1) & " - " & myReader.GetString(2).ToString().Replace("'", "") & " - " & myReader.GetString(4).ToString().Replace("'", "")

            Table1.Rows.Add(Row)

            'Fill Drop Down
            drpMenu.Items.Add(New ListItem(myReader.GetString(0) & " - " & myReader.GetString(1) & " - " & myReader.GetString(2).ToString().Replace("'", "") & " - " & myReader.GetString(4).ToString().Replace("'", "")))
    End While
End If

myTextBox 是一个文本框,用户可以在其中输入使用存储过程搜索的可能位置编号。如果用户输入一个有效的位置号码,这很好用,我没有问题。如果他们输入了一个不存在的位置号码,我得到一个例外:

System.IndexOutOfRangeException: Index was outside the bounds of the array.

我认为 If myReader.HasRows 行会阻止我尝试读取和操作不存在的结果,但一定有我遗漏的东西。 myTextBox 已经在代码的其他地方进行了验证,以确保用户输入的整数没有任何古怪的字符,因此错误的输入似乎也不是问题所在。

如何在调用SqlHelper.ExecuteReader()前判断位置号码是否存在?或者更好的问题是如何优雅地处理此异常并告诉用户找不到位置?

编辑:这是存储过程。

ALTER PROCEDURE [dbo].[storedProcedure]
    -- Add the parameters for the stored procedure here
    @MBR as  integer
AS
BEGIN 
    EXEC ('{CALL RM#IMLIB.spGETLOC( ?)}', @MBR) at AS400
END 

编辑 #2: 当我 运行 SMS 中的存储过程并传递一个有效位置时,它 returns 我所期望的。如果我传递了一个无效的位置编号,它 returns 什么都没有。

首先。创建一个局部变量...并将文本框值转换为局部变量...以确保这不是错误。

dim myValue as Int32
myValue = '' convert textbox value to an int.

其次...通常,我的数据读取器代码如下所示。

    If (Not ( reader Is Nothing) ) then
        If reader.HasRows Then 
            Do While reader.Read()
                Console.WriteLine(reader.GetInt32(0) _
                  & vbTab & reader.GetString(1))
            Loop 
        End If
    End If

(当然,您必须根据具体情况调整 GetInt32 或 GetString 和序号)。

我的猜测是您的子程序 (RM#IMLIB.spGETLOC) 具有逻辑,如果没有匹配,则不会 return 一行。

您仍然可以 return 结果....其中没有行。 **(再读一遍)。

例如

Select ColA, ColB from dbo.MyTable where 0=1

这将 return 结果,没有行。这不同于 not returning a(ny) select statement..(再读一遍)

我的猜测是这个细微差别就是您遇到问题的地方。

追加:

如果您不能更改子存储过程....

创建一个#TempTable... 使用子存储过程填充#TempTable。 从 #TempTable 执行 select。

这是一个通用示例:

    IF OBJECT_ID('tempdb..#TempOrders') IS NOT NULL
    begin
            drop table #TempOrders
    end


    CREATE TABLE #TempOrders
    ( 
        ColumnA int
      , [ColumnB] nchar(5)

    )

/* Note, your #temp table must have the exact same columns as returned by the child procedure */

INSERT INTO #TempOrders ( ColumnA, ColumnB )
exec dbo.uspChildProcedure ParameterOne

Select ColumnA, ColumnB from #TempOrders






    IF OBJECT_ID('tempdb..#TempOrderDetails') IS NOT NULL
    begin
            drop table #TempOrderDetails
    end

我终于弄明白我的问题了。

稍后在我的代码中,如果找不到位置,我有一个空的 DataRow 数组。我收到异常是因为它试图从 array(0) 中获取一个完全有意义的项目。

我最初错过了它,因为我认为它是一个 DataRow,而不是一个 DataRow 数组。伙计,我讨厌修复我没有写的代码...