У меня есть таблица, в которой хранятся файлы для общей файловой программы. В таблице «Файловая система» хранятся файлы и структура папок. Таблица 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
I 'Я пытался использовать 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