看看这两个问题:
-- #1
SELECT * FROM my_table
WHERE CONTAINS(my_column, 'monkey')
-- #2
SELECT * FROM my_table
WHERE CONTAINS(my_column, 'a OR monkey') -- "a" is a noise word
在Management Studio中运行时,查询#1返回20行 查询#2返回相同的20行,但我也在消息选项卡中看到以下内容:
信息:全文搜索条件包含干扰词。
到目前为止,如此无聊 - 正是我期望发生的事情。
现在,看看这个C#片段:
using (SqlConnection conn = new SqlConnection(...))
{
SqlCommand cmd = conn.CreateCommand();
// setup the command object...
conn.Open();
using (SqlDataReader dr = cmd.ExecuteReader())
{
if (dr.HasRows)
{
// get column ordinals etc...
while (dr.Read())
{
// do something useful...
}
}
}
}
当我针对查询#1运行此代码时,一切都按预期运行 - 20行中的每一行都会点击“执行一些有用的”部分。
当我针对查询#2运行它时,没有任何反应 - 从未达到“做有用的事情”部分。
现在这里的事情变得更有趣......
如果我删除了HasRows
检查,那么一切都按预期工作 - 无论使用哪个查询,都会为20行中的每一行点击“做一些有用的”部分。
如果SQL Server生成消息,似乎没有正确填充HasRows
属性。返回结果并可以使用Read()
方法进行迭代,但HasRows
属性将为false。
这是.NET和/或SQL Server中的已知错误,还是我错过了一些明显的东西? 我正在使用VS2008SP1,.NET3.5SP1和SQL2008。
编辑:我很欣赏我的问题与this one非常相似,而且几乎可以肯定是同一问题的表现,但这个问题已经陷入困境三个月了明确的答案。
答案 0 :(得分:6)
我是推荐问题的原始海报(丢失登录信息),但从未设法弄明白。最后,我把它归结为糟糕的伏都教,牺牲了整洁,并采取类似
的方式bool readerHasRows=false;
while(reader.reader())
{
readerHasRows=true;
doStuffOverAndOver();
}
if (!readerHasRows)
{
probablyBetterShowAnErrorMessageThen();
}
真正奇怪的是它在一个aspx页面中工作而在另一个aspx页面中没有,尽管代码块与所使用的存储过程几乎相同。
毋庸置疑我从现在开始避免.HasRows;)
编辑 - Management Studio也会在项目中的问题流程的消息标签中显示消息。所以这似乎是问题的原因。但是为什么它会起作用.HasRows ??
EDIT2 - 已确认,已更改查询以避免出现警告消息,并且.hasrows现在为真。
答案 1 :(得分:2)
这当然是奇怪的行为 - 但我想知道为什么你需要检查HasRows
是否要简单地迭代结果集。
HasRows
属性封装了_hasRows
字段,由于各种原因,该字段在许多不同的地方设置为true
或false
内SqlDataReader
。如果私有true
的{{1}}方法返回表示数据存在的数字,则大多数这些地方都设置为TdsParserStateObject
。
答案 2 :(得分:1)
听起来像HasRows是其中一个值不能保证准确的属性......
我同意前两篇文章(关于直接进入while(dr.Read())并在第一次迭代中获得序数)。另外,为什么不获取数据集而不是数据读取器?如果在这种情况下,您只处理20行,那么与使用数据读取器相比,一次获取整个数据集可能不会产生太大的性能损失。我知道这并没有真正回答你的问题,只是想一个解决方法。
答案 3 :(得分:0)
与Andrew一样,我不确定为什么你不会只使用while循环,以避免额外的GetOrdinal调用的性能损失。您可以使用标志值在第一行执行GetOrdinal调用,然后可以跳过代码。
过去我注意到HasRows存在类似的问题,并且采用了与上面列出的类似的模式,但问题很少。
答案 4 :(得分:0)
尝试以下操作并报告是否成功:
using (SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.SingleResult))
答案 5 :(得分:0)
如果怀疑多个结果集导致此问题,我建议调用NextResult方法。由于第一个结果集似乎是空的,因此使用CommandBehavior.SingleResult不会更改行为,因为仍会返回第一个(空)结果。你可以试试。无论如何,我听说这是一个错误,但我不记得我在哪里阅读它,快速谷歌搜索没有产生任何结果。