CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  MS-SQL Server >  基础类

取树中某一节点的所有子节点的存储过程~!

楼主lovvver(ElephantTalk.Bright)2005-04-01 14:38:49 在 MS-SQL Server / 基础类 提问

我有一个表,为树型数据设计的。  
  里面有字段dealerid(节点编号),parentid(父节点标号)等字段。  
   
  希望做一个存储过程,给任一节点的编号,然后找出其所有子节点的节点编号。  
  这个存储过程该如何写法,希望邹建等高手帮一下忙!!  
   
  如果所给的节点的个数不定(所给节点通过某一条件查询查出,可以有多条结果),要找出所有这些节点的子节点数据的union。  
   
  这个存储过程又该怎么写啊?  
  问题点数:168、回复次数:9Top

1 楼jinjazz(近身剪)回复于 2005-04-01 14:40:15 得分 50

转贴一个~~  
   
  --示例  
   
  --测试数据  
  create   table   tb(父项   varchar(10),子项   varchar(10))  
  insert   tb   select   'a001','A1'  
  union   all   select   'a001','D1'  
  union   all   select   'a001','E1'  
  union   all   select   'A1'     ,'B1'  
  union   all   select   'A1'     ,'C1'  
  union   all   select   'E1'     ,'C1'  
  union   all   select   'E1'     ,'D1'  
  union   all   select   'E1'     ,'F1'  
  go  
   
  --查询处理函数  
  create   function   f_id()  
  returns   @re   table(子项   varchar(10),[level]   int,sid   varchar(8000))  
  as  
  begin  
  declare   @l   int  
  set   @l=1  
  insert   @re   select   distinct   父项,@l,父项  
  from   tb   a  
  where   not   exists(select   *   from   tb   where   子项=a.父项)  
  while   @@rowcount>0  
  begin  
  set   @l=@l+1  
  insert   @re   select   a.子项,@l,b.sid+'>'+a.子项  
  from   tb   a,@re   b  
  where   a.父项=b.子项   and   b.[level]=@l-1  
  end  
  return  
  end  
  go  
   
  --调用函数实现分级显示  
  select   层号=level,[部件号(产品号)]=子项  
  from   f_id()  
  order   by   sid  
  go  
   
  --删除测试  
  drop   table   tb  
  drop   function   f_id  
   
  /*--结果  
   
  层号                     部件号(产品号)        
  -----------   ----------    
  1                       a001  
  2                       A1  
  3                       B1  
  3                       C1  
  2                       D1  
  2                       E1  
  3                       C1  
  3                       D1  
  3                       F1  
   
  (所影响的行数为   9   行)  
  --*/  
  Top

2 楼zjcxc(邹建)回复于 2005-04-01 14:47:25 得分 118

--树形数据查询示例  
  --作者:   邹建  
   
  if   exists   (select   *   from   dbo.sysobjects   where   id   =   object_id(N'[tb]')   and   OBJECTPROPERTY(id,   N'IsUserTable')   =   1)  
  drop   table   [tb]  
  GO  
   
  --示例数据  
  create   table   [tb]([id]   int   identity(1,1),[pid]   int,name   varchar(20))  
  insert   [tb]   select   0,'中国'  
  union     all     select   0,'美国'  
  union     all     select   0,'加拿大'  
  union     all     select   1,'北京'  
  union     all     select   1,'上海'  
  union     all     select   1,'江苏'  
  union     all     select   6,'苏州'  
  union     all     select   7,'常熟'  
  union     all     select   6,'南京'  
  union     all     select   6,'无锡'  
  union     all     select   2,'纽约'  
  union     all     select   2,'旧金山'  
  go  
   
   
   
  if   exists   (select   *   from   dbo.sysobjects   where   id   =   object_id(N'[dbo].[f_cid]')   and   xtype   in   (N'FN',   N'IF',   N'TF'))  
  drop   function   [dbo].[f_cid]  
  GO  
   
  /*--树形数据处理  
   
  查询指定id的所有子  
   
  --邹建   2003-12(引用请保留此信息)--*/  
   
  /*--调用示例  
   
  --调用(查询所有的子)  
  select   a.*,层次=b.[level]   from   [tb]   a,f_cid(2)b   where   a.[id]=b.[id]  
  --*/  
  create   function   f_cid(  
  @id   int  
  )returns   @re   table([id]   int,[level]   int)  
  as  
  begin  
  declare   @l   int  
  set   @l=0  
  insert   @re   select   @id,@l  
  while   @@rowcount>0  
  begin  
  set   @l=@l+1  
  insert   @re   select   a.[id],@l  
  from   [tb]   a,@re   b  
  where   a.[pid]=b.[id]   and   b.[level]=@l-1  
  end  
  return  
  end  
  go  
   
  --调用(查询所有的子)  
  select   a.*,层次=b.[level]   from   [tb]   a,f_cid(2)b   where   a.[id]=b.[id]  
  goTop

3 楼zjcxc(邹建)回复于 2005-04-01 14:54:36 得分 0

--如果所给的节点个数不定,那就要看你的参数是如何传递  
  --假设你通过一个字符串来传递,则可以这样写存储过程  
   
  --示例数据  
  create   table   [tb](dealerid   int   identity(1,1),parentid   int,name   varchar(20))  
  insert   [tb]   select   0,'中国'  
  union     all     select   0,'美国'  
  union     all     select   0,'加拿大'  
  union     all     select   1,'北京'  
  union     all     select   1,'上海'  
  union     all     select   1,'江苏'  
  union     all     select   6,'苏州'  
  union     all     select   7,'常熟'  
  union     all     select   6,'南京'  
  union     all     select   6,'无锡'  
  union     all     select   2,'纽约'  
  union     all     select   2,'旧金山'  
  go  
   
  --查询处理的存储过程  
  create   proc   p_qry  
  @idlist   varchar(8000)   --要查询的id列表  
  as  
  set   nocount   on  
  declare   @l   int  
  set   @l=0  
  create   table   #t(dealerid_qry   int,dealerid   int,level   int)  
  insert   #t   select   dealerid,dealerid,@l  
  from   tb    
  where   charindex(','+cast(dealerid   as   varchar)+',',','+@idlist+',')>0  
  while   @@rowcount>0  
  begin  
  set   @l=@l+1  
  insert   #t   select   b.dealerid_qry,a.dealerid,@l  
  from   tb   a,#t   b  
  where   a.parentid=b.dealerid   and   b.level=@l-1  
  end  
  select   b.dealerid_qry,a.*  
  from   tb   a,#t   b  
  where   a.dealerid=b.dealerid  
  order   by   b.dealerid_qry  
  go  
   
  --调用实现查询  
  exec   p_qry   '2,1,5'  
  go  
   
  --删除测试  
  drop   table   tb  
  drop   proc   p_qry  
   
  /*--结果  
   
  dealerid_qry   dealerid         parentid         name                                    
  ------------   -----------   -----------   --------------------    
  1                         4                       1                       北京  
  1                         5                       1                       上海  
  1                         6                       1                       江苏  
  1                         9                       6                       南京  
  1                         10                     6                       无锡  
  1                         7                       6                       苏州  
  1                         8                       7                       常熟  
  1                         1                       0                       中国  
  2                         2                       0                       美国  
  2                         11                     2                       纽约  
  2                         12                     2                       旧金山  
  5                         5                       1                       上海  
  --*/  
   
  Top

4 楼zjcxc(邹建)回复于 2005-04-01 14:57:21 得分 0

--如果所给的节点个数不定,假设你通过一个字符串来传递,则可以这样写存储过程  
  --如果要求查询结果只包含dealerid不重复的,则改为  
   
  --示例数据  
  create   table   [tb](dealerid   int   identity(1,1),parentid   int,name   varchar(20))  
  insert   [tb]   select   0,'中国'  
  union     all     select   0,'美国'  
  union     all     select   0,'加拿大'  
  union     all     select   1,'北京'  
  union     all     select   1,'上海'  
  union     all     select   1,'江苏'  
  union     all     select   6,'苏州'  
  union     all     select   7,'常熟'  
  union     all     select   6,'南京'  
  union     all     select   6,'无锡'  
  union     all     select   2,'纽约'  
  union     all     select   2,'旧金山'  
  go  
   
  --查询处理的存储过程  
  create   proc   p_qry  
  @idlist   varchar(8000)   --要查询的id列表  
  as  
  set   nocount   on  
  declare   @l   int  
  set   @l=0  
  create   table   #t(dealerid   int,level   int)  
  insert   #t   select   dealerid,@l  
  from   tb    
  where   charindex(','+cast(dealerid   as   varchar)+',',','+@idlist+',')>0  
  while   @@rowcount>0  
  begin  
  set   @l=@l+1  
  insert   #t   select   a.dealerid,@l  
  from   tb   a,#t   b  
  where   a.parentid=b.dealerid   and   b.level=@l-1  
  end  
  select   a.*  
  from   tb   a,(select   distinct   dealerid   from   #t)b  
  where   a.dealerid=b.dealerid  
  go  
   
  --调用实现查询  
  exec   p_qry   '2,1,5'  
  go  
   
  --删除测试  
  drop   table   tb  
  drop   proc   p_qry  
   
  /*--结果  
   
  dealerid         parentid         name                                    
  -----------   -----------   --------------------    
  1                       0                       中国  
  2                       0                       美国  
  4                       1                       北京  
  5                       1                       上海  
  6                       1                       江苏  
  7                       6                       苏州  
  8                       7                       常熟  
  9                       6                       南京  
  10                     6                       无锡  
  11                     2                       纽约  
  12                     2                       旧金山  
  --*/  
   
  Top

5 楼TigerSuper(菜鸟(鸟吃菜吗?))回复于 2005-04-01 14:58:40 得分 0

UP  
  怎么实现个数不确定节点的查询?Top

6 楼lovvver(ElephantTalk.Bright)回复于 2005-04-01 15:01:05 得分 0

因为我在做一个客户关系管理的东西,  
  这个树的层次就大概5-6层的样子,每层有具体名字,  
  如Fiscal   unit,reseller,agent   group,agent,sub-agent等。  
   
  每个用户(系统用户)有可能有几个身份(对应这个树的几个节点)。  
  我希望登陆以后,这个用户能够看到他所有下级节点。  
   
  因此我首先要根据登陆信息找到登陆用户的节点(>=1个),然后再根据这些节点找到这些节点对应的所有子节点的集合(DATASET)  
  希望能够用存储过程实现为好。  
  多谢了。~~  
  Top

7 楼zjcxc(邹建)回复于 2005-04-01 15:06:06 得分 0

后面的就是存储过程的处理方法,先参考,解决不了再根据实际情况问Top

8 楼lovvver(ElephantTalk.Bright)回复于 2005-04-01 15:12:08 得分 0

多谢邹老大和各位老兄!~  
  我得研究一下,啊哈~Top

9 楼winternet(冬天)回复于 2005-04-01 15:54:51 得分 0

upTop

相关问题

  • 如何通过存储过程跨服务器调用存储过程?(给出我所有的分了)
  • 如何改变存储过程的所有者
  • 关于修改树形结点的存储过程,在线等
  • 存储过程
  • 存储过程
  • 存储过程
  • 存储过程
  • 存储过程
  • 存储过程
  • 存储过程

关键词

  • 节点
  • 存储过程
  • 用户
  • 数据
  • 树
  • union
  • 所有
  • tb
  • 登陆
  • varchar

得分解答快速导航

  • 帖主:lovvver
  • jinjazz
  • zjcxc

相关链接

  • SQL Server类图书

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo