Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# CLR存储过程中的SqlDataReader和SqlDataAdapter仅返回第一行_C#_Sql Server_Sqlclr - Fatal编程技术网

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

C# CLR存储过程中的SqlDataReader和SqlDataAdapter仅返回第一行,c#,sql-server,sqlclr,C#,Sql Server,Sqlclr,我在SQL Server 2014上运行了一个CLR存储过程。当我执行以下代码时,数据读取器只返回结果集的第一行。SQL在单独运行时返回多行。我还尝试用SqlDataAdapter填充DataTable,但仍然只得到一行 using (SqlConnection conn = new SqlConnection("context connection=true")) using (SqlCommand cmd = new SqlCommand("SELECT * FROM some_table"

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

谢谢你事先的帮助。这确实让我感到困惑,因为这是最简单的事情。

这段代码本身并没有什么问题。我自己在SQL Server 2014上运行了它,它是根据.NET Framework 4.5.2版编译的,它可以按照您的期望工作。需要明确的是,对于您在这里所做的工作,SQL Server和.NET Framework的版本实际上并不重要

我还尝试将
CommandBehavior.SingleRow
传递到
cmd.ExecuteReader()
,但仍然返回所有行

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

  • 确保发布到与在SSMS中运行
    SELECT
    语句相同的数据库(和实例)
  • 确保已将此代码的最新版本发布到DB
  • 其他外部因素
  • 另外,请使用()构造在
    中创建
    SqlDataReader
    ,因为它是一次性对象


    从O.p.更新:

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


    请注意:通常最好使用
    TOP()
    子句,而不是
    SET ROWCOUNT n

    小心!Microsoft在这里有一个错误:

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

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

    这是参考源代码,看一看,你会发现“lock”语句-对于SQL/CLR来说是非法的,但是他们批准了这个类

    这表示/暗示其已批准:

    但这并没有将其列入最近批准的名单:


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

    您的代码看起来是正确的。我猜你在做这个例子的时候删除了这个bug。不过,我要说的一件事是,您不需要检查HasRows。我希望如此。我刚刚在SQL Server 2014、.NET 4.5.2上尝试了这段代码,它可以按照您的预期工作。您发布的代码是否与您正在运行的代码相同?是否确实要发布到运行SELECT语句的同一数据库(和实例)?你确定你已经将这段代码的最新版本发布到数据库了吗?唯一的区别可能是我的版本很可能是4.5,但我们在这里讨论的是SqlDataReader,所以这不重要,但我将尝试编译为4.5.2。另一个奇怪之处是,表没有主键,也不能给它主键。@No,使用.NET4.5应该一点问题都没有。缺少主键也是如此。我甚至只是在没有PK或聚集索引的情况下再次测试了一次,结果正如预期的那样。调用
    SqlDataReader
    传入
    CommandBehavior.SingleRow
    时有一个选项,我尝试过,但它仍然返回所有行。这就是为什么我建议再次检查您是否确实发布了此代码,并且当您运行相同的
    SELECT*
    时,代码是否位于相同的数据库中。另外,确保模式限定了表名,只是为了确保。这属于其他外部因素。正如我在前面的评论中提到的,CLR是由一个行计数设置为1的存储过程调用的,因此是在该上下文中。在调用CLR之前将行计数设置回0修复了该问题。“谢谢你的帮助。”我明白了。我只是想把它记录下来,因为代码很好,你的发现证实了我的建议,让我去别处看看。我已经更新了我的答案,包括外部因素的细节。