我正在尝试列出虚拟目录中的所有文件及其子目录。这可能是下属公司的员工,这不是文件系统。也许递归存储过程可能不是答案。
情景:
DirId, ParentId
FileId, DirId
ParentId
是父目录,根目录有parentId = NULL
...认为它是自我解释的。
现在问题......我想要一个目录及其子目录中存在的列表文件。
对于一个目录,我将创建一个存储过程:
SELECT * FROM Files Where DirId = ????
那么我如何创建一个包含子目录的存储过程呢?目前我正在使用C#代码并循环遍历每个目录。我更喜欢使用存储过程...除非你证明我错了。
答案 0 :(得分:4)
请查看使用CTE。
像
这样的东西DECLARE @Directory Table(
DirId INT,
ParentId INT
)
DECLARE @Files Table(
FileId INT,
DirId INT
)
INSERT INTO @Directory SELECT 1, NULL
INSERT INTO @Directory SELECT 2, 1
INSERT INTO @Directory SELECT 3, 1
INSERT INTO @Directory SELECT 4, 2
INSERT INTO @Files SELECT 1, 1
INSERT INTO @Files SELECT 2, 1
INSERT INTO @Files SELECT 3, 2
INSERT INTO @Files SELECT 4, 2
INSERT INTO @Files SELECT 5, 3
INSERT INTO @Files SELECT 6, 3
INSERT INTO @Files SELECT 7, 4
INSERT INTO @Files SELECT 8, 4
;WITH Directories AS (
SELECT DirId,
ParentID
FROM @Directory
WHERE DirId = 2
UNION ALL
SELECT d.DirId,
d.ParentID
FROM @Directory d INNER JOIN
Directories p ON d.ParentId = p.DirId
)
SELECT *
FROM Directories d INNER JOIN
@Files f ON d.DirId = f.DirId
答案 1 :(得分:1)
我认为你所要求的不是实际访问文件系统,而是你的数据库中的表中有一个目录结构,在这种情况下你可以使用这样的递归CTE:
DECLARE @DirId INTEGER
SET @DirId = 1
;WITH CTEFolders AS
(
SELECT FileId, DirId FROM Files WHERE DirId = @DirId
UNION ALL
SELECT fi.FileId, fi.DirId
FROM CTEFolders c
JOIN Folders fo ON c.DirId = fo.ParentId = c.DirId
JOIN Files fi ON fo.DirId = fi.DirId
)
SELECT * FROM CTEFolders
答案 2 :(得分:-1)
实际上递归并不是一个好的解决方案。 Dba不希望我们使用递归,
您可以使用此脚本获取目录和子目录
Select d.FileName, f.* from Files f
left Join Files fsub on fsub.DirId = f.DirId
inner Join Directory d on d.DirId = f.DirId
子目录和目录将使用此脚本列出