作者:痴情季豪_726 | 来源:互联网 | 2023-09-14 15:48
有一个地区表(AR_AREA),如:
AR_PK AR_NAME AR_PID
1 广东 0
2 广西 0
3 广州 1
4 东莞 1
5 桂林 2
6 海珠区 3
7 天河区 3
有一个单位表(UN_UNIT),如:
UN_PK UN_ANME UN_AREA
1 AA 1
2 BB 3
3 CC 7
我的目的是根据地区ID(UN_AREA),把对应的公司的ID(UN_PK)取出来,如我限制的地区是:用一个变量Name="1,"来表示,也就是取出广东所有单位的信息,这时就应该把地区是广州(3)、东莞(4)、海珠区 (6)、天河区(7)的单位取出来
DataTable [] DT = new DataTable[2];
string Name = "1,";
SqlDataAdapter sda = null;
DataSet ds = null;
private void cLoad()
{
string [] att = Name.Split(',');
for(int i=0;i
{
cLoadUnit(att[i]);
}
}
private void cLoadUnit(string PID)
{
string SQL = "SELECT * FROM UN_UNIT WHERE UN_AREA = "+ PID;
sda = new SqlDataAdapter(SQL,con);
ds = new DataSet();
ds = sda.fill("AA");
DT[0] = ds.Tables["AA"];
for(int i=0;i {
ComID.Text += DT[0].Rows[i]["UN_PK"].ToString() + ",";
}
string cSQL = "SELECT * FROM AR_AREA WHERE AR_SUPERIORAREA ="+PID;
sda = new SqlDataAdapter(cSQL,con);
ds = sda.fill("BB")
DT[1] = ds.Tables["BB"];
for(int i=0;i {
LoadUnit(DT[1].Rows[i]["AR_PK"].ToString());
}
}
最终的结果应该是ComID.Text = "1,2,3,";但事实却是这样:东莞(3)\天河区(7)这两条纪录不会被作为父ID递归下去,因为那时DT[1].Rows.Count已被清0了,因此ComID.Text="1,2,";
不知道我表达得是否清楚,有时间和有兴趣的朋友能帮我调试吗.
15 个解决方案
select *
fro Ar_Area as a, UN_UNIT as u
where a.AR_PK=u.UN_AREA and (a.ARPK=地区编号 or a.AR_PID=地区编号)
最简单的办法就是在地区表上加一个字段,AR_PATH,表示每个节点的路径,如:
AR_PK AR_NAME AR_PID AR_PATH
1 广东 0 /1
2 广西 0 /2
3 广州 1 /1/3
4 东莞 1 /1/4
5 桂林 2 /2/5
6 海珠区 3 /1/3/6
7 天河区 3 /1/3/7
这样,如果取广东的所有地区,就查找AR_PATH以/1开头的记录,如果要找广州以下的地区,就找以/1/3开头的记录。这种做法的效率肯定会比递归来得高,但维护的时候会比较麻烦,一旦更改某个节地区的上级地区,那它和它的下级地区的AR_PATH也必须更改。
同意 effun(一风) .这样设计时比较好,查询是不用递归.
string strCitys = "";
DataTable dt = DataClass.ExecuteDataTable("Select * FROM AR_AREA");
this.cLoadUnit(ref strCitys,ref dt,"1");
if(strCitys != "")
{
strCitys = strCitys.Substring(0,strCitys.Length-1);
}
Response.Write(strCitys);
private void cLoadUnit(ref string Citys,ref DataTable dt ,string PID)
{
DataRow[] rows = dt.Select("AR_PID='"+ PID+"'");
for(int i=0;i {
Citys += rows[i]["AR_PK"].ToString() +",";
this.cLoadUnit(ref Citys,ref dt,rows[i]["AR_PK"].ToString());
}
}
用一条SQL批处理命令就可以了。
string Sql=@"
declare @tmp table(ar_pk int)
insert @tmp (ar_pk) select ar_pk from AR_AREA where ar_pk=@param
declare @deep int --防止你的AR_AREA有循环
set @deep=0
while @@rowcount>0 and @deep<5 begin
insert @tmp(ar_pk) select ar_pk from AR_AREA as a
inner join @tmp as t on a.ar_pk=t.ar_pid
set @deep=@deep+1
end
select un_pk from un_unit as u
inner join @tmp as t on u.ar_pk=u.un_area";
查询时在你的DBCommandParameter参数中给出@param参数值。
最后一句有一个字母t写错了:
declare @tmp table(ar_pk int)
insert @tmp (ar_pk) select ar_pk from AR_AREA where ar_pk=@param
declare @deep int --防止你的AR_AREA有循环
set @deep=0
while @@rowcount>0 and @deep<5 begin
insert @tmp(ar_pk) select ar_pk from AR_AREA as a
inner join @tmp as t on a.ar_pk=t.ar_pid
set @deep=@deep+1
end
select un_pk from un_unit as u
inner join @tmp as t on t.ar_pk=u.un_area
许多数据库程序都可以用SQL来计算,不要使用c#来写。这类从数据库计算问题,直接到SQL Server论坛(或者相应的数据库论坛)去问就行了。这个程序还是很简单的,许多复杂的计算程序的逻辑要比这个复杂的多(往往需要inner join五六个),用一两条SQL查询要比你写上几百行代码来的清楚、快速的多。
在这类数据库查询应用方面,如果你不懂SQL,是很吃亏的。如果一个项目需要稍微复杂的面向数据库编程,使用懂SQL的程序员来写是很重要的。
sp1234 ,你写的这类的SQL语句我真的不懂啊..我以前学的都是些简单的.这类的语句我都不知从哪里开始学,能给个方向我吗?
sp1234,好像执行你那段代码有些错误啊.能写个详细的步骤给我吗.