我正忙着研究.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
但我正在使用这个简化的代码,以便易于阅读。有些情况下我需要游标中的游标,而这段代码只是为了说明问题
答案 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();