1.添加根节点: hierarchyid  GetRoot()方法

--创建数据库
create table Employeeh(EmployeeID int,Name varchar(500),ManagerID int,EmplyeeNode hierarchyID)
--添加根节点的记录
insert Employeeh values(1,'CEO',null,hierarchyid::GetRoot()) --添加两个平级的子节点
--1.定义父节点
declare @rootmanager hierarchyid
--对变量进行赋值
set @rootmanager=(select EmplyeeNode from Employeeh where EmployeeID=1)
--父节点作为子节点进行插入
insert Employeeh values(2,'Manager1',1,@rootmanager.GetDescendant(null,null)) --插入第二条数据
declare @manager1 hierarchyid
set @manager1=(select EmplyeeNode from Employeeh where EmployeeID=2)
insert Employeeh values(3,'Manager2',1,@rootmanager.GetDescendant(@manager1,null)) --访问表的数据
select EmployeeID,Name,ManagerID,EmplyeeNode.ToString() from Employeeh

结果:

2.添加子节点:父节点GetDescendant()方法

在子节点中在添加子节点:

--在Manager1 中添加子节点
declare @manager1 hierarchyid
set @manager1=(select EmplyeeNode from Employeeh where EmployeeID=3)
insert Employeeh values(4,'SubManager1',2,@manager1.GetDescendant(null,null)) declare @manager2 hierarchyid
set @manager2=(select EmplyeeNode from Employeeh where EmployeeID=3)
insert Employeeh values(5,'SubManager2',3,@manager2.GetDescendant(null,null)) --查询
select EmployeeID,Name,ManagerID,EmplyeeNode.ToString() from Employeeh

--访问节点所在的层次结构
select EmployeeID,Name,ManagerID,EmplyeeNode.ToString(),EmplyeeNode.GetLevel() from Employeeh

3.获取当前级别:当前节点GetLevel()方法

4.获取当前节点下所有子节点,判断条件:where 列名 IsDescendantOf(当前节点)=1 or  0

--查看当前节点下的子节点
--1.申明当前的节点
declare @current hierarchyid
set @current=(select EmplyeeNode from Employeeh where Name='Manager2')
select EmployeeID,Name,ManagerID,EmplyeeNode.ToString(),EmplyeeNode.GetLevel() from Employeeh
--判断当前节点的子节点为真
where EmplyeeNode.IsDescendantOf(@current)=1

5.获取当前节点的父节点:判断条件:where 列名 当前节点 GetAncestor(级别)

   --查看当前节点所在的父节点
declare @current hierarchyid
set @current=(select EmplyeeNode from Employeeh where Name='SubManager2')
select EmployeeID,Name,ManagerID,EmplyeeNode.ToString(),EmplyeeNode.GetLevel() from Employeeh
where EmplyeeNode=@current.GetAncestor(1)

6.移动节点到新的父节点:Set 列名=当前节点   GetReparentedValue(@OldParent,@NewParent) where

7.索引:深度优化(查询所有的后代)、宽度优先(查询直接后代)

将旧表数据导入层次结构数据新表

新建旧表插入数据:

    create table EmployeeOld(employeeid int,managerid int,name varchar(500))
insert EmployeeOld values(1,null,'ceo')
insert EmployeeOld values(2,1,'manager1')
insert EmployeeOld values(3,1,'manager2')
insert EmployeeOld values(4,2,'sub1')
insert EmployeeOld values(5,2,'sub2')
insert EmployeeOld values(6,3,'sub3')
insert EmployeeOld values(7,3,'sub4')

把旧表的数据导入到新表中:

	--创建新表(有层次结构的表)
create table EmployeeNew(employeeid int,managerid int,name varchar(500),node hierarchyid) --查看以前的表结构
select EmployeeID,Name,ManagerID,EmplyeeNode.ToString() from Employeeh --思路:1.获取子节点在父节点下所对应的的行号
--2.将父节点的hierarchyid 给链接到行号的前面 --1.通用表表达式 获取旧表的数据 并且存储在父节点下的行号
--2.第二个通用表达式使用第一个通用表达式的值,同时连接父节点 hierarchyid的值
;with eh(employeeid,managerid,name,position)
as
(
select employeeid,managerid,name,ROW_NUMBER() over(partition by managerid
order by employeeid) from EmployeeOld
),
employeenewtemp(employeeid,managerid,name,node)
as
(
select employeeid,managerid,name,hierarchyid::GetRoot() from eh where managerid is null
union all
select eh.employeeid,eh.managerid,eh.name,
CAST(employeenewtemp.node.ToString()+CAST(eh.position as varchar(500))
+'/' as hierarchyid) from eh inner join employeenewtemp on eh.managerid=employeenewtemp.employeeid
)
--插入到新表中
insert into EmployeeNew select employeeid,managerid,name,node.ToString() from employeenewtemp

查看数据:

	 select * from EmployeeOld
select employeeid,managerid,name,node.ToString() from EmployeeNew

C#中控制台调用。

一:建立连接返回数据

引入这个命名空间

using Microsoft.SqlServer.Types;
public DataTable getdata()
{
SqlConnection conn = new SqlConnection("data source=localhost;initial catalog=HRDB1;user id=sa;password=sunliyuan123456");
//打开连接
conn.Open();
//执行Sql语句
SqlDataAdapter da = new SqlDataAdapter("select * from EmployeeNew", conn);
//实例化DataSet
DataSet ds = new DataSet();
//进行填充
da.Fill(ds, "EmployeeNew");
//释放资源
ds.Dispose();
conn.Close();
//返回第一个表
return ds.Tables[0];
}

二:生成树节点:

 /// <summary>
/// 生成树的节点
/// </summary>
/// <param name="oParent">树节点</param>
/// <param name="oTable">得到的表</param>
private void LoadTreeNode(TreeNode oParent,DataTable oTable)
{
//清空所有的节点
oParent.Nodes.Clear();
//取得父节点的数据 放入DataRow
DataRow oRow=(DataRow)oParent.Tag;
//获取node的值并进行转换
SqlHierarchyId iID =(SqlHierarchyId)oRow["node"];
//的到第一节父节点 出入的值是父节点的id 说明传进来的值就是子节点
var query = from employee in oTable.AsEnumerable()
where employee.Field<SqlHierarchyId>("node").GetAncestor(1)
.Equals(iID)
select employee;
//把数据放入到DataView 中
DataView oDV = query.AsDataView();
foreach(DataRowView oR in oDV)
{
//得到一节子节点
TreeNode oNode = new TreeNode(oR["name"].ToString());
oNode.Tag = oR.Row;
LoadTreeNode(oNode,oTable);
//附加到父节点
oParent.Nodes.Add(oNode);
}
}

三:生成树视图并得到根节点

        /// <summary>
/// 生成树视图并得到根节点
/// </summary>
/// <param name="oTV"></param>
/// <param name="oTable"></param>
/// <param name="key"></param>
/// <param name="text"></param>
public void LoadTreeView(TreeView oTV,DataTable oTable,string key,string text)
{
oTV.Nodes.Clear();
SqlHierarchyId iID = new SqlHierarchyId();
TreeNode roonode;
//查询根节点
var query = from employee in oTable.AsEnumerable()
where employee.Field<SqlHierarchyId>(key).GetAncestor(1)
.Equals(iID)
select employee;
DataView oDV = query.AsDataView();
//找到根节点
if(oDV.Count ==1)
{
roonode = new TreeNode(oDV[0][text].ToString());
roonode.Tag = oDV[0].Row;
LoadTreeNode(roonode, oTable);
oTV.Nodes.Add(roonode);
}
}

对数据进行绑定:

	private clsData oData = new clsData();
private DataTable dtData; private void btnGetData_Click(object sender, EventArgs e)
{
dtData = oData.getdata();
dgData.DataSource = dtData; } private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
} private void doTV_Click(object sender, EventArgs e)
{ oData.LoadTreeView(tvData, dtData, "node", "name");
}

效果:

SqlServr性能优化性能之层次结构(十五)的更多相关文章

  1. Android性能优化——性能优化的难题总结

    前言 现在都在谈性能优化或者在面试的时候被问到性能优化相关问题,那么我们为什么要做性能优化呢?以及性能优化的难点是什么?在整个项目周期中不同的阶段该做什么?优化效果如何长期保持?作为一名Android ...

  2. Linux性能优化实战内存篇(五)

    一.Linux内存工作原理 1,内存映射 Linux内核给每个进程都提供了一个独立的虚拟空间,并且这个地址空间是连续的.这样,进程就可以很方便地访问内存,更确切地说是访问虚拟内存. 虚拟地址空间的内部 ...

  3. SqlServer性能优化 性能调控(十)

    如何做资源的调控: 1.建立资源池. 2.创建工作负荷组 create resource pool ImporPool with ( min_cpu_percent=30,max_cpu_percen ...

  4. 鲲鹏性能优化十板斧之前言 | 鲲鹏处理器NUMA简介与性能调优五步法

    鲲鹏处理器NUMA简介 随着现代社会信息化.智能化的飞速发展,越来越多的设备接入互联网.物联网.车联网,从而催生了庞大的计算需求.但是功耗墙问题以功耗和冷却两大限制极大的影响了单核算力的发展.为了满足 ...

  5. 性能优化之Java(Android)代码优化

    最新最准确内容建议直接访问原文:性能优化之Java(Android)代码优化 本文为Android性能优化的第三篇——Java(Android)代码优化.主要介绍Java代码中性能优化方式及网络优化, ...

  6. Android性能优化之布局优化

    最新最准确内容建议直接访问原文:Android性能优化之布局优化 本文为Android性能优化的第二篇——布局优化,主要介绍使用抽象布局标签(include, viewstub, merge).去除不 ...

  7. for循环实战性能优化之使用Map集合优化

           笔者在<for循环实战性能优化>中提出了五种提升for循环性能的优化策略,这次我们在其中嵌套循环优化小循环驱动大循环的基础上,借助Map集合高效的查询性能来优化嵌套for循环 ...

  8. 【MongoDB】MongoDB 性能优化 - BI查询聚合

    在BI服务中通过查询聚合语句分析定位慢查询/聚合分析,小结如下: 慢查询定位: 通过Profile分析慢查询 对于查询优化: 通过添加相应索引提升查询速度: 对于聚合大数据方案: 首先要说明的一个问题 ...

  9. Android性能优化之数据库优化

    本文为性能优化的第一篇——数据库性能优化,原理适用于大部分数据库包括Sqlite.Mysql.Oracle.Sql server,详细介绍了索引(优缺点.分类.场景.规则)和事务,最后介绍了部分单独针 ...

随机推荐

  1. hdu 6311 欧拉回路

    题意:求一个图(不一定联通)最小额外连接几条边,使得可以一笔画出来 大致做法 1.找出联通块 2.统计每一个连通块里面度数为奇数的点的个数, 有一个性质 一个图能够用一笔画出来,奇数点的个数不超过2个 ...

  2. set.seed(7)什么意思

    以前虽然在每个程序都看见过,但是没注意过这个问题,也不理解是什么意思,去搜了一些帖子才明白. 其实,很好理解,就是如果你不加set.seed(7),当然代码也可以执行这个命令,但是每次执行的结果都会不 ...

  3. (二)C语言文本流和二进制流的区别

    转至:http://www.cnblogs.com/xiangzi888/archive/2011/11/10/2244336.html 一.首先回答,什么是文件,流 一个文件通常就是磁盘上的一段命名 ...

  4. QCon技术干货:个推基于Docker和Kubernetes的微服务实践

    2016年伊始,Docker无比兴盛,如今Kubernetes万人瞩目.在这个无比需要创新与速度的时代,由容器.微服务.DevOps构成的云原生席卷整个IT界.在近期举办的QCon全球软件开发大会上, ...

  5. Java入门:创建多个对象

    当使用一个类实例化多个对象时,多个对象之间是什么关系?他们各自的数据会不会发生混淆?这次课跟大家讲解一下这个问题.学完本次课,大家应该对对象在内存中的表示方式有一个初步的了解,为理解更深入的面向对象概 ...

  6. linux(ubuntu) mysql安装使用

    简单的安装一下: sudo apt-get install mysql-server apt-get isntall mysql-client sudo apt-get install libmysq ...

  7. Spring Cloud微服务实战阅读笔记(一) 基础知识

    本文系<Spring Cloud微服务实战>作者:翟永超,一书的阅读笔记. 一:基础知识   1:什么是微服务架构     是一种架构设计风格,主旨是将一个原本独立的系统拆分成多个小型服务 ...

  8. vue 倒计时返回首页

    1. vue页面15分钟无操作时返回首页 2. 基于vue的倒计时demo 3. 在vue2.0项目中一个简单的倒计时功能 4. vue重新发送验证码 5. 表格<td>里面文字垂直显示

  9. Dialog插件artDialog

    经本人测试,发现没有layer好用,因为artDialog不能拖拽.不过除了拖拽,其他还蛮简洁的,在自定义上的灵活性也还可以.下面是我自己写的测试demo. <!DOCTYPE html> ...

  10. TPL概要

    ReaderWriterLockSlim.读写锁,允许多个线程同时获取读锁,但同一时间只允许一个线程获得写锁,因此也称作共享-独占锁.只有等到对象被写入锁占用的时候,才会阻塞 Barrier .它允许 ...