今天我设法在纯 T-SQL 中做到了这一点,没有递归。您只需要一个源路径和一个目标路径。路径应采用FileTableRootPath() + file_stream.GetFileNamespacePath()
.
该查询应该像 IO.Directory.Move 命令一样工作,即
- 如果dest文件夹不存在,将src重命名为dest路径的最后一位,并移动到dest路径的父文件夹中
- 如果 dest 文件夹确实存在,则将 src 文件夹移动到 dest 文件夹中
- 如果 dest 的父级 = src 的父级,那么它只是文件夹的重命名。
也许这对某人有帮助。我还没有做密集测试。您可能希望在事务中执行此操作并在发生异常时回滚。需要删除前四行并将@src 和@dest 作为查询参数传递。
如果您做了一些愚蠢的事情(例如,在移动时射击超过 16 的最大级别或如果 @src 不存在),则不会出现优雅的失败。如果@src 不存在,则查询不会做任何事情。如果您违反了 FileTables 的文件夹深度限制,我猜您会在更新期间收到错误消息。
DECLARE @dest varchar(max)
DECLARE @src varchar(max)
SET @src = '\\MachineName\InstanceName\DBName\FileTableName\path\to\src'
SET @dest = '\\MachineName\InstanceName\DBName\FileTableName\path\to\dest'
DECLARE @srcID hierarchyid;
SELECT @srcId = GETPATHLOCATOR(@src)
DECLARE @srcParentId hierarchyid
SELECT @srcParentId = ISNULL(parent_path_locator, 0x) FROM FileTableName WHERE path_locator = @srcId
DECLARE @newName varchar(max);
DECLARE @destParentId hierarchyid;
SET @destParentId = GetPathLocator(@dest);
SET @newName = NULL
IF @destParentId IS NULL
BEGIN
SET @destParentID = GetPathLocator(left(@dest, len(@dest) - charindex('\', reverse(@dest) + '\')));
SET @newName = right(@dest, charindex('\', reverse(@dest) + '\') - 1)
END
IF @destParentId != @srcParentId
UPDATE FileTableName
SET path_locator = STUFF(path_locator.ToString(), 1, len(ISNULL(@srcParentId.ToString(), '/')), @destParentId.ToString())
WHERE path_locator.IsDescendantOf(GetPathLocator(@src)) = 1
IF @newName IS NOT NULL
UPDATE FileTableName
SET name = @newName
WHERE path_locator = STUFF(@srcId.ToString(), 1, len(ISNULL(@srcParentId.ToString(), '/')), @destParentId.ToString())
编辑:我几乎已经实现了整个 System.IO.File 和 System.IO.Directory 类来使用 T-SQL 和 FileTable 而不是直接通过 IO。如果您需要任何东西,请联系我。