2016-02-11 76 views
1

我目前使用它来获取目录/文件名,但需要能够将整体文件夹名称添加到文件名。将文件夹名称添加到文件名与SQL Server

IF OBJECT_ID('tempdb..#DirectoryTree') IS NOT NULL 
    DROP TABLE #DirectoryTree; 

CREATE TABLE #DirectoryTree 
(
    id INT IDENTITY(1 ,1) 
    ,subdirectory NVARCHAR(512) 
    ,depth INT 
    ,isfile BIT 
); 

INSERT #DirectoryTree (subdirectory, depth, isfile) 
    EXEC master.sys.xp_dirtree 'X:\KO Contracts\Contracts', 3, 1; 

运行:

SELECT * 
FROM #DirectoryTree AS dt 

返回:

id subdirectory   depth isfile 
1 7761601     1  0 
2 Documents    2  0 
3 12 Month Program.pdf  3  1 
4 7764478     1  0 
5 Documents    2  0 
6 12 Month Program.pdf  3  1 
7 7773224     1  0 
8 Documents    2  0 
9 12 Month Program.pdf  3  1 
10 12Month PT.pdf   3  1 
11 6 Month Program.pdf  3  1 

我需要的是重命名的文件(isfile = 1)它是(depth = 1)的目录。

例子:

7761601_12 Month Program.pdf 
7764478_12 Month Program.pdf 
7773224_12 Month Program.pdf 
7773224_12Month PT.pdf 
7773224_6 Month Program.pdf 

回答

1
;WITH v AS (
    SELECT 
     * 
    FROM 
     (VALUES 
     (1,'7761601',1,0), 
     (2,'Documents',2,0), 
     (3,'12 Month Program.pdf',3,1), 
     (4,'7764478',1,0), 
     (5,'Documents',2,0), 
     (6,'12 Month Program.pdf',3,1), 
     (7,'7773224',1,0), 
     (8,'Documents',2,0), 
     (9,'12 Month Program.pdf',3,1), 
     (10,'12Month PT.pdf',3,1), 
     (11,'6 Month Program.pdf',3,1)) AS i(id,subdirectory,depth,isfile) 
), 
folder_root AS (
    SELECT 
     o.id, 
     folder_root_id=MAX(i.id) 
    FROM 
     v AS o 
     INNER JOIN v AS i ON 
      i.isfile=0 AND 
      i.depth=1 AND 
      i.id<o.id 
    WHERE 
     o.isfile=1 
    GROUP BY 
     o.id 
) 
SELECT 
    file_name=folder_name.subdirectory+'_'+v.subdirectory 
FROM 
    v 
    INNER JOIN folder_root AS fr ON 
     fr.id=v.id 
    INNER JOIN v AS folder_name ON 
     folder_name.id=fr.folder_root_id; 

结果:

+------------------------------+ 
|   file_name   | 
+------------------------------+ 
| 7761601_12 Month Program.pdf | 
| 7764478_12 Month Program.pdf | 
| 7773224_12 Month Program.pdf | 
| 7773224_12Month PT.pdf  | 
| 7773224_6 Month Program.pdf | 
+------------------------------+ 
+0

这完美的作品!欣赏它! – Doolius

0

为此,您可以使用递归CTE,像这样:

;WITH CTE_Rollup AS 
(
    SELECT 
     id, 
     id AS base_file_id, 
     CAST(subdirectory AS NVARCHAR(MAX)) AS full_path, 
     subdirectory AS new_filename, 
     depth 
    FROM 
     #DirectoryTree 
    WHERE 
     isfile = 1 
    UNION ALL 
    SELECT 
     DT.id, 
     R.base_file_id, 
     CAST(DT.subdirectory + '\' + R.full_path AS NVARCHAR(MAX)), 
     CAST(CASE WHEN R.full_path = R.new_filename THEN DT.subdirectory + '_' + R.new_filename ELSE R.new_filename END AS NVARCHAR(512)) AS new_filename, 
     DT.depth 
    FROM 
     CTE_Rollup R 
    INNER JOIN #DirectoryTree DT ON DT.id = R.id - 1 AND DT.depth = R.depth - 1 
) 
SELECT 
    base_file_id, 
    full_path, 
    new_filename 
FROM CTE_Rollup R 
WHERE 
    R.depth = 1 

new_filename作品通过确保我们只是讨论GE,如果我们只有一个了从文件级别(等等new_filenamefull_path仍然在这一点上相等)。

我还包含了full_path因为这可能是一个重命名操作非常有用。

两个非常重要的事情要考虑,但...

  1. xp_dirtree既不记录也不支持,所以它不是在生产代码使用它是一个好主意。

  2. 这似乎是一种更适合于前端进程而非数据库内的操作。

+0

经过几次更新后,这适用于只有1个文件的文件夹。但是,具有3个文件的文件夹不起作用,因为上面的RowId不是深度2.(我的更新是:我必须删除'depth = 2',重命名'depth = 3'到'深度= 2',然后添加一个'ROW_NUMBER'列,以'Id'为依据,所以它们是按顺序的) – Doolius

+0

啊,是的,考虑到你的数据,我没有考虑同一个目录中的多个文件。谢谢 –

相关问题