我有一个表,用于存储文件共享程序的文件。表“ FileSystem”存储文件和文件夹结构。 FileSystem表具有一个“ IsFolder”字段,用于指示这是文件还是文件夹。 “ ParentId”代表文件或文件夹的父文件夹。例如:
Id ParentId Name RelativePath IsFolder
----------------------------------------------------
1 NULL \ \ 1
2 1 Test \Test 1
3 2 Folder1 \Test\Folder1 1
4 2 myFile.txt \Test\Folder1 0
如果将“ Test”文件夹的名称更新为“ Test2”,我想更新所有适用文件夹的RelativePath文本。
Id ParentId Name RelativePath IsFolder
----------------------------------------------------
1 NULL \ \ 1
2 1 Test2 \Test2 1
3 2 Folder1 \Test2\Folder1 1
4 2 myFile.txt \Test2\Folder1 0
我已经尝试过使用CTE,但性能确实很慢。我完全有可能使用错误的TSQL!
CREATE TABLE [dbo].[FileSystem]
(
[FileSystemId] [INT] IDENTITY(1,1) NOT NULL,
[Name] [VARCHAR](500) NULL,
[RelativePath] [VARCHAR](1000) NULL,
[IsFolder] [BIT] NOT NULL,
[ParentId] [INT] NULL,
[LastWriteTime] [DATETIME] NULL,
[FileData] [VARBINARY](MAX) NULL,
[UploadedBy] [VARCHAR](50) NULL,
[IsDeleted] [BIT] NOT NULL,
[DeletedTime] [DATETIME] NULL,
[DeletedBy] [VARCHAR](50) NULL,
[DocumentType] [VARCHAR](10) NULL,
CONSTRAINT [PK_FileSystem]
PRIMARY KEY CLUSTERED ([FileSystemId] ASC)
WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[FileSystem]
ADD CONSTRAINT [DF_FileSystem_IsDeleted] DEFAULT ((0)) FOR [IsDeleted]
GO
ALTER TABLE [dbo].[FileSystem] WITH CHECK
ADD CONSTRAINT [FK_FileSystem_FileSystem]
FOREIGN KEY([ParentId]) REFERENCES [dbo].[FileSystem] ([FileSystemId])
GO
ALTER TABLE [dbo].[FileSystem] CHECK CONSTRAINT [FK_FileSystem_FileSystem]
这是我尝试过的CTE,但需要20秒才能运行。
WITH CTE AS
(
SELECT
t.FileSystemId,
t.ParentId,
t.Name as RootPath,
t.RelativePath,
t.IsFolder
FROM
FileSystem AS t
WHERE ParentId is null
UNION ALL
SELECT
t.FileSystemId,
t.ParentId,
CAST(REPLACE(CTE.RootPath+'\'+t.Name,'\\','\')AS VARCHAR(500)) AS RootPath,
t.RelativePath,
t.IsFolder
FROM
FileSystem AS t
JOIN CTE
ON CTE.FileSystemId=t.parentId
WHERE
t.IsFolder=1 AND t.FileSystemId IS NOT NULL
)
SELECT
CTE.RootPath, CTE.RelativePath, CTE.FileSystemId
FROM
CTE
WHERE
CTE.ParentId IS NOT NULL
如果不重复层次结构中的路径,则不需要递归查询,因为relativepath
具有所需的信息:
update filesystem
set relativepath = (case when relativepath like '%\Test\%'
then replace(relativepath, '\Test\', '\Test2\'
else concat(left(relativepath, len(relativepath) - len('Test')),
'Test2'
)
end)
where concat('%\', relativepath, '\%') like '%\Test\%';
超级菜鸟错误,但我没有意识到我的ParentId上没有索引。如果CTE对任何人都有帮助,我将保留问题。