我在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();
}
提前感谢您的帮助。这让我感到困惑,因为这是最简单的事情。
答案 0 :(得分:1)
此代码没有任何内在错误。我自己在SQL Server 2014上运行它,根据.NET Framework 4.5.2版进行编译,它可以按照您的预期运行。而且要明确的是,对于你在这里所做的事情,SQL Server和.NET Framework的版本并不重要。
我还尝试将CommandBehavior.SingleRow
传递给cmd.ExecuteReader()
并仍然返回所有行。
由于此代码确实有效,因此需要检查以下内容:
SELECT
语句的同一个数据库(和实例)。另外,请在SqlDataReader
构造中创建using()
,因为它是一个Disposable对象。
从O.P。更新:
在调用SQLCLR存储过程之前,已从发出SET ROWCOUNT 1;
的T-SQL存储过程调用SQLCLR存储过程。因此,任何查询只能返回1行。通过在调用SQLCLR存储过程之前发出SET ROWCOUNT 0;
来解决1行问题。
请注意:通常首选使用TOP ()
子句代替SET ROWCOUNT n;
。
答案 1 :(得分:0)
小心!微软有一个错误:
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
然而,这未能将其列入最近批准的名单:
(奇怪的是OracleClient在列表中!)