2010-12-09 63 views
2

我想列出虚拟目录中的所有文件,它是子目录。这可能是下属公司的员工,这不是文件系统。也许递归存储过程可能不是答案。SQL Server递归存储过程

场景:

  • 目录表:DirId, ParentId
  • 文件表:FileId, DirId

ParentId是父目录的根目录具有parentId = NULL ...认为这是自我解释。

现在的问题......我想要一个目录及其子目录中存在的列表文件。

只是一个目录我将创建一个存储过程:

SELECT * FROM Files Where DirId = ???? 

那么我将如何创建一个存储过程,包括子目录?目前我正在使用C#代码并遍历每个目录。我更喜欢使用存储过程,除非你证明我错了。

+2

考虑使用[递归CTE查询](http://msdn.microsoft.com/en-us/library/ms186243.aspx),也许。 – 2010-12-09 08:38:14

+1

你想通过SQL Server访问文件系统?这通过应用程序代码更容易,更容易完成。你能解释在SQL中如何解决这个问题吗? – Oded 2010-12-09 08:39:08

+0

为什么你要使用存储过程来完成一项明显更适合在C#等代码中执行的任务? – 2010-12-09 08:39:13

回答

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

实际上,递归不是一个好的解决方案。 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 

子目录和目录将与此脚本列出

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 

这里有一个很好的MSDN reference on recursive CTEs