我有一个声明如下的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中运行存储过程并传递有效位置时,它会返回我期望的内容。如果我传递了无效的位置编号,则不返回任何内容。
答案 0 :(得分:2)
首先。创建一个局部变量...并将文本框值转换为局部变量...以确保这不是错误。
dim myValue as Int32
myValue = '' convert textbox value to an int.
第二......通常,我的datareader代码看起来像这样。
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)select语句不同..(再次阅读)
我的猜测是,这个小小的细微差别是你遇到问题的地方。
APPEND:
如果您无法更改子存储过程....
创建一个#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
答案 1 :(得分:1)
我终于找到了我的问题。
稍后在我的代码中,如果找不到位置,我有一个DataRow数组为空。我得到了异常,因为它试图从数组(0)中获取一个完全正确的项目。
我最初错过了它,因为我认为它是DataRow,而不是DataRow数组。伙计,我讨厌修理我没写过的代码...