首先说下树节点对应的表的基本结构,必需要有的字段(节点编号,父节点编号,节点名称),其他字段根据你开发的需要添加
从添加节点开始,一开始就取出表中最大节点编号,每次添加节点的时候,该节点编号增加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

简单的界面

delphi7 treeview + 数据库 实现动态节点维护的更多相关文章

  1. Redis Cluster 集群节点维护 (三)

    Redis Cluster 集群节点维护: 集群运行很久之后,难免由于硬件故障,网络规划,业务增长,等原因对已有集群进行相应的调整,比如增加redis nodes 节点,减少节点,节点迁移,更换服务器 ...

  2. 修复jquery.treeview的增加子节点的方法的bug

    1.修复理由 在一个android项目中用到了treeview控件(本来自己通过android的原生api实现了一个http://www.cnblogs.com/Mr-Nobody/p/3527688 ...

  3. delphi TreeView修改选中的节点的颜色和背景

      TreeView修改选中的节点的颜色和背景     TCustomDrawTarget = (dtControl, dtItem, dtSubItem);   TCustomDrawStage = ...

  4. Oracle数据库之动态SQL

    Oracle数据库之动态SQL 1. 静态SQLSQL与动态SQL Oracle编译PL/SQL程序块分为两个种:一种为前期联编(early binding),即SQL语句在程序编译期间就已经确定,大 ...

  5. Bootstrap treeview增加或者删除节点

    参考(AddNode: http://blog.csdn.net/qq_25628235/article/details/51719917,deleteNode:http://blog.csdn.ne ...

  6. C#上移,下移TreeView中的树节点顺序

    C#上移,下移TreeView中的树节点顺序 2009-08-12 20:10 1494人阅读 评论(2) 收藏 举报 c#buttonobjectnullstring C#中,通过单击上移,下移按钮 ...

  7. 根据数据库记录动态生成C#类及其公共属性并动态执行的解决方案

    原文:根据数据库记录动态生成C#类及其公共属性并动态执行的解决方案 问题: C#中,想动态产生这么一个类: public class StatisticsData    {        public ...

  8. 重写TreeView,多层级节点下批量显示图片,图片支持缩略图和文件名列表切换,支持调用者动态匹配选中,支持外界拖入图片并添加到对应节点下

    1.先看下整体效果 2.前端代码 <UserControl x:Class="iPIS.UI.Base.Tree.ImageTreeControl" xmlns=" ...

  9. 在DELPHI中用TreeView控件从数据库中动态装载信息

    1.PInfo表结构ID VARCHAR(50)FullName VARCHAR(50)ParentID VARCHAR(50) 2.Unit文件unit Info; interface uses  ...

随机推荐

  1. webstorm如何调试vue项目的js

    webstorm如何调试vue项目的js webstormvuewebstorm调试jsjs 1.编辑调试配置,新建JavaScript调试配置,并设置要访问的url地址,如下图所示: 在URL处填写 ...

  2. 算法笔记--BSGS && exBSGS 模板

    https://www.cnblogs.com/sdzwyq/p/9900650.html 模板: unordered_map<int, int> mp; LL q_pow(LL n, L ...

  3. Navicate 12 for mysql

    先下载安装好 navicat工具,在下载下面的工具 链接:https://pan.baidu.com/s/1Y-IOrbnhvhlS6Y3lpABLQg密码: nktc 选其中的一个 请根据自己安装N ...

  4. pyside pyqt QPushbuttion 无边框 stylesheet border:none

    pyside pyqt QPushbuttion 无边框 stylesheet border:none 在 stylesheet 中添加 border:none 即可 效果是字体到边缘之间的间隙为0, ...

  5. Hibernate初探之单表映射——第二章:Hibernate进阶

    第二章:Hibernate进阶 1.hibernate.cfg.xml常用配置 2.session 简介 3.transaction简介 4.session详解 5.对象关系映射常用配置 1.hibe ...

  6. springboot mybatis 的SQL异常不输出错误到控制台问题排查

    项目中使用springboot集成 mybatis,运行过程中查询SQL列在表中不存在,但系统不输出任何错误到控制台 但SQL是打印的,只是没有任何异常信息 将SQL复制出来到数据库中运行,才发现错误 ...

  7. python_tkinter事件

    1.事件绑定函数(3个) 组件.bind('事件类型',事件函数) 为一个组件绑定一个操作 组件.bind_class('组件类型','事件类型',事件函数) 为一个类组件绑定一个操作 组件.bind ...

  8. js中in关键字的使用方法

    1.for...in 对数组或对象的循环/迭代操作 对于数组循环出来的是数组元素:对于对象循环出来的是对象属性 2.判断对象是否是数组/对象的元素/属性 格式:(变量 in 对象) 当‘对象’是数组时 ...

  9. 简单的JAVAWeb选课系统

    该系统管理员可以添加和删除学生.教师,教师可以修改自己信息.添加课程.浏览自己课程,学生可以修改自己的信息.选课.浏览全部课程. 首先展示文件: 然后就是一次展示代码: Guanli包中代码: pac ...

  10. recyclerview + cardview

    https://www.jianshu.com/p/3a1ea6f78ad5http://qwzs112.iteye.com/blog/2235410https://github.com/mukesh ...