使用SQL Server将文件夹名称添加到filename

时间:2016-02-11 15:54:30

标签: sql sql-server-2012 file-rename

我目前正在使用它来获取目录/文件名,但需要能够将整个文件夹名称添加到文件名中。

$jObj = json_decode($json);

$new = new stdClass();  // create a new object

foreach( $jObj->entry as $entry ) {
    $t = new stdClass();

    $t->id      = $entry->id;
    $t->title   = $entry->title;
    $t->updated = $entry->updated;

    $new->entries[] = $t;   // create an array of objects
}


$newJsonString = json_encode($new);

运行:

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

2 个答案:

答案 0 :(得分: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  |
+------------------------------+

答案 1 :(得分: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的工作方式是确保我们只在文件中提升一级时才更改它(因此new_filenamefull_path仍然相等那一点。)

我还包含full_path,因为它可能在重命名操作中很有用。

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

  1. xp_dirtree既未记录也未受支持,因此在生产代码中使用它并不是一个好主意。

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