看此文档前,先参考一下文档 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中的更多相关文章

  1. Oracle 11g Rac 用rman实现把本地数据文件迁移到ASM共享存储中

    在Oracle Rac环境中,数据文件都是要存放在ASM共享存储上的,这样两个节点才能同时访问.而当你在某一节点下把数据文件创建在本地磁盘的时候,那么在另一节点上要访问该数据文件的时候就会报错,因为找 ...

  2. git文件迁移到新架构

    环境: ubuntu16.04 代码托管地址:git.oschina.net 迁移原因: git上某工程是一堆静态页面html,因为在ubuntu下缺乏git图形客户端,想使用eclipse集成的gi ...

  3. 将数据库从普通文件系统迁移到ASM中

    数据库存储的是普通的文件系统,现在将数据库迁移到ASM存储中. 准备ASM环境: [oracle@kel ~]$ asmcmd ASMCMD> ls ASM/ KEL/ ASMCMD> 在 ...

  4. oracle数据文件迁移

    这篇文章是从网络上获取的,然后根据内容一步步操作, 1.目前的疑问:移动日志文件的时候,为何要先进行切换? 2.move操作后,再进行rename操作的原理 --------------------- ...

  5. 使用.bat 批量将部分文件迁移到新的路径下

    1.建一个11.bat ,里面写  :   dir  /b /s  >1111.txt 保存后运行 即将所有的文件路径保存到1111.txt中 2.可以将获取的路径复制到execl中,找到自己需 ...

  6. 【基本优化实践】【1.1】IO优化——把文件迁移到不同物理磁盘

    [1]概念 把不同数据文件移动到不同的物理磁盘,无疑是一个提高IO的有效办法 在资源可以的情况下,尽量把 temp .数据库的主数据文件(mdf).数据库的从数据数据(ndf).数据库的事务日志文件( ...

  7. java遍历给定目录,树形结构输出所有文件,包括子目录中的文件

    (转自:http://blog.csdn.net/gangwazi0525/article/details/7569701) import java.io.File; public class Rea ...

  8. 如何将已部署在ASM的资源迁移到ARM中

    使用过Azure的读者都知道,Azure向客户提供了两个管理portal,一个是ASM,一个是ARM,虽然Azure官方没有宣布说淘汰ASM,两个portal可能会在很长的一段时间共存,但是考虑到AR ...

  9. 【Python】自动生成html文件查看指定目录中的所有图片

    获取本目录下的pic子目录中的所有图片(jpg,png,bmp,gif等,此处以jpg文件为例),然后生成一个image.html文件,打开该html文件即可在浏览器中查看pic子目录中的所有图片. ...

随机推荐

  1. 5-- String 、StringBulid 、StringBuffer的区别

    String是典型的Immutable(不可变)类,被声明为final class,所有属性都是final的.由于它的不可变性,类似拼接.截取字符串等操作都会产生新的String对象,往往编码中常常对 ...

  2. electron中JS报错:require is not defined的问题解决方法

    Electron已经发布了6.0正式版,升级后发现原来能运行的代码报错提示require is not defined 解决办法: 修改创建BrowserWindow部分的相关代码,设置属性webPr ...

  3. 初探three.js几何体

    今天说说three.js的几何体,常见的几何体今天就不说了,今天说一说如何画直线,圆弧线,以及高级几何体. 1. 画一条直线 画直线我们使用THREE.Geometry()对象. //给空白几何体添加 ...

  4. 关于Java调用接入微信、支付宝支付提现

    前言: 本篇文章介绍关于自己写的一个集成微信.支付宝的支付.提现等功能的介绍,本项目已在码云上进行开源,欢迎大家一起来进行改造,使进行更好的创新供大家使用:也有对应的pom文件坐标可以导入,因目前不知 ...

  5. 使用for语句输出1-100之间的所有偶数

    使用for语句输出1-100之间的所有偶数 for i in range(1,101): if i%2==0: print(i) 使用while语句输出1-100之间能够被3整除的数字 j=1 whi ...

  6. poj 1062 昂贵的聘礼 (有限制的最短路)

    昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 56594   Accepted: 17083 Descripti ...

  7. fastText训练word2vec并用于训练任务

    最近测试OpenNRE,没有GPU服务器,bert的跑不动,于是考虑用word2vec,捡起fasttext 下载安装 先clone代码 git clone https://github.com/fa ...

  8. orleans 2.0 进阶之自定义持久化储存

    一丶简单介绍下目录结构和项目依赖,如图 二丶主要核心自定义代码 1. 添加自定义实现类 CustomProvider public class CustomProvider : IGrainStora ...

  9. 如何开启MySQL慢查询日志

    一.开启慢查询日志首先需要了解四个参数: slow_query_log # 是否开启慢查询日志,默认OFF,开启则设置为 ON. slow_query_log_file # 慢查询日志文件存储位置. ...

  10. vue路由进阶

    一..全局路由前置守卫 1.首先看一下文档结构 Dashboard和Login是一级页面  home about mine是在Dashboard下的二级页面 2.router.js代码如下 impor ...