【发布时间】:2011-01-12 23:57:31
【问题描述】:
我正在使用拆分功能(在 social.msdn.com 上找到)并且在查询窗口中手动执行时
SELECT * FROM dbo.Split('/ABC/DEF/GHI/JKL', '/')
我得到以下信息
Id Name
-- ----
1
2 ABC
3 DEF
4 GHI
5 JKL
Id 只是一个序号,表示在原始字符串中的位置,Name 是该节点的名称。尚无分层信息。
现在,下一步是将其放入数据库中的分层数据结构中。我正在尝试在存储过程中执行此操作,并且我的 SQL 技能就是这样,我碰壁了。以下是我希望拥有的内容:(请注意,上面的 Id 列与此处的 Id 或 ParentId 列无关。)
Id ParentId Name FullName
-- -------- ---- --------
1 NULL ABC /ABC
2 1 DEF /ABC/DEF
3 2 GHI /ABC/DEF/GHI
4 3 JKL /ABC/DEF/GHI/JKL
我的 SP(使用参数 @FullName 称为 GetId)已经到此为止了 - GetId 应该返回与此节点关联的 Id。如果节点不存在,则应创建该节点并返回该新行的 Id - 换句话说,此 SP 的使用者不应该关心或知道节点在调用它之前是否存在:
DECLARE @count int
-- // is there already a row for this node?
SELECT @count = COUNT(CatId)
FROM Category
WHERE FullName = @FullName
-- // if no row for this node, create the row
-- // and perhaps create multiple rows in hierarchy up to root
IF (@count = 0)
BEGIN
SELECT * FROM Split(@FullName, '/')
-- // NOW WHAT ???
-- // need to insert row (and perhaps parents up to root)
END
-- // at this point, there should be a row for this node
-- // return the Id associated with this node
SELECT Id
FROM Category
WHERE FullName = @FullName
通过一系列插入,这些项目最终将结束的类别表(邻接表)具有以下结构。
CREATE TABLE Category (
Id int IDENTITY(1,1) NOT NULL PRIMARY KEY,
ParentId int NULL,
Name nvarchar(255) NOT NULL,
FullName nvarchar(255) NOT NULL)
因此,我不想为 Category 表中的 Id 列生成值,并且需要为每个节点获取适当的 ParentId。
在处理路径“/ABC/DEF/GHI/JKL”和“/ABC/DEF/XYZ/LMN/OPQ”并执行 SELECT * FROM Category 之后,我希望看到以下内容:
Id ParentId Name FullName
-- -------- ---- --------
1 NULL ABC /ABC
2 1 DEF /ABC/DEF
3 2 GHI /ABC/DEF/GHI
4 3 JKL /ABC/DEF/GHI
5 2 XYZ /ABC/DEF/XYZ
6 5 LMN /ABC/DEF/XYZ/LMN
7 6 OPQ /ABC/DEF/XYZ/LMN/OPQ
问:是否可以从最外层节点开始递归回调 SP,直到该节点存在或我们位于最终父节点?大意是:
GetId(@FullName)
{
If Category exists with @FullName
return CatId
Else // row doesn't exist for this node
Split @FullName, order by Id DESC so we get the leaf node first
Create Category row
@FullName,
@Name,
@ParentId = Id of next FullName (call GetId with FullName of next row from Split)
}
【问题讨论】:
-
您使用的是哪个版本的 SQL Server?如果2008年你考虑过hierarchyid吗?
-
你表示路径的方式让我想起了很多
hierarchyid格式。我自己并没有真正使用过它,所以不知道它是否比邻接列表模型更适合您的目的...... -
@Martin 我快速浏览了 HierarchyId,它看起来很有趣,但我认为它对我不起作用,因为层次结构信息(路径)具有数字节点,而不是字符串节点。 bit.ly/iek63I
标签: sql sql-server tsql stored-procedures string