从SQL表中读取文件夹路径,并为缺少的父文件夹创建记录

时间:2015-10-14 23:12:49

标签: sql sql-server sql-server-2012 directory

我有一个像这样的文件夹路径示例表:

Level   Folder
0       C:
1       C:\David
3       C:\David\Documents\Pictures
1       C:\John
2       C:\John\Documents
3       C:\John\Documents\Videos
4       C:\Susan\Documents\Pictures\Photos

“level”表示文件夹深度,其中0 = root等

我想为缺少的每个父文件夹创建一条记录。在这种情况下:

2       C:\David\Documents
1       C:\Susan
2       C:\Susan\Documents
3       C:\Susan\Documents\Pictures

我并不担心计算Level列,但我已将其包含在内,以防它变得更容易。我用它来创建我的样本数据:

CREATE TABLE #Folders (
    [Level]     int,
    [Folder]    nvarchar(255)
)

INSERT INTO #Folders
Select 0, 'C:'
UNION
Select 1, 'C:\David'
UNION
SELECT 3,  'C:\David\Documents\Pictures'
UNION
SELECT 1, 'C:\John'
UNION
SELECT 2, 'C:\John\Documents'
UNION
SELECT 3, 'C:\John\Documents\Videos'
UNION
SELECT 4, 'C:\Susan\Documents\Pictures\Photos'

SELECT * FROM #Folders
ORDER BY Folder
DROP TABLE #Folders

2 个答案:

答案 0 :(得分:1)

从我希望T-SQL拥有的用户定义函数开始:

;WITH c ( level, path )
     AS (SELECT o.level,
                o.folder
           FROM [table] o
          WHERE NOT EXISTS (SELECT 'f'
                              FROM [table] e
                             WHERE e.folder LIKE o.folder + '\%')
         UNION ALL
         SELECT c.level - 1,
                SUBSTRING(c.path, 1, dbo.LastCharIndex('\', c.path) - 1)
           FROM c
          WHERE dbo.lastcharindex('\', c.path) > 0)
INSERT INTO [table]
SELECT level,
       path
  FROM c
 WHERE NOT EXISTS(SELECT 'f'
                    FROM [table]
                   WHERE folder = c.path) 

使用递归CTE(用表名替换[table])来跟进:

for(var i=0; i<== tags.length;i++){
  //Code that creates a label or whatever with the tag
}

这应该将所有丢失的文件夹及其各自的级别插入到您的表中。

答案 1 :(得分:0)

我想我找到了一个解决方案(注意到@ Forty3,你刚刚发布了一个)。我会检查你的。这是我试过的:

;WITH CTE ([level], folder, parentfolder) AS (
    -- anchor
    SELECT
        [Level],
        folder,
        LEFT(folder, LEN(folder)-CHARINDEX('\', REVERSE(folder)))
    FROM #Folders
    WHERE [Level] > 1
UNION ALL
    SELECT
        [Level]-1,
        parentfolder,
        LEFT(parentfolder, LEN(parentfolder)-CHARINDEX('\', REVERSE(parentfolder)))
    FROM CTE
    WHERE [level] > 0
)
INSERT INTO #Folders
SELECT DISTINCT
    [level],
    folder
FROM CTE
WHERE folder NOT IN (SELECT folder from #Folders)
ORDER BY cte.Folder

SELECT * FROM #Folders

创建所需的输出:

level   folder
0       S:
1       S:\David
2       S:\David\Documents
3       S:\David\Documents\Pictures
1       S:\John
2       S:\John\Documents
3       S:\John\Documents\Videos
1       S:\Susan
2       S:\Susan\Documents
3       S:\Susan\Documents\Pictures
4       S:\Susan\Documents\Pictures\Photos