通过递归,用ADO 访问数据库生成树形菜单出现问题

时间:2022-02-22 12:43:26
通过调用递归生成树形菜单时,在递归进入最里层要退出的时候,发现递归之前查询的数据表里面的数据都没有了,导致在执行
 m_tree.InsertItem((_bstr_t)m_DataSet.GetFields()->Item[L"DeptName"]->Value,pNode);时,出现数据已被删除的问题。 难道访问数据库只能打开一张表? 递归打开新表查询后,原来的查询结果就没有了? 大神们知道这是怎么回事吗?  很着急!!!
数据库中的表:
通过递归,用ADO 访问数据库生成树形菜单出现问题
程序运行时报错:
通过递归,用ADO 访问数据库生成树形菜单出现问题
忽略报错后执行的结果:
通过递归,用ADO 访问数据库生成树形菜单出现问题

程序只是在递归进去时成功获得数据了,在递归出来时,SQL查询的结果没有了(调试时发现的),导致了错误!怎么解决?
void CDeptManager::GetNode(HTREEITEM pNode, int nPid)
{
HTREEITEM node;
CString str;
str.Format(_T("Select DeptName,ID From tab_Dept where pid = '%d'"),nPid); //查询语句
m_DataSet.Open(str); //打开记录集
int ID;
_variant_t value;
int counts = m_DataSet.GetRecordCount();
for(int i = 0;i<counts;i++)
{
try
{

node = m_tree.InsertItem((_bstr_t)m_DataSet.GetFields()->Item[L"DeptName"]->Value,pNode); //部门名称并插入节点

value = (_variant_t)m_DataSet.GetFields()->Item[L"ID"]->Value; //编号

ID = value.intVal;
m_tree.SetItemData(node,ID); //与节点关联
if (ID)
{
GetNode(node,ID);
}
//m_DataSet.Next(); //记录下移
}
catch(_com_error e)
{
AfxMessageBox(e.Description());
return;
}
}

通过递归,用ADO 访问数据库生成树形菜单出现问题

9 个解决方案

#1


楼主不要使用这种重复查询的功能了,建议使用 with as 块,一次性都查出来 ;

#2


可以考虑直接用 sql的方式,写个递归查询,这样比较高效,而不是通过程序来实现递归。

具体sql server的递归,可以用with 的方式写,百度一下,很多的

#3


这样数据库连接次数太多了。楼主可以按照楼上两位的说法,用with as 方法在数据库中递归读出数据老。也可以把所有数据都读出来,然后在程序里用lamdba处理结构。

#4


引用 2 楼 yupeigu 的回复:
可以考虑直接用 sql的方式,写个递归查询,这样比较高效,而不是通过程序来实现递归。

具体sql server的递归,可以用with 的方式写,百度一下,很多的

直接用sql方式的话,如果我在MFC程序中需要执行添加,删除等操作,也没问题吗?

#5


引用 4 楼 chengjinlang 的回复:
Quote: 引用 2 楼 yupeigu 的回复:

可以考虑直接用 sql的方式,写个递归查询,这样比较高效,而不是通过程序来实现递归。

具体sql server的递归,可以用with 的方式写,百度一下,很多的

直接用sql方式的话,如果我在MFC程序中需要执行添加,删除等操作,也没问题吗?


没问题的。

你执行完添加,后者删除之后,可以重新执行一下这个递归sql,重新刷一下控件

#6


引用 3 楼 sinat_28984567 的回复:
这样数据库连接次数太多了。楼主可以按照楼上两位的说法,用with as 方法在数据库中递归读出数据老。也可以把所有数据都读出来,然后在程序里用lamdba处理结构。
通过递归,用ADO 访问数据库生成树形菜单出现问题

#7


头像不错 通过递归,用ADO 访问数据库生成树形菜单出现问题

#8


通过递归,用ADO 访问数据库生成树形菜单出现问题

#9


引用 5 楼 yupeigu 的回复:
Quote: 引用 4 楼 chengjinlang 的回复:

Quote: 引用 2 楼 yupeigu 的回复:

可以考虑直接用 sql的方式,写个递归查询,这样比较高效,而不是通过程序来实现递归。

具体sql server的递归,可以用with 的方式写,百度一下,很多的

直接用sql方式的话,如果我在MFC程序中需要执行添加,删除等操作,也没问题吗?


没问题的。

你执行完添加,后者删除之后,可以重新执行一下这个递归sql,重新刷一下控件
m_DataSet.Open(_T( "with district as (select * from tab_Dept where ID = 1 union all select a.* from tab_Dept a,district b where a.PID = b.ID) select * from district"));
这条语句执行不了,查询了下执行后的结果int counts = m_DataSet.GetRecordCount();     得到count=-1
m_DataSet.Open(_T("Select * From tab_User"));  
但是这条就没问题
这是什么原因?

#1


楼主不要使用这种重复查询的功能了,建议使用 with as 块,一次性都查出来 ;

#2


可以考虑直接用 sql的方式,写个递归查询,这样比较高效,而不是通过程序来实现递归。

具体sql server的递归,可以用with 的方式写,百度一下,很多的

#3


这样数据库连接次数太多了。楼主可以按照楼上两位的说法,用with as 方法在数据库中递归读出数据老。也可以把所有数据都读出来,然后在程序里用lamdba处理结构。

#4


引用 2 楼 yupeigu 的回复:
可以考虑直接用 sql的方式,写个递归查询,这样比较高效,而不是通过程序来实现递归。

具体sql server的递归,可以用with 的方式写,百度一下,很多的

直接用sql方式的话,如果我在MFC程序中需要执行添加,删除等操作,也没问题吗?

#5


引用 4 楼 chengjinlang 的回复:
Quote: 引用 2 楼 yupeigu 的回复:

可以考虑直接用 sql的方式,写个递归查询,这样比较高效,而不是通过程序来实现递归。

具体sql server的递归,可以用with 的方式写,百度一下,很多的

直接用sql方式的话,如果我在MFC程序中需要执行添加,删除等操作,也没问题吗?


没问题的。

你执行完添加,后者删除之后,可以重新执行一下这个递归sql,重新刷一下控件

#6


引用 3 楼 sinat_28984567 的回复:
这样数据库连接次数太多了。楼主可以按照楼上两位的说法,用with as 方法在数据库中递归读出数据老。也可以把所有数据都读出来,然后在程序里用lamdba处理结构。
通过递归,用ADO 访问数据库生成树形菜单出现问题

#7


头像不错 通过递归,用ADO 访问数据库生成树形菜单出现问题

#8


通过递归,用ADO 访问数据库生成树形菜单出现问题

#9


引用 5 楼 yupeigu 的回复:
Quote: 引用 4 楼 chengjinlang 的回复:

Quote: 引用 2 楼 yupeigu 的回复:

可以考虑直接用 sql的方式,写个递归查询,这样比较高效,而不是通过程序来实现递归。

具体sql server的递归,可以用with 的方式写,百度一下,很多的

直接用sql方式的话,如果我在MFC程序中需要执行添加,删除等操作,也没问题吗?


没问题的。

你执行完添加,后者删除之后,可以重新执行一下这个递归sql,重新刷一下控件
m_DataSet.Open(_T( "with district as (select * from tab_Dept where ID = 1 union all select a.* from tab_Dept a,district b where a.PID = b.ID) select * from district"));
这条语句执行不了,查询了下执行后的结果int counts = m_DataSet.GetRecordCount();     得到count=-1
m_DataSet.Open(_T("Select * From tab_User"));  
但是这条就没问题
这是什么原因?