Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
735 views
in Technique[技术] by (71.8m points)

.net - Is there a bug in SqlDataReader.HasRows when running against SQL Server 2008?

Take a look at these two queries:

-- #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

Query #1 returns 20 rows when I run it in Management Studio.
Query #2 returns the same 20 rows, but I also see the following in the Messages tab:

Informational: The full-text search condition contained noise word(s).

So far, so boring - exactly what I'd expect to happen.

Now, take a look at this C# snippet:

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...
            }
        }
    }
}

When I run this code against query #1 everything behaves as expected - the "do something useful" section gets hit for each of the 20 rows.

When I run it against query #2, nothing happens - the "do something useful" section is never reached.

Now here's where things get a bit more interesting...

If I remove the HasRows check then everything works as expected - the "do something useful" section gets hit for each of the 20 rows, regardless of which query is used.

It seems that the HasRows property isn't populated correctly if SQL Server generates a message. The results are returned and can be iterated through using the Read() method but the HasRows property will be false.

Is this a known bug in .NET and/or SQL Server, or have I missed something obvious?
I'm using VS2008SP1, .NET3.5SP1 and SQL2008.

EDIT: I appreciate that my question is very similar to this one, and it's almost certainly a manifestation of the same issue, but that question has been bogged down for three months with no definitive answer.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I'm the original poster of the refernced question (lost login) and never managed to figure it out. In the end I put it down to bad voodoo, sacrificed neatness and went with something like

bool readerHasRows=false;
while(reader.reader())
{
   readerHasRows=true;
   doStuffOverAndOver();
}
if (!readerHasRows)
{
   probablyBetterShowAnErrorMessageThen();
}

What was really weird was that it worked in one aspx page and not in a another despite the code blocks being almost identical bar the stored procedure used.

Needless to say I'm avoiding .HasRows from now on ;)

EDIT - Management Studio shows messages in the messages tab on the problem procedure in my project too. So that seems to be the cause of the problem. But why would it bugger up .HasRows??

EDIT2 - Confirmed, altered the query to avoid the warning messages and .hasrows is now true.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...