文件迁移到FileTable中
看此文档前,先参考一下文档 https://blog.csdn.net/downmoon/article/details/24374609
环境:阿里云ECS SQL Server 2017 + Delphi7
测试用xcopy,robocopy等命令迁移文件好像不太会用。
倒是可以通过T-SQL的方法,但是需要文件在服务器上面,这就有点难受了。如下:
--我们使用该函数插入一个图片文件到该目录下:这里的路径需要是服务器上的路径。
declare @image1 varbinary(max), @path_locator hierarchyid;
select @image1=cast(bulkcolumn as varbinary(max)) from openrowset(bulk N'C:\1.png', single_blob) as x;
select @path_locator=path_locator from DocumentStores where [name]='MyDir1';
insert into DocumentStores(name, file_stream, path_locator)
values('1.png', @image1, dbo.fnGetNewPathLocator(newid(), @path_locator)); --如果你想使用SQL Server本身提供的hierarchyid层次结构,下面这个函数也许可以帮你:
create FUNCTION fnGetNewPathLocator
(@child uniqueidentifier,
@parent hierarchyid)
returns hierarchyid
as
begin
declare @ret hierarchyid, @binid Binary(16) = convert(binary(16), @child);
select @ret=hierarchyid::Parse(
COALESCE(@parent.ToString(), N'/') +
CONVERT(nvarchar, CONVERT(bigint, SUBSTRING(@binId, 1, 6))) + N'.' +
CONVERT(nvarchar, CONVERT(bigint, SUBSTRING(@binId, 7, 6))) + N'.' +
CONVERT(nvarchar, CONVERT(bigint, SUBSTRING(@binId, 13, 4))) + N'/');
return @ret;
end;
通过程序也能实现,只是如果层级太深,生成的path_locator太长,总感觉不太靠谱。
下面是用Delphi实现的,Insert操作(本地E:\Doc目录下所有文件迁移到FileTable)。
procedure TForm1.BitBtn9Click(Sender: TObject);
var
lst, lstContent: TStrings;
I: Integer;
strSQL: string;
begin
lst := TStringList.Create;
lstContent := TStringList.Create;
try
GetFileStructureList('E:\Doc', lst);
strSQL := EmptyStr;
rzprogressbar1.TotalParts := lst.Count;
for I:= to lst.Count- do
begin
SplitString(lst.Strings[I], '|', lstContent);
if SameText(lstContent.Strings[], '') then //目录
strSQL := strSQL + Format('Insert into DocumentStores(name, path_locator, is_directory, is_archive) values(%S, %S, %D, %D);',
[QuotedStr(ExtractFileName(lstContent.Strings[])), QuotedStr(lstContent.Strings[]), , ]) + ##
else if SameText(lstContent.Strings[], '') then //文件
strSQL := strSQL + Format('Insert into DocumentStores(name, path_locator, file_stream) values(%S, %S, %S);',
[QuotedStr(ExtractFileName(lstContent.Strings[])), QuotedStr(lstContent.Strings[]),
StrToHex(BaseEncodeFile(lstContent.Strings[]))]) + ##;
rzprogressbar1.PartsComplete := rzprogressbar1.PartsComplete + ;
Application.ProcessMessages;
end;
try
ADOConnection1.Connected := True;
ADOConnection1.BeginTrans;
ADOQuery1.SQL.Text := strSQL;
ADOQuery1.ExecSQL;
ADOConnection1.CommitTrans;
except
ADOConnection1.RollbackTrans;
end;
finally
lst.Free;
lstContent.Free;
end;
end; //下面是公用单元
unit U_Commfunc; interface uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, EncdDecd, Contnrs; //生成filetable用的path_locator
function GetPathLocator(root: Boolean=True): string;
function GetGUID: string;
function StrToHex(AStr: string): string;
//文件转字符串流
function BaseEncodeFile(fn: TFileName): string;
procedure SplitString(Source,Deli:string; var lst :TStrings);
//获取目录+文件的列表 返回值是文件的个数,顶层为选择的目录 为filetalbe插入用
function GetFileStructureList(Path: PChar; var lst: TStrings): LongInt; implementation function GetGUID: string;
var
LTep: TGUID;
sGUID: string;
begin
CreateGUID(LTep);
sGUID := GUIDToString(LTep);
sGUID := StringReplace(sGUID, '-', '', [rfReplaceAll]);
sGUID := Copy(sGUID, , Length(sGUID) - );
Result := sGUID;
end; function GetPathLocator(root: Boolean): string;
var
//LocatorPath的三个组成部分 S1,S2,S3;
sGuid, S1, S2, S3: string;
begin
Result := '';
if root then
Result := '/';
sGuid := GetGUID;
S1 := IntToStr(StrToInt64(StrToHex(Copy(sGuid, , ))));
S2 := IntToStr(StrToInt64(StrToHex(Copy(sGuid, , ))));
S3 := IntToStr(StrToInt64(StrToHex(Copy(sGuid, , ))));
Result := Result + S1 + '.' + S2 + '.' + S3 + '/';
end; function StrToHex(AStr: string): string;
var
i : Integer;
ch:char;
begin
Result:='0x';
for i:= to length(AStr) do
begin
ch:=AStr[i];
Result:=Result+IntToHex(Ord(ch),);
end;
end; function BaseEncodeFile(fn: TFileName): string;
var
ms: TMemoryStream;
ss: TStringStream;
str: string;
begin
ms := TMemoryStream.Create;
ss := TStringStream.Create('');
try
ms.LoadFromFile(fn);
EncdDecd.EncodeStream(ms, ss); // 将ms的内容Base64到ss中
str := ss.DataString;
str := StringReplace(str, #, '', [rfReplaceAll]); // 这里ss中数据会自动添加回车换行,所以需要将回车换行替换成空字符
str := StringReplace(str, #, '', [rfReplaceAll]);
result := str; // 返回值为Base64的Stream
finally
FreeAndNil(ms);
FreeAndNil(ss);
end;
end; procedure SplitString(Source,Deli:string; var lst :TStrings);
var
EndOfCurrentString: Integer;
begin
if lst = nil then exit;
lst.Clear;
while Pos(Deli, Source)> do
begin
EndOfCurrentString := Pos(Deli, Source);
lst.add(Copy(Source, , EndOfCurrentString - ));
Source := Copy(Source, EndOfCurrentString + length(Deli), length(Source) - EndOfCurrentString);
end;
lst.Add(source);
end; function GetFileStructureList(Path: PChar; var lst: TStrings): LongInt;
var
SearchRec: TSearchRec;
Found: Integer;
TmpStr, TmpLocator: string;
CurDir, DirLocator: PChar;
DirQue: TQueue;
C: Cardinal;
begin
Result := ;
if lst = nil then exit;
dirQue := TQueue.Create;
try
CurDir := Path;
DirLocator := PChar(GetPathLocator());
lst.Add('0|'+CurDir+'|'+DirLocator);
while CurDir <> nil do
begin
//搜索后缀,如:c:\*.*;
TmpStr := IncludeTrailingPathDelimiter(curDir)+'*.*';
Found := FindFirst(TmpStr, faAnyFile, SearchRec);
while Found = do
begin
C := GetFileAttributes(PChar(IncludeTrailingPathDelimiter(curDir) + SearchRec.Name));
//if (searchRec.Attr and faDirectory)<>0 then //这个貌似有问题/
if (C and FILE_ATTRIBUTE_DIRECTORY)<> then
begin
if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
begin
TmpStr := IncludeTrailingPathDelimiter(curDir)+SearchRec.Name;
TmpLocator := GetPathLocator(False);
TmpLocator := DirLocator + TmpLocator;
lst.Add('0|'+TmpStr+'|'+TmpLocator);
DirQue.Push(StrNew(PChar(TmpStr)));
DirQue.Push(StrNew(PChar(TmpLocator)));
end;
end else begin
Result:=Result+;
TmpLocator := GetPathLocator(False);
TmpLocator := DirLocator + TmpLocator;
lst.Add('1|'+IncludeTrailingPathDelimiter(curDir)+SearchRec.Name+'|'+TmpLocator);
end;
found:=FindNext(SearchRec);
end;
{当前目录找到后,如果队列中没有数据,则表示全部找到了;
否则就是还有子目录未查找,取一个出来继续查找。}
if DirQue.Count > then
begin
CurDir := DirQue.Pop;
DirLocator := DirQue.Pop;
end else begin
CurDir := nil;
DirLocator := nil;
end;
end;
finally
dirQue.Free;
end;
end; end.
效果图如下,目录加文件共计20个。
本地文件夹E:\Doc:

FileTable虚拟目录文件Doc:

数据库表中存放数据:

文件迁移到FileTable中的更多相关文章
- Oracle 11g Rac 用rman实现把本地数据文件迁移到ASM共享存储中
在Oracle Rac环境中,数据文件都是要存放在ASM共享存储上的,这样两个节点才能同时访问.而当你在某一节点下把数据文件创建在本地磁盘的时候,那么在另一节点上要访问该数据文件的时候就会报错,因为找 ...
- git文件迁移到新架构
环境: ubuntu16.04 代码托管地址:git.oschina.net 迁移原因: git上某工程是一堆静态页面html,因为在ubuntu下缺乏git图形客户端,想使用eclipse集成的gi ...
- 将数据库从普通文件系统迁移到ASM中
数据库存储的是普通的文件系统,现在将数据库迁移到ASM存储中. 准备ASM环境: [oracle@kel ~]$ asmcmd ASMCMD> ls ASM/ KEL/ ASMCMD> 在 ...
- oracle数据文件迁移
这篇文章是从网络上获取的,然后根据内容一步步操作, 1.目前的疑问:移动日志文件的时候,为何要先进行切换? 2.move操作后,再进行rename操作的原理 --------------------- ...
- 使用.bat 批量将部分文件迁移到新的路径下
1.建一个11.bat ,里面写 : dir /b /s >1111.txt 保存后运行 即将所有的文件路径保存到1111.txt中 2.可以将获取的路径复制到execl中,找到自己需 ...
- 【基本优化实践】【1.1】IO优化——把文件迁移到不同物理磁盘
[1]概念 把不同数据文件移动到不同的物理磁盘,无疑是一个提高IO的有效办法 在资源可以的情况下,尽量把 temp .数据库的主数据文件(mdf).数据库的从数据数据(ndf).数据库的事务日志文件( ...
- java遍历给定目录,树形结构输出所有文件,包括子目录中的文件
(转自:http://blog.csdn.net/gangwazi0525/article/details/7569701) import java.io.File; public class Rea ...
- 如何将已部署在ASM的资源迁移到ARM中
使用过Azure的读者都知道,Azure向客户提供了两个管理portal,一个是ASM,一个是ARM,虽然Azure官方没有宣布说淘汰ASM,两个portal可能会在很长的一段时间共存,但是考虑到AR ...
- 【Python】自动生成html文件查看指定目录中的所有图片
获取本目录下的pic子目录中的所有图片(jpg,png,bmp,gif等,此处以jpg文件为例),然后生成一个image.html文件,打开该html文件即可在浏览器中查看pic子目录中的所有图片. ...
随机推荐
- react-native修改xcode项目名
目录 1. 选中旧工程名,改为新的工程名 2. 依次选择黄色文件夹,修改名字,千万不要在Xcode外修改!!! 3. 点击Find,点击Find and Replace in Project... 4 ...
- 压缩感知重构算法之IRLS算法python实现
压缩感知重构算法之OMP算法python实现 压缩感知重构算法之CoSaMP算法python实现 压缩感知重构算法之SP算法python实现 压缩感知重构算法之IHT算法python实现 压缩感知重构 ...
- 数据库Oracle的select用法(部分)
Oracle的select用法(部分): 1.查询所有: select * from employees; 2.加上where子句:用选择限制行 select * from employees whe ...
- [TimLinux] JavaScript querySelectorAll返回对象无法使用indexOf问题
1. querySelectorAll 该函数返回的对象类型为NodeList,这个类型并没有indexOf方法,如果需要使用indexOf方法,需要先将该对象每一项转存入Array对象中,然后就可以 ...
- Cesium专栏-大量gltf三维模型加载
Cesium 是一款面向三维地球和地图的,世界级的JavaScript开源产品.它提供了基于JavaScript语言的开发包,方便用户快速搭建一款零插件的虚拟地球Web应用,并在性能,精度,渲染质量以 ...
- ZOJ 2112 Dynamic Rankings(树状数组+主席树)
The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...
- 利用PyCharm操作Github:仓库新建、更新,代码回滚
Github是目前世界上最流行的代码存储和分享平台,而PyCharm是Python圈中最流行的IDE,它很好地支持了Git操作.本文将会介绍如何利用PyCharm来连接Github,同时演示Git ...
- 201871010119-帖佼佼《面向对象程序设计(java)》第十二周学习总结
博客正文开头格式: 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nw ...
- 更新Preloader与uboot
1.用bsp-editor 产生Preloader 参考https://rocketboards.org/foswiki/Documentation/AVGSRD160Preloader 根据QSYS ...
- webpack学习1.1 webpack背景介绍
一.为什么要前端需要构建? 开发复杂化 框架去中心化(代码中需要的模块都可以通过npm安装佢解决一个问题,包越来越零散,根据需要来安装) 开发编译化 语言模块化 二.为什么要用webpack? 1.三 ...