有一个表NodeRelation
两个字段PNode(父节点),CNode(子节点)
PNode与CNode的值相互联系,表示父子关系
值如下:
    PNode   CNode                  图示:
     0        1                            0
     0        2                           / \                          
     1        1                          1   2
     2        3                             / \    
     2        4                            3   4
     3        3                           
     4        4
     .        .
     .        .
表示:0为根节点,1为0的子节点且其自身无子节点,2为0的根节点其自身有
      3与4两个子节点,3、4无子节点,........。
现要求:任选一节点,求出其下的所有节点(例如:选中0则1、2、3、4都要求出),
并把求出节点存入一ListBox中(所有值都是string类型)。

解决方案 »

  1.   

    procedure InsertList(FatherNode:string);
    var
      qry:TADOQuery;
    begin
      qry:=TADOQuery.create(nil);
      qry.connection:=ADOConnection1;
      qry.sql.text:='select * from NodeRelation where pnode='+#39+FatherNode+#39;
      qry.open;
      while not qry.eof do begin
        ListBox1.items.add(qry.fieldbyname('pnode').asstring);
        if qry.fieldbyname('pnode').asstring<>qry.fieldbyname('cnode').asstring then
          insertlist(qry.fieldbyname('cnode').asstring);
        qry.next;
      end;
      qry.free;
    end;在網吧寫的,沒有測試過,你試試!
      

  2.   

    以下测试通过:
       //adoquery1 用来以主表table2的内容,建立临时表 table1
       //table1,tabel2中两字段a 代表主结点,b 代表子结点
       //adotable1与临时表table1相联,为操作表
       //listBox1 显示结果
       //Edit1 输入查询结点编号procedure TForm1.Button1Click(Sender: TObject);
    Function loop(filterstr:string):string;
     var
     str:string;
     begin
       with adotable1 do
       begin
         Filter:='a='+Filterstr;  //在临时表中找出该结点记录
         Filtered:=True;
         if Recordcount=0 then
         Exit     //没有该结点退出
         else
         begin
           First;
           while not eof do
           begin
               if FieldByName('a').asstring=FieldByName('b').asstring then
                  begin
                 // ListBox1.Items.Add(FieldByName('b').AsString);
                  Exit;   //子结点值同主结点,没有子结点退出
                  end
                else
                  begin
                  ListBox1.Items.Add(FieldByName('b').AsString); //添加子结点
                  str:=FieldByName('b').AsString;    //记录子结点值,以便继续寻找
                  delete;                            //结点添加完后从临时表中删除
                  Loop(str);                        //  寻找子结点的子结点
                  Filter:='a='+Filterstr;           //重新选出该结点的记录
                  Filtered:=True;
                  end;
            end;//while
          Filtered:=False;
         end;    //else
       end;  //with
     end;  //funciton
    var
    str,sqlStr:string;
    begin     str:=Edit1.Text;       //建立临时表table1 a字段代表主结点,b结点代表子结点
         sqlstr:='delete table1 '+
                 'insert into table1 (a,b) select a,b from table2';
         with adoquery1 do
         begin
          sql.Clear;
          sql.Add(sqlstr);
          ExecSql;
         end;     adoTable1.active:=False;    //更新临时表内容
         adoTable1.Active:=True;     ListBox1.Items.Clear;   //清除上次查询内容     with adoTable1 do
         begin
         if not locate('a',str,[]) then   //这位需要查询的结点记录
         begin
         showMessage('无此结点');
         abort;
         end
         else
         loop(str);
         end;//wtih
    end;
      

  3.   

    用存储过程也可以,我写的展BOM的就是这样,以数行结构显示,支持选定层次查询