<script type="text/javascript">
</script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
SELECT*FROMufn_GetSubtree(2)ASS
WHERENOTEXISTS(SELECT*FROMEmployeesASE
WHEREE.mgrid=S.empid)
最后一个任务是利用Listing7显示的ufn_GetMgmtChain函数,报告通向特定雇员的管理链。
LISTING7:获取通向特定雇员的管理链
CREATEFUNCTIONufn_GetMgmtChain
(
@empidASint
)
RETURNS@treetable
(
empidintNOTNULL,
mgridintNULL,
empnamevarchar(25)NOTNULL,
salarymoneyNOTNULL,
lvlintNOTNULL
)
AS
BEGIN
DECLARE@lvlASint
SET@lvl=0
INSERTINTO@tree
SELECTempid,mgrid,empname,salary,@lvl
FROMEmployees
WHEREempid=@empid
WHILE@@ROWCOUNT>0
BEGIN
SET@lvl=@lvl+1
INSERTINTO@tree
SELECTE.empid,E.mgrid,E.empname,E.salary,@lvl
FROMEmployeesASEJOIN@treeAST
ONE.empid=T.mgridANDT.lvl=@lvl-1
END
RETURN
END
注意ufn_GetMgmtChain函数的实现与ufn_GetSubtree函数的实现相似,区别在于现在我们顺着管理链而上,直至到达顶端。要得到通向James(empid是14)的管理链,可以执行如下查询:
SELECT*FROMufn_GetMgmtChain(14)
ORDERBYlvlDESC
从SELECT查询的性能考虑,我们可以把lvl和path列的值直接加入到Employees表,然后通过触发器更新这两个列的值。采用这种方法要比在 UDF中计算lvl和path值更有利于提高查询的性能。如果要使用一个用到了lvl列和path列的过滤器,ufn_GetSubtree必须先扫描整个表,计算这两个列的值。如果让lvl和path作为Employees表的列,我们可以在path列上建立一个索引,从而避免对整个表的扫描操作。然而,使用ufn_GetSubtree函数时,我们无需对Employees的结构做任何修改,而且和使用触发器时不同,我们不会增加任何维护lvl和path列的负担。 UDF的出现拓展了无限的空间。在这里, UDF是不要求对表的结构做任何修改的强大层次型数据处理工具。 <script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript">
</script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
要得到Andrew子树中的叶节点(不是管理员的雇员),查询命令如下:
SELECT*FROMufn_GetSubtree(2)ASS
WHERENOTEXISTS(SELECT*FROMEmployeesASE
WHEREE.mgrid=S.empid)
最后一个任务是利用Listing7显示的ufn_GetMgmtChain函数,报告通向特定雇员的管理链。
LISTING7:获取通向特定雇员的管理链
CREATEFUNCTIONufn_GetMgmtChain
(
@empidASint
)
RETURNS@treetable
(
empidintNOTNULL,
mgridintNULL,
empnamevarchar(25)NOTNULL,
salarymoneyNOTNULL,
lvlintNOTNULL
)
AS
BEGIN
DECLARE@lvlASint
SET@lvl=0
INSERTINTO@tree
SELECTempid,mgrid,empname,salary,@lvl
FROMEmployees
WHEREempid=@empid
WHILE@@ROWCOUNT>0
BEGIN
SET@lvl=@lvl+1
INSERTINTO@tree
SELECTE.empid,E.mgrid,E.empname,E.salary,@lvl
FROMEmployeesASEJOIN@treeAST
ONE.empid=T.mgridANDT.lvl=@lvl-1
END
RETURN
END
注意ufn_GetMgmtChain函数的实现与ufn_GetSubtree函数的实现相似,区别在于现在我们顺着管理链而上,直至到达顶端。要得到通向James(empid是14)的管理链,可以执行如下查询:
SELECT*FROMufn_GetMgmtChain(14)
ORDERBYlvlDESC
从SELECT查询的性能考虑,我们可以把lvl和path列的值直接加入到Employees表,然后通过触发器更新这两个列的值。采用这种方法要比在 UDF中计算lvl和path值更有利于提高查询的性能。如果要使用一个用到了lvl列和path列的过滤器,ufn_GetSubtree必须先扫描整个表,计算这两个列的值。如果让lvl和path作为Employees表的列,我们可以在path列上建立一个索引,从而避免对整个表的扫描操作。然而,使用ufn_GetSubtree函数时,我们无需对Employees的结构做任何修改,而且和使用触发器时不同,我们不会增加任何维护lvl和path列的负担。 UDF的出现拓展了无限的空间。在这里, UDF是不要求对表的结构做任何修改的强大层次型数据处理工具。 <script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript">
</script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>