CLR存储过程中的SqlDataReader和SqlDataAdapter仅返回第一行

时间:2016-11-15 23:51:56

标签: c# sql-server sqlclr

我在SQL Server 2014上运行了一个CLR存储过程。当我执行以下代码时,数据读取器只返回结果集的顶行。 SQL本身运行时会返回多行。我还尝试使用DataTable填充SqlDataAdapter,但仍然只获得一行。

using (SqlConnection conn = new SqlConnection("context connection=true"))
using (SqlCommand cmd = new SqlCommand("SELECT * FROM some_table", conn))
{
    cmd.CommandType = CommandType.Text;
    conn.Open();

    SqlDataReader reader = cmd.ExecuteReader();

    if (reader.HasRows)
    {
        while (reader.Read())
            SqlContext.Pipe.Send(reader.GetInt32(0).ToString());
    }

    reader.Close();
    conn.Close();
}

提前感谢您的帮助。这让我感到困惑,因为这是最简单的事情。

2 个答案:

答案 0 :(得分:1)

此代码没有任何内在错误。我自己在SQL Server 2014上运行它,根据.NET Framework 4.5.2版进行编译,它可以按照您的预期运行。而且要明确的是,对于你在这里所做的事情,SQL Server和.NET Framework的版本并不重要。

我还尝试将CommandBehavior.SingleRow传递给cmd.ExecuteReader()并仍然返回所有行。

由于此代码确实有效,因此需要检查以下内容:

  1. 确保您要发布到SSMS中运行SELECT语句的同一个数据库(和实例)。
  2. 确保您已将此代码的最新版本发布到数据库。
  3. 其他外部因素
  4. 另外,请在SqlDataReader构造中创建using(),因为它是一个Disposable对象。

    从O.P。更新:

    在调用SQLCLR存储过程之前,已从发出SET ROWCOUNT 1;的T-SQL存储过程调用SQLCLR存储过程。因此,任何查询只能返回1行。通过在调用SQLCLR存储过程之前发出SET ROWCOUNT 0;来解决1行问题。

    请注意:通常首选使用TOP ()子句代替SET ROWCOUNT n;

答案 1 :(得分:0)

小心!微软有一个错误:

https://social.msdn.microsoft.com/Forums/sqlserver/en-US/83b23289-a24b-4f82-b81f-3e8ccf6d8001/is-this-serious-sqlclr-bug-present-in-sql-server-2012?forum=sqlnetfx

SqlDataReader类实际上只是简单地抓取了一个锁,但它不应该因为SQL CLR批准的代码永远不会被锁定。

我向MS提交了一个证明这一点的示例,一个非常简单的循环只使用经过批准的SQL / CLR类/方法,当SSMS用户点击取消时会导致AppDomain卸载 - 完全是灾难性的。

这是参考源,看看你会发现“锁定”语句 - 对于SQL / CLR是非法的,但他们批准了这个类!

https://referencesource.microsoft.com/#system.data/system/Data/SqlClient/SqlDataReader.cs

这表示/暗示其已获批准:

https://msdn.microsoft.com/en-us/library/ms131094.aspx

然而,这未能将其列入最近批准的名单:

https://docs.microsoft.com/en-us/sql/relational-databases/clr-integration/database-objects/supported-net-framework-libraries

(奇怪的是OracleClient在列表中!)