1

我有一个这样声明的 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:索引超出了数组的范围。

我认为这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 中运行存储过程并传递一个有效位置时,它会返回我所期望的。如果我传递了无效的位置编号,它不会返回任何内容。

4

2 回答 2

2

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

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)中有逻辑,如果没有匹配项,则不会返回一行。

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

例如

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

这将返回一个没有行的结果。这与不返回(ny)选择语句不同..(再读一遍)

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

附加:

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

创建#TempTable... 用子存储过程填充#TempTable。从#TempTable 中进行选择。

这是一个通用示例:

    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
于 2015-07-02T15:59:56.920 回答
1

我终于弄清楚了我的问题。

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

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

于 2015-07-02T18:34:42.313 回答