Intouch环境下SqlDataReader.GetValue(0)无法取值求助
解决Intouch脚本中SqlDataReader无法获取SQL查询结果的问题
你的核心问题是提前消耗了查询返回的唯一一行数据,同时缺少对聚合查询可能返回DBNull的处理,以下是修正方案:
问题分析
- 你的代码先执行了
InTouch:SQLTesting = objDR.Read();,这已经读取了sum查询返回的唯一一行数据,后续while循环里的objDR.Read()会返回false,导致赋值代码完全不执行。 - sum聚合查询如果没有匹配的记录,会返回
DBNull,直接调用.ToString()会触发报错。
修正后的代码
Dim objDB As System.Data.SqlClient.SqlConnection; Dim objCmd As System.Data.SqlClient.SqlCommand; Dim objDR As System.Data.SqlClient.SqlDataReader; Dim sDBConnStr As String; Dim sSQL As String; sDBConnStr = "Server=Desktop-3J641FK;Database=Runtime;Integrated Security=True;"; objDB = New System.Data.SqlClient.SqlConnection(sDBConnStr); Try objDB.Open(); sSQL = "SELECT sum (case when EventLogKey = '5' and DetectDateTime between '2022-07-21 11:00:20' and '2022-07-25 11:00:20' then 1 else 0 end) FROM [Runtime].[dbo].[EventHistory]"; objCmd = New System.Data.SqlClient.SqlCommand(sSQL, objDB); objDR = objCmd.ExecuteReader(); ' sum查询最多返回一行,只需一次Read判断 If objDR.Read() Then ' 先判断是否为DBNull,避免报错 If Not objDR.IsDBNull(0) Then InTouch:SQLTest = objDR.GetValue(0).ToString(); Else ' 无匹配记录时赋值默认值(比如0) InTouch:SQLTest = "0"; End If InTouch:SQLTesting = True; Else InTouch:SQLTesting = False; InTouch:SQLTest = ""; End If Finally ' 确保所有资源被正确释放,防止连接泄漏 If objDR IsNot Nothing Then objDR.Close(); If objCmd IsNot Nothing Then objCmd.Dispose(); If objDB IsNot Nothing Then objDB.Close(); objDB.Dispose(); End If End Try
关键修改点
- 移除多余的
while循环,改用If objDR.Read()处理单行结果,避免重复读取消耗数据。 - 删除提前消耗数据的
InTouch:SQLTesting = objDR.Read();,将读取结果的判断整合到业务逻辑中。 - 增加
IsDBNull(0)判断,处理无匹配记录时的空值情况。 - 使用
Try...Finally块确保数据库资源在任何情况下都能被释放,避免连接泄漏。
内容的提问来源于stack exchange,提问作者shing9301
相关产品推荐
相关产品推荐

