
 
 | 
| 技术资料  > ASP技术 > ASP技巧 : 树型结构在ASP中的简单解决 |  
树型结构在ASP中的简单解决 March 25,2004 |  
  树型结构在我们应用程序中还是很常见的,比如文件目录,BBS,权限设置,部门设置等。这些数 
 
据信息都采用层次型结构,而在我们现在的关系型数据库中很难清淅表达。那么要在程序中遇到树型 
 
结构问题该如何处理呢? 
 
  最近笔者通过一个ASP权限管理的程序轻松解决了一这问题,现在将其整理出来以飨读者。 
 
  首先,要将层次型数据模型转化为关系型数据模型。也就是说如何在我们的ACCESS,SQL SERVER 
 
,ORACLE等关系型数据库中设计这个数据结构。 
  拿个实例来讲吧,譬如下面一个数据: 
 
    文档管理 1 
      |----新建文档 2 
      |----文档修改 3 
      |----文档归档 4 
      |     |----查看归档信息 5 
      |     |----删除归档信息 6 
      |     |     |----删除历史文档 7 
      |     |     |----删除正式文档 8 
      |----系统管理 9 
      |----用户管理 10 
    人事管理 11 
    行政管理 12 
    财务管理 13 
 
  这是一个很典型的层次型结构数据,那么大家想一想,如何将其通过二维表的形式来表达呢?初 
 
看上去很难,是吧。可是仔细推敲一番还是有门路可钻的。 
 
  可以这样,将上面所有的权限视为一个权限字段,那么这个权限字段肯定是要有一个ID值的。我 
 
们再给这个关系型数据表再强行加一个字段——隶属ID字段,也就是表明这个权限是属于哪一级权限 
 
之下的,即这个ID值隶属于哪一个ID值。比如:“查看归档信息”权限ID值为“5”,它是隶属于“文 
 
档归档”权限之下的,那么它的隶属ID字段的值就应该是“4”。OK,如果这一点能理解的话,那么我 
 
们的关系转化工作也就算基本完成了。 
 
  下面我们就开始设计这张关系型数据表(以Sql Server 7.0 为例): 
 
    +-----------+-----------+-----------+-----------+----------+ 
  | 字段名   |  字段含义 | 字段类型 |  字段大小 | 字段属性 | 
    +-----------+-----------+-----------+-----------+----------+ 
    | SelfID    |  权限ID   |    Int    |     4     |    PK    | 
    | PowerName |  权限名  |   Varchar |     50    | Not Null | 
    | PowerInfo |  权限信息 |   Varchar |     500   |          | 
    | BelongID  |  隶属ID   |    Int    |     4     |          | 
    +-----------+-----------+-----------+-----------+----------+ 
 
  好了,结构设计好你就可以轻松输入你的测试数据了。 
 
  然后,我们就针对如何在网页中模仿层次结构显示这功能的ASP程序,这也是最关键的一步了。 
 
程序清单:powerlist.asp 
 
<% 
'数据库连接 
set conn=Server.CreateObject("ADODB.Connection") 
conn.open "driver={SQL Server};server=chaiwei;DATABASE=chaiwei;UID=sa;PWD=" 
 
'打开所有父层数据 
set rs=Server.CreateObject("ADODB.Recordset") 
rs.Open "select * from powers where belongid is null order by powerid",conn,1,3 
 
'层次数表态变量赋初值 
format_i=1 
 
'列表主程序段 
do while not rs.eof 
     
    '打印父层数据信息 
    response.write "<a href='powerlist.asp?SelfID=" & rs("powerid") & "&BelongID=" & rs("belongid") & "'>" & rs("powername") & "</a>" 
    response.write "<br>" 
     
    '子程序调用,子层数据处理 
    Call ListSubPower(rs("powerid")) 
     
    rs.movenext 
 
loop 
 
'关闭父层数据集 
rs.close 
set rs=nothing 
 
 
'子层数据处理子程序 
Sub ListSubPower(id) 
     
    '打开隶属于上层 powerid 的所有子层数据信息 
    set rs_sub=Server.CreateObject("ADODB.Recordset") 
    rs_sub.Open "select * from powers where belongid=" & id & " order by powerid",conn,1,3     
 
        '列子层数据 
        do while not rs_sub.eof 
             
            '层次数表态变量递进累加 
            format_i=format_i+1 
             
            '循环缩进格式控制,因为顶层与二层不需要缩进,所以从第三层开始引用此程序段 
            for i=format_i to 3 step -1 
                response.write "  |" 
                response.write "   " 
            next 
             
            '打印子层数据信息 
            response.write "  |----" 
            response.write "<a href='powerlist.asp?SelfID=" & rs_sub("powerid") & "&BelongID=" & rs_sub("belongid") &"'>" & rs_sub("powername") & "</a>" 
            response.write "<br>" 
             
            '递归调用子程序本身,对子层数据进行逐渐处理 
            ListSubPower(rs_sub("powerid")) 
         
            rs_sub.movenext 
         
        loop 
         
        '层次数表态变量递退累减         
        format_i=format_i-1     
     
    '关闭子层数据集 
    rs_sub.close 
    set rs_sub=nothing     
End Sub 
%> 
 
  powerlist.asp程序中,我们先打开顶层数据,在循环中显示出来;然后又设计一个子程序ListSubPower,通过递归算法在循环中调用,以此来打开子层数据信息,并且在子程序内部循环中又反复调用自己,以此来逐层展开深层数据。 
  另外,在程序中还用了一个静态变量format_i来控制缩进显示格式。 
 
  本文就树型结构在数据设计、程序控制方面做简单尝试,目的在于抛砖引玉,希望读者通过本文得到更多启示。 
         |  
 
 | 
  
Copyright © 2001-2008 Shenzhen Hiblue Software Team All rights reserved