DECLARE @CategoryNO int, @Level int
SET @Level = 0
然后要建立两张临时表,第一张表用来存储待处理记录,第二张表存储最终的结果。关于它们是如何使用的请继续往下看。
CREATE TABLE #TreeViewTemp
(
CategoryNO int NOT NULL,
CategoryName nvarchar(30) NOT NULL,
Parent int NULL,
[Level] int NOT NULL
)
CREATE TABLE #TreeViewResult
(
CategoryNO int NOT NULL,
CategoryName nvarchar(30) NOT NULL
)
接下来向#TreeViewTemp表中插入第一级别的记录。在这里,ROOT记录表示的是根级别,是所有第一级别的父级,最终结果将不包含该记录。注意#TreeViewTemp表中记录了这些记录的级别。
INSERT #TreeViewTemp
SELECT CategoryNO, CategoryName, Parent, @Level
FROM Category
WHERE Parent = 0
再下来,进入一个循环结构。循环结束的条件是#TreeViewTemp表中不再有记录。接下来的内容都是在循环结构中的,BEGIN和END关键字就不写出来了。
WHILE EXISTS (SELECT CategoryNO FROM #TreeViewTemp)
循环的第一条语句,取出#TreeViewTemp中当前级别的第一条记录,并记录下它的CategoryNO(还记得一开始的@CategoryNO和@Level变量吗?)
SELECT TOP(1) @CategoryNO = CategoryNO
FROM #TreeViewTemp
WHERE [Level] = @Level
ORDER BY CategoryNO
如果取不到记录,也就是说临时表中当前级别的记录不存在,那么令@Level变量的值减一,也就是退回上一级别,并继续下一个循环。
IF @@ROWCOUNT = 0
BEGIN
SET @Level = @Level - 1
CONTINUE
END
如果当前级别还有记录,就把这条记录插入到最终结果的表中。插入的时候根据当前级别在名称前面加上空格。
INSERT #TreeViewResult
SELECT CategoryNO, SPACE(4 * @Level) + CategoryName
FROM #TreeViewTemp
WHERE CategoryNO = @CategoryNO
接着找出刚刚那条记录的所有子类别,插入到#TreeViewTemp表中。这里把@Level的值加1再插入到表中,表明这些记录是下一级别的。
INSERT #TreeViewTemp
SELECT CategoryNO, CategoryName, Parent, @Level + 1
FROM Category
WHERE Parent = @CategoryNO
如果这条记录有子类别,那么就使@Level的值加1,进入下一级别。
IF @@ROWCOUNT 0
SET @Level = @Level + 1
循环结构中最后一条语句,把#TreeViewTemp中刚刚处理的那条记录删除。
DELETE #TreeViewTemp
WHERE CategoryNO = @CategoryNO
最后一件事,当然是把最终的结果显示出来了。
SELECT CategoryNO, CategoryName FROM #TreeViewResult
最最后的,把临时表删除。
DROP TABLE #TreeViewTemp
DROP TABLE #TreeViewResult
好了,构建树形结构的基本框架就是这样,可以在这个基础上作些修改以适应不同的需求。
我不知道以上说明是否能让大家明白这个逻辑,甚至我自己也说不清楚,它实在是比较复杂……
这个方法有一个缺点,就是使用了临时表。由于临时表的数据是存储在硬盘中的,所以整个过程的速度会有影响。
在最后把整个过程的代码整合在一起:
Code
DECLARE @CategoryNO int, @Level int
SET @Level = 0
CREATE TABLE #TreeViewTemp
(
CategoryNO int NOT NULL,
CategoryName nvarchar(30) NOT NULL,
Parent int NULL,
[Level] int NOT NULL
)
CREATE TABLE #TreeViewResult
(
CategoryNO int NOT NULL,
CategoryName nvarchar(30) NOT NULL
)
INSERT #TreeViewTemp
SELECT CategoryNO, CategoryName, Parent, @Level
FROM Category
WHERE Parent = 0
WHILE EXISTS (SELECT CategoryNO FROM #TreeViewTemp)
BEGIN
SELECT TOP(1) @CategoryNO = CategoryNO
FROM #TreeViewTemp
WHERE [Level] = @Level
ORDER BY CategoryNO
IF @@ROWCOUNT = 0
BEGIN
SET @Level = @Level - 1
CONTINUE
END
INSERT #TreeViewResult
SELECT CategoryNO, SPACE(4 * @Level) + CategoryName
FROM #TreeViewTemp
WHERE CategoryNO = @CategoryNO
INSERT #TreeViewTemp
SELECT CategoryNO, CategoryName, Parent, @Level + 1
FROM Category
WHERE Parent = @CategoryNO
IF @@ROWCOUNT 0
SET @Level = @Level + 1
DELETE #TreeViewTemp
WHERE CategoryNO = @CategoryNO
END
SELECT CategoryNO, CategoryName FROM #TreeViewResult
DROP TABLE #TreeViewTemp
DROP TABLE #TreeViewResult