如何计算存储过程返回的行?

时间:2014-05-12 12:31:58

标签: .net sql-server tsql ado.net

我必须使用ado.net从SQL Server加载大量数据。

此数据从慢速存储过程返回。我不能将结果存储在临时表中因为我不知道结果表的结构。所以我做不了类似的事情:

CREATE TABLE #temp
(
   ID INT,
   NAME VARCHAR(100),
   ...
)
INSERT INTO #temp Exec dbo.proc @param=1

SELECT COUNT(*) FROM #temp

SELECT * FROM #temp 

因为数据集很大,我使用SqlDataReader。但是对于进步,我应该知道这些数据的行数。

    private SqlCommand _asyncCmd;
    private SqlDataReader _reader;
    private SqlConnection _con;
    private IAsyncResult _asyncResult;

    public void GetDictionaryMetadataAsync(int param)
    {
        _con = new SqlConnection(_connectionString);
        _asyncCmd = new SqlCommand("SP_procedure", _con);

        _asyncCmd.CommandType = CommandType.StoredProcedure;
        _asyncCmd.CommandTimeout = 0;
        _asyncCmd.Parameters.Add(new SqlParameter("@param", SqlDbType.Int));
        _asyncCmd.Parameters["@param"].Value = param;

        _asyncCmd.Connection.Open();

        var callback = new AsyncCallback(EndExecuteReader);
        _asyncResult = _asyncCmd.BeginExecuteReader(callback, _asyncCmd);
    }

    private void EndExecuteReader(IAsyncResult result) 
    {
        _reader = _asyncCmd.EndExecuteReader(result);

        var command = new SqlCommand("SELECT @@ROWCOUNT", _con);
        // GETTING COUNT
        var count = command.ExecuteScalar() as int?;
        if (!count.HasValue) throw new NullReferenceException();
        Count = count.Value;
    }

    public IEnumerable<object[]> GetDictionaryMetadataAsyncEnd()
    {
        _asyncResult.AsyncWaitHandle.WaitOne();

        if (!_reader.Read())
            yield break;
        var values = new object[_reader.FieldCount];

        _reader.GetValues(values);
        yield return values;

        while (_reader.Read())
        {
            _reader.GetValues(values);
            yield return values;
        }
    }

但这部分代码

        // GETTING COUNT
        var count = command.ExecuteScalar() as int?;

总是返回0。

你知道我该怎么办?

提前致谢。

1 个答案:

答案 0 :(得分:2)

您获得@@ ROWCOUNT = 0的最可能原因是在一个单独的隐含定义的数据库事务中运行命令(检查 @@ SPID 值以确保)。

解决方案是在c#代码中使用单个显式定义的事务。

注意,&#34; SET NOCOUNT ON&#34;存储过程中的选项不会对@@ROWCOUNT值产生任何影响:

  

即使SET NOCOUNT为ON,也会更新@@ ROWCOUNT函数。

PS。 &#34; MultipleActiveResultSets =真&#34; SqlConnection连接字符串的选项帮助