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

本文关键字:返回 一行 SqlDataAdapter 存储过程 存储 过程中 SqlDataReader CLR | 更新日期: 2023-09-27 18:18:01

我有一个在SQL Server 2014上运行的CLR存储过程。当我执行以下代码时,数据读取器只返回结果集的第一行。当SQL单独运行时,返回不止一行。我也试过用SqlDataAdapter填充DataTable,但仍然只得到一行。

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();
}

提前感谢您的帮助。

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

这实在是太简单了。

这段代码本身并没有什么问题。我自己在SQL Server 2014上运行它,针对。net框架版本4.5.2编译,它可以像你期望的那样工作。要清楚的是,对于你在这里做的事情,SQL Server和。net框架的版本并不重要。

我也尝试通过CommandBehavior.SingleRowcmd.ExecuteReader(),仍然返回所有行。

由于这段代码可以工作,这里有一些东西需要检查:

  1. 确保你发布到SSMS中运行SELECT语句的同一个DB(和实例)。
  2. 请确保您已将此代码的最新版本发布到数据库。
  3. 其他外部因素

另外,请在using()结构中创建SqlDataReader,因为它是一个Disposable对象。


UPDATE FROM op .:

SQLCLR存储过程是从一个在调用SQLCLR存储过程之前发出SET ROWCOUNT 1;的T-SQL存储过程调用的。因此,任何查询只能返回1行。通过在调用SQLCLR存储过程之前发出SET ROWCOUNT 0;,可以修复1行问题。

请注意:通常更倾向于使用TOP ()子句而不是SET ROWCOUNT n;

小心!微软在这里有一个bug:

https://social.msdn.microsoft.com/forums/sqlserver/en - us/83b23289 a24b - 4 - f82 b81f - 3 - e8ccf6d8001/is这严重- sqlclr bug -现在- sql - server - 2012 ?forum=sqlnetfx

SqlDataReader类实际上短暂地获取了一个锁,但它不应该这样做,因为SQL CLR批准的代码不应该获取锁。

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

这是参考源代码,看一看,你会发现"锁"语句——对SQL/CLR来说是非法的,但他们批准了这个类!

https://referencesource.microsoft.com/system.data/系统/数据/SqlClient SqlDataReader.cs

这表示/暗示它被批准了:

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

然而,这未能包括它在最近批准的列表:

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

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