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 数组。伙计,我讨厌修复我没有写的代码...
我有一个声明如下的 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 数组。伙计,我讨厌修复我没有写的代码...