【问题标题】:SqlDataReader.HasRows returns false since SQL 2008 upgrade自 SQL 2008 升级以来,SqlDataReader.HasRows 返回 false
【发布时间】:2010-09-16 20:50:30
【问题描述】:

我有一个连接到 SQL 数据库的 ASP.NET 2.0 网站。我已将 SQL 服务器从 2000 年升级到 2008 年,从那时起,一页无法正常工作。

我发现问题是即使数据集不为空,对 SqlDataReader.HasRows 的调用也会返回 false,并且删除检查允许通过 reader.Read() 的循环访问预期数据。

    _connectionString = WebConfigurationManager.ConnectionStrings["SQLServer"].ConnectionString;
    SqlConnection connection = new SqlConnection(_connectionString);
    SqlCommand command = new SqlCommand(searchtype, connection);
    SqlParameter _parSeachTerm = new SqlParameter("@searchterm", SqlDbType.VarChar, 255);
    _parSeachTerm.Value = searchterm;
    command.Parameters.Add(_parSeachTerm);
    command.CommandType = CommandType.StoredProcedure;
    try
    {
        connection.Open();
        SqlDataReader reader = command.ExecuteReader();
        if (reader.HasRows) //this always returns false!?
        {
            while (reader.Read())
            {...

有人知道发生了什么吗? HasRows返回正确值的其他页面上有类似的代码块。

编辑-只是为了澄清一下,存储过程确实返回了我已经确认的结果,因为如果我删除 HasRows 检查,循环运行良好。只需将连接字符串中的 SQL 服务器名称更改为在 SQL 2000 上运行的相同数据库即可解决问题。我已经检查过 NOCOUNT 是否关闭,那么如果不是这种情况,还有什么可以让 HasRows 返回 false??

EDIT2- 这是 SP

CREATE PROCEDURE StaffEnquirySurnameSearch

@searchterm varchar(255)

AS

SELECT  AD.Name, AD.Company, AD.telephoneNumber, AD.manager, CVS.Position, CVS.CompanyArea, CVS.Location, CVS.Title, AD.guid AS guid,
AD.firstname, AD.surname
FROM ADCVS AD
LEFT OUTER JOIN CVS ON
AD.Guid=CVS.Guid 
WHERE AD.SurName LIKE @searchterm
ORDER BY AD.Surname, AD.Firstname
GO

非常感谢。

【问题讨论】:

  • 退出 Profiler,看看幕后发生了什么。可能是迁移的问题。 Profiler 会在发送查询时向您显示查询,以便您对其进行测试以确保它们正常工作。
  • 这个存储过程里面有打印语句吗? (猜测)
  • 不,这只是一个简单的选择与一个连接

标签: c# asp.net sql sql-server-2008


【解决方案1】:

HasRows 需要一个可滚动的光标。

您带回的行是否包含任何大的image/BLOB 数据?

正如其他人所建议的那样,我认为发布Stored Procedure 可能会对此事有所启发......

【讨论】:

    【解决方案2】:

    我认为你的 NOCOUNT 倒退了。 我相信 NOCOUNT 需要开启才能正常工作。

    在你的存储过程中添加 设置无计数 在 AS 之后和任何代码之前。 否则返回两个结果集。 一个带有计数,一个带有实际数据。 您只需要包含实际数据的结果集。

    【讨论】:

    • 我认为你是对的。如果发帖人将 NOCOUNT 信息放在问题中而不是评论中会很有帮助...
    【解决方案3】:

    我又在猜测了。
    您是否有机会打开多个数据读取器?

    添加 MARS_Connection=yes;或 MultipleActiveResultSets=true 连接字符串,如果有帮助的话。
    此外,不推荐使用连接和数据读取器

    更简单的写法可能是

    using (connection cnn = new Connection(...) { using (SqlDataReader rdr = .... { //some code which deals with datareader } }

    操作完成后,这将关闭连接和数据读取器。

    【讨论】:

    • 谢谢,添加 MARS 会产生 System.ArgumentException:不支持关键字:'mars_connection'。资源的清理在 finally 块中完成。
    【解决方案4】:

    可能是您的连接字符串、存储过程或 sql 驱动程序中的错误。 大多数人都在猜测存储过程。 所以给我们看代码。 当您使用它时,向我们展示连接字符串和 searchtype 变量的内容。

    【讨论】:

      【解决方案5】:

      您不是偶然使用 RAISEERROR 吗?我们使用与上述相同的模式发现了一些问题(检查 HasRows,然后是 reader.Read()),并发现如果 RAISEERROR 与某个错误代码一起使用(我相信大于 16),那么 HasRows 将返回 false 并且 我们会在捕捉异常时遇到问题。

      【讨论】:

        【解决方案6】:

        首先,按照@tvanfosson 的说明检查程序。 其次,在代码 sn-p 中实际上不需要检查 HasRows()。

        【讨论】:

          【解决方案7】:

          如果您直接调用存储过程,比如在 SSMS 中,它是否有效?我会首先确保它确实如此。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-09-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-07-04
            相关资源
            最近更新 更多