首先说下树节点对应的表的基本结构,必需要有的字段(节点编号,父节点编号,节点名称),其他字段根据你开发的需要添加
从添加节点开始,一开始就取出表中最大节点编号,每次添加节点的时候,该节点编号增加1;
添加节点的时候我们有2个步骤,首先是给treeview树种建立节点;其次是给数据库中添加相应的节点记录;
添加节点树的时候,需要注意的是要把该节点的节点编号加入到该节点的data属性中.
在数据库中加入节点记录的时候,节点编号和父节点编号都不能少,如果是第0层节点,那么该节点的父节点编号是'0'(这种情况你自己定义,我在这里设为'0')
显示节点我写了一个通用函数来实现的
删除节点由于要删除该节点及其所有后代节点在表中的记录,这个在sql server中好像没有什么好的语句,我写了一个存储过程来实现的

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ShellAPI, DB, ADODB; type
TForm1 = class(TForm)
tv1: TTreeView;
btn_addtj: TButton;
btn_addzjd: TButton;
btn_del: TButton;
edt_jdmc: TEdit;
Label1: TLabel;
btn_xs: TButton;
con1: TADOConnection;
qry1: TADOQuery;
qry2: TADOQuery;
procedure btn_addtjClick(Sender: TObject);
procedure btn_addzjdClick(Sender: TObject);
procedure btn_delClick(Sender: TObject);
procedure btn_xsClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; var
Form1: TForm1;
maxdwbh: integer;
procedure addChildNodes(tv: TTreeView; fnode: TTreeNode; qry: TADOQuery); overload;
procedure addChildNodes(tv: TTreeView; fnode: TTreeNode; qry: TADOQuery; tab, jdbh, jdmc, fjdbh, nilfjdbh: string); overload;
implementation {$R *.dfm}
{
功能:在一个treeview中显示数据库中父子节点,并且把节点的编号存入自己的data属性中
参数:tv 展示树
fnode 表示tv中的节点,第一次调用通常这个节点取nil
qry 一个ADOQuery控件,用来做查询
tab 我们的父子节点存放的数据库表名称
jdbh tab中节点编号代表的字段名称
jdmc tab中节点名称代表的字段名称
fjdbh tab中父节点编号代表的字段名称
nilfjdbh 树中第0级节点的父节点字段给分配的值
注意:我们的树在添加(子)节点的时候也要把它的节点的编号存入到该节点的data属性中
} procedure addChildNodes(tv: TTreeView; fnode: TTreeNode; qry: TADOQuery; tab, jdbh, jdmc, fjdbh, nilfjdbh: string);
var
sql, fdwbh: string;
node, newnode: TTreeNode;
pinteger: ^string;
begin
//判断表中有没有节点,如果连第0级节点都不存在,我们也就不需要显示树了
sql := 'select * from tab where fjdbh=''' + nilfjdbh + '''';
qry.Close;
qry.SQL.Clear;
qry.SQL.Add(sql);
qry.Open;
if not qry.IsEmpty then
begin
if fnode = nil then
fdwbh := nilfjdbh
else
fdwbh := string(fnode.data^);
//取出节点fnode的全部子节点的记录
sql := 'select ' + jdbh + ',' + jdmc + ',' + fjdbh + ' from ' + tab + ' where ' + fjdbh + '=''' + fdwbh + ''' order by ' + jdbh;
qry.Close;
qry.SQL.Clear;
qry.SQL.Add(sql);
qry.Open;
//树中加入子节点
if not qry.IsEmpty then //有子节点
begin
//添加一个节点的所有子节点
qry.First;
while not qry.Eof do
begin
newnode := tv.Items.AddChild(fnode, qry.fieldbyname(jdmc).AsString);
New(pinteger);
pinteger^ := qry.fieldbyname(jdbh).AsString;
newnode.Data := pinteger;
qry.Next;
end;
//定位下一个该操作的节点
if fnode = nil then
node := tv.Items.GetFirstNode
else
node := fnode.getFirstChild;
//递归调用对下一个子节点进行同样的操作
addChildNodes(tv, node, qry, tab, jdbh, jdmc, fjdbh, nilfjdbh);
end else //没有子节点的情况,取它的下一个兄弟节点递归调用
begin
node := fnode.GetNext;
if node <> nil then
addChildNodes(tv, node, qry, tab, jdbh, jdmc, fjdbh, nilfjdbh);
end;
end;
end; procedure addChildNodes(tv: TTreeView; fnode: TTreeNode; qry: TADOQuery);
var
fdwbh: Integer;
sql: string;
node, newnode: TTreeNode;
Pdata: ^Integer;
begin
if fnode = nil then
fdwbh :=
else
fdwbh := Integer(fnode.data^);
//取出节点fnode的全部子节点的记录
sql := 'select dwbh,dwmc,fdwbh from zzjgbmb where fdwbh=' + inttostr(fdwbh) + ' order by dwbh';
qry.Close;
qry.SQL.Clear;
qry.SQL.Add(sql);
qry.Open;
//树中加入子节点
if not qry.IsEmpty then //有子节点
begin
//添加一个节点的所有子节点
qry.First;
while not qry.Eof do
begin
newnode := tv.Items.AddChild(fnode, qry.fieldbyname('dwmc').AsString);
New(Pdata);
Pdata^ := qry.fieldbyname('dwbh').AsInteger;
newnode.Data := Pdata;
qry.Next;
end;
//定位下一个该操作的节点
if fnode = nil then
node := tv.Items.GetFirstNode
else
node := fnode.getFirstChild;
//递归调用对下一个节点进行同样的操作
addChildNodes(tv, node, qry);
end else //没有子节点的情况
begin
node := fnode.GetNext;
if node <> nil then
addChildNodes(tv, node, qry);
end;
end; procedure TForm1.btn_addtjClick(Sender: TObject);
var
jdmc, sql: string;
fdwbh: integer;
node, newnode: TTreeNode;
pinteger: ^integer;
begin
try
node := tv1.Selected;
jdmc := edt_jdmc.text;
newnode := tv1.Items.add(node, jdmc);
maxdwbh := maxdwbh + ;
New(pinteger);
pinteger^ := maxdwbh;
newnode.data := pinteger; if node = nil then
fdwbh :=
else if node.Level = then
fdwbh :=
else
fdwbh := Integer(node.Parent.data^);
sql := 'insert into zzjgbmb(dwbh,fdwbh,dwmc) values(' + inttostr(maxdwbh) + ',' + inttostr(fdwbh) + ',''' + jdmc + ''')';
qry1.Close;
qry1.SQL.Clear;
qry1.SQL.Add(sql);
qry1.ExecSQL;
ShowMessage('单位"' + jdmc + '"添加成功!');
except
on e: Exception do
ShowMessage(e.Message);
end;
end; procedure TForm1.btn_addzjdClick(Sender: TObject);
var
jdmc, sql: string;
fdwbh: integer;
node, newnode: TTreeNode;
pinteger: ^integer;
begin
try
jdmc := edt_jdmc.text;
node := tv1.Selected;
newnode := tv1.Items.AddChild(node, jdmc);
maxdwbh := maxdwbh + ;
New(pinteger);
pinteger^ := maxdwbh;
newnode.Data := pinteger;
if node = nil then
Exit
else
fdwbh := Integer(node.data^); sql := 'insert into zzjgbmb(dwbh,fdwbh,dwmc) values(' + inttostr(maxdwbh) + ',' + inttostr(fdwbh) + ',''' + jdmc + ''')';
qry1.Close;
qry1.SQL.Clear;
qry1.SQL.Add(sql);
qry1.ExecSQL;
ShowMessage('单位"' + jdmc + '"添加成功!');
except
on e: Exception do
ShowMessage(e.Message);
end;
end; procedure TForm1.btn_delClick(Sender: TObject);
var
node: TTreeNode;
dwbh: integer;
sql: string;
begin
try
node := tv1.Selected;
node.Delete;
dwbh := Integer(node.data^);
sql := 'exec p_zzjgbmb_delnode ' + inttostr(dwbh);
qry1.Close;
qry1.SQL.Clear;
qry1.SQL.Add(sql);
qry1.ExecSQL;
except
on e: Exception do
ShowMessage(e.Message);
end;
end; procedure TForm1.btn_xsClick(Sender: TObject);
begin
try
tv1.Items.Clear;
addChildNodes(tv1, nil, qry1, 'zzjgbmb', 'dwbh', 'dwmc', 'fdwbh', '');
except
on e: Exception do
ShowMessage(e.Message);
end;
end; procedure TForm1.FormCreate(Sender: TObject);
var
sql: string;
begin
try
maxdwbh := ;
sql := 'select max(dwbh) maxdwbh from zzjgbmb';
qry1.Close;
qry1.SQL.Clear;
qry1.SQL.Add(sql);
qry1.Open;
if not qry1.isempty then
begin
qry1.First;
maxdwbh := qry1.fieldbyname('maxdwbh').AsInteger;
end;
except
on e: Exception do
showmessage(e.message);
end;
end; end.

删除节点及其后代节点的存储过程

create procedure [dbo].[p_zzjgbmb_delnode](@dwbh int)
as
begin
declare @tmp1 table (dwbh int)
declare @tmp2 table (dwbh int)
declare @tmp3 table (dwbh int) insert into @tmp1 select dwbh from zzjgbmb where fdwbh=@dwbh
insert into @tmp3 select dwbh from @tmp1 while exists(select dwbh from zzjgbmb where fdwbh in (select dwbh from @tmp1))
begin
delete @tmp2
insert into @tmp2 select dwbh from zzjgbmb where fdwbh in (select dwbh from @tmp1)
delete @tmp1
insert into @tmp1 select dwbh from @tmp2
insert into @tmp3 select dwbh from @tmp1
end delete from zzjgbmb where dwbh in (select dwbh from @tmp3);
delete from zzjgbmb where dwbh = @dwbh
end

简单的界面

最新文章

  1. android: startActivityForResult用法详解
  2. eclipse插件:打开选中文件所在的目录
  3. php的两个符号@和&amp;---php总会要知道的系列
  4. Linux重定向的理解
  5. linux源码阅读笔记 move_to_user_mode()解析
  6. iOS,面试必看,最全梳理
  7. java内存模型分析2
  8. Zedboard甲诊opencv图像处理(二)
  9. jQuery的ajax详解
  10. mysql在cmd命令下执行数据库操作
  11. Cookie禁用 获取session
  12. gitlab安装后吃内存的解决办法
  13. 收获,不止_Oracle读书笔记
  14. Linux运维之——每日小技巧,获取网站请求数的前20个IP
  15. 猫都能学会的Unity3D Shader入门指南(一)
  16. 快速切题 sgu115. Calendar 模拟 难度:0
  17. 项目中调试SQLServer 方便的查看SQL语句的执行时间的方法
  18. 使用脚本实现killproc的功能
  19. 25、springboot与缓存整合Redis
  20. Nodejs操作MongoDB数据库示例

热门文章

  1. mysql打开报错2013解决办法
  2. MongoDB同步机制
  3. elasticsearch查询:启动项目报错No property ... found for...Did you mean &#39;...&#39;?
  4. [唐胡璐]Android自动化- 测试环境搭建中遇到的问题
  5. idea 包.路径切换为目录结构
  6. 设置easyUI-dialog窗口居中显示
  7. 使用math中的hypot实现向量
  8. 007_FreeROTS队列
  9. Tpcc-mysql 结果解读
  10. loj#6285 数列分块入门 9 ( 回 滚 )