.HasRows() 对数据 reader 的函数永远占用
.HasRows() function on data reader taking forever
我有一些简单的代码,一个 if
语句检查数据 reader 的 HasRows
并且出于某种原因当我 运行 我的代码在 Visual Studio 2017 年需要永远评估和 return 答案(在写这篇文章时,我的代码已经 运行ning 了 4 分钟)。有什么建议吗?
Dim cmd As OdbcCommand
Dim rdr As OdbcDataReader
cmd = New OdbcCommand("select GLPN,GLFY,GLDCT,GLDOC,GLCO,GLDGJ,GLANI,GLSBL,GLLT,GLCRCD,GLAA,GLU,GLGLC,GLEXA,GLICUT,GLR2,GLR1,GLSFX,GLOKCO" _
& ",GLEXR,GLODOC,GLPKCO,GLPDCT,GLCN,GLDKJ,GLVINV,GLIVD,GLPO,GLDCTO,GLLNID,GLTORG,GLAN8,GLICU,GLOPSQ,GLJBCD" _
& ",GLACR,GLABR2,GLABR1,GLDGJ,GLLT,GLCRCD,GLEXA,GLICUT,GLEXR,GLDKJ,GLIVD,GLAN8,GLICU,GLACR,GLKCO,GLSBLT,GLOBJ,GLSUB,GLJELN,GLEXTL,GLCRR,GLBCRC" _
& " from " _
& "PRODDTA.F0911 where GLPOST = 'P' and GLDGJ >= ? and GLDGJ <= ? and (GLLT = 'AA' or GLLT = 'CA') and GLDOC = 206940", cnn)
cmd.Parameters.Add("?GLUPMJs", OdbcType.Int).Value = todaysdate - 14
cmd.Parameters.Add("?GLUPMJe", OdbcType.Int).Value = todaysdate
cnn.Open()
cmd.CommandTimeout = 300
rdr = cmd.ExecuteReader
If rdr.HasRows() Then
'Do a bunch of stuff
End if
Edit1:仍然遇到有趣的问题,但我注意到它只出现在一个地方,我有 "HasRows()" 检查多个地方,它工作速度快 3 毫秒等。它只针对一个查询。
Edit2:我上次在 SQL 开发人员上引用的查询 运行s 非常快,总共 1.202 秒,它也 returns 没有消息。
Edit3:我想知道它是否与我正在 returning 的字段数量有关,其他 运行 在这一行上快速的查询是 returning字段数小得多。
这可能不会加快速度,但你试过了吗??
While rdr.Read()
'Do a bunch of stuff
End While
编辑:
Dim dt As DataTable = New DataTable
dt.Load(rdr)
If dt.Rows.Count >= 0 Then
'Do a bunch of stuff
End If
问题可能在于查询执行时间过长。如果您只对检查记录的存在感兴趣,您可以使用“SELECT TOP 1 1
”执行查询并使用 ExecuteScalar
而不是 ExecuteReader
.
看来 HasRows
方法遇到问题的不止您一个。在 this post 中,OP 指出该方法存在问题,尽管它是 SQL-SERVER。但我认为该解决方案可能有用,因为两个 DataReader 都继承自同一个 class,并且它们密切相关。
如果您阅读他们在问题中引用的 post 和投票最多的答案,您会发现他们得出的结论是 HasRows
在 SQL查询执行不仅返回了一些数据结果,还返回了一条消息。他们最终使用了一种替代方法,基于Read()
方法检查数据reader上是否有任何数据,事实证明这种方法更可靠。
在他们的例子中,问题是 HasRows
属性 被设置为 false 而 reader 实际上包含数据,但这可能与您的性能问题有关。您绝对应该尝试 Read
方法,以确保您的查询没有问题。
P.S:另一个有趣的 link 有一个人报告了同样的问题。
HasRows() 延迟的原因是因为 ExecuteReader 并没有真正执行查询,它推迟了执行直到需要它。 HasRows 是执行它的人。感谢 Dwillis 指出。
我通过在它前面放一行代码来测试它,这是延迟所在的地方,当 hasRows 运行 它很快时。
有趣的是 sql 运行 在 Sql Management Studio 中 运行es 在 1.5 秒内返回所有行,但在代码中它永远需要不同的问题,但也可能是由于 ODBC 设置。
我有一些简单的代码,一个 if
语句检查数据 reader 的 HasRows
并且出于某种原因当我 运行 我的代码在 Visual Studio 2017 年需要永远评估和 return 答案(在写这篇文章时,我的代码已经 运行ning 了 4 分钟)。有什么建议吗?
Dim cmd As OdbcCommand
Dim rdr As OdbcDataReader
cmd = New OdbcCommand("select GLPN,GLFY,GLDCT,GLDOC,GLCO,GLDGJ,GLANI,GLSBL,GLLT,GLCRCD,GLAA,GLU,GLGLC,GLEXA,GLICUT,GLR2,GLR1,GLSFX,GLOKCO" _
& ",GLEXR,GLODOC,GLPKCO,GLPDCT,GLCN,GLDKJ,GLVINV,GLIVD,GLPO,GLDCTO,GLLNID,GLTORG,GLAN8,GLICU,GLOPSQ,GLJBCD" _
& ",GLACR,GLABR2,GLABR1,GLDGJ,GLLT,GLCRCD,GLEXA,GLICUT,GLEXR,GLDKJ,GLIVD,GLAN8,GLICU,GLACR,GLKCO,GLSBLT,GLOBJ,GLSUB,GLJELN,GLEXTL,GLCRR,GLBCRC" _
& " from " _
& "PRODDTA.F0911 where GLPOST = 'P' and GLDGJ >= ? and GLDGJ <= ? and (GLLT = 'AA' or GLLT = 'CA') and GLDOC = 206940", cnn)
cmd.Parameters.Add("?GLUPMJs", OdbcType.Int).Value = todaysdate - 14
cmd.Parameters.Add("?GLUPMJe", OdbcType.Int).Value = todaysdate
cnn.Open()
cmd.CommandTimeout = 300
rdr = cmd.ExecuteReader
If rdr.HasRows() Then
'Do a bunch of stuff
End if
Edit1:仍然遇到有趣的问题,但我注意到它只出现在一个地方,我有 "HasRows()" 检查多个地方,它工作速度快 3 毫秒等。它只针对一个查询。
Edit2:我上次在 SQL 开发人员上引用的查询 运行s 非常快,总共 1.202 秒,它也 returns 没有消息。
Edit3:我想知道它是否与我正在 returning 的字段数量有关,其他 运行 在这一行上快速的查询是 returning字段数小得多。
这可能不会加快速度,但你试过了吗??
While rdr.Read()
'Do a bunch of stuff
End While
编辑:
Dim dt As DataTable = New DataTable
dt.Load(rdr)
If dt.Rows.Count >= 0 Then
'Do a bunch of stuff
End If
问题可能在于查询执行时间过长。如果您只对检查记录的存在感兴趣,您可以使用“SELECT TOP 1 1
”执行查询并使用 ExecuteScalar
而不是 ExecuteReader
.
看来 HasRows
方法遇到问题的不止您一个。在 this post 中,OP 指出该方法存在问题,尽管它是 SQL-SERVER。但我认为该解决方案可能有用,因为两个 DataReader 都继承自同一个 class,并且它们密切相关。
如果您阅读他们在问题中引用的 post 和投票最多的答案,您会发现他们得出的结论是 HasRows
在 SQL查询执行不仅返回了一些数据结果,还返回了一条消息。他们最终使用了一种替代方法,基于Read()
方法检查数据reader上是否有任何数据,事实证明这种方法更可靠。
在他们的例子中,问题是 HasRows
属性 被设置为 false 而 reader 实际上包含数据,但这可能与您的性能问题有关。您绝对应该尝试 Read
方法,以确保您的查询没有问题。
P.S:另一个有趣的 link 有一个人报告了同样的问题。
HasRows() 延迟的原因是因为 ExecuteReader 并没有真正执行查询,它推迟了执行直到需要它。 HasRows 是执行它的人。感谢 Dwillis 指出。
我通过在它前面放一行代码来测试它,这是延迟所在的地方,当 hasRows 运行 它很快时。
有趣的是 sql 运行 在 Sql Management Studio 中 运行es 在 1.5 秒内返回所有行,但在代码中它永远需要不同的问题,但也可能是由于 ODBC 设置。