.Net游标中的Core游标

时间:2017-02-06 14:58:38

标签: c# .net sql-server asp.net-core cursor

我正忙着研究.Net核心Web应用程序,我想知道是否可以在另一个游标中执行游标。

我有以下代码,我认为可以使用

string string = null;
SqlCommand collections_cur = null;
SqlCommand headings_cur = null;
int cl_idno = 0;

sqlserv.Open();

string = " select * from collections " +
         " where cl_idno >= @cl_idno ";
collections_cur = new SqlCommand(string, sqlserv);

string = " select * from headings " +
         " where hd_cl_idno = @hd_cl_idno ";
headings_cur = new SqlCommand(string, sqlserv);

collections_cur.Parameters.Add(new SqlParameters("cl_idno", 1));
using(SqlDataReader reader1 = collections_cur.ExecuteReader())
{

    while(reader1.Read())
    {

        // some stuff

        cl_idno = reader1.GetInt32(0);

        headings_cur.Parameters.Add(new SqlParameters("hd_cl_idno", cl_idno));
        using(SqlDataReader reader2 = headings_cur.ExecuteReader())
        {

            while(reader2.Read())
            {

                // more stuff

            }

        }

    }

}

sqlserv.Close();

以上错误导致以下错误

InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.

我认为它会分别对待reader1和reader2,但我不确定如何正确使用第二个DataReader对象。

PS

我知道我可以使用

使用单个游标执行此操作
select * from collections
left join headings on hd_cl_idno = cl_idno
where cl_idno >= 1

但我正在使用这个简化的代码,以便易于阅读。有些情况下我需要游标中的游标,而这段代码只是为了说明问题

1 个答案:

答案 0 :(得分:0)

这似乎是C#开发人员不赞成的,但无论如何我都有一个解决方案,如果它可能让任何人受益。您应该自担风险使用它,或者不使用它,但它对我有用。

我对代码进行了以下调整

//
// define and initialize variables
//

string credentials = null;
SqlConnection sqlserv = null;
string lv_string = null;
SqlCommand collections_cur = null;
SqlCommand headings_cur = null;
int cl_idno = 0;

//
// connect to database
// MultipleActiveResultSets=True was added
// to allow usage of multiple cursors
//

credentials = "Data Source=(localdb)\\MSSQLLocalDB;" +
              "Initial Catalog=rescratch;" +
              "Integrated Security=True;" +
              "Connect Timeout=30;" +
              "Encrypt=False;" +
              "TrustServerCertificate=True;" +
              "ApplicationIntent=ReadWrite;" +
              "MultipleActiveResultSets=True;" +
              "MultiSubnetFailover=False";

sqlserv = new SqlConnection(credentials);

sqlserv.Open();

//
// declare cursors
//

lv_string = " select * from collections " +
            " where cl_idno >= @cl_idno ";
collections_cur = new SqlCommand(lv_string, gv_sqlserv);
collections_cur.Parameters.Add(new SqlParameters("cl_idno", 0));

lv_string = " select * from headings " +
            " where hd_cl_idno = @hd_cl_idno ";
headings_cur = new SqlCommand(lv_string, gv_sqlserv);
headings_cur.Parameters.Add(new SqlParameters("hd_cl_idno", 0));

//
// main cursor
//

// set parameter
collections_cur.Parameters["cl_idno"].Value = 1;
using(SqlDataReader lv_reader1 = collections_cur.ExecuteReader())
{

    while(lv_reader1.Read())
    {

        // some stuff

        cl_idno = lv_reader1.GetInt32(0);

        //
        // sub cursor
        //

        // set parameter
        headings_cur.Parameters["hd_cl_idno"].Value = cl_idno;
        using(SqlDataReader lv_reader2 = headings_cur.ExecuteReader())
        {

            while(lv_reader2.Read())
            {

                // more stuff

            }

        }

    }

}

sqlserv.Close();