文件迁移到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子目录中的所有图片. ...
随机推荐
- ios中陀螺仪CoreMotion的用法
转自:http://code.eoe.cn/471/title/ios涓檧铻轰华CoreMotion鐨勭敤娉 README.md 外部引用 原始文档 以前在iphone中要得到加速度时,只能使用Ac ...
- 【Springboot】Springboot整合Jasypt,让配置信息安全最优雅方便的方式
1 简介 在上一篇文章中,介绍了Jasypt及其用法,具体细节可以查看[Java库]如何使用优秀的加密库Jasypt来保护你的敏感信息?.如此利器,用之得当,那将事半功倍.本文将介绍Springboo ...
- Vue&Cesium&Ribbon界面: 将桌面GIS搬进浏览器
上一篇文章在这里:vue集成cesium,webgis平台第一步 把界面改了一下,开始实际填充功能. Ribbon是一种以面板及标签页为架构的用户界面(User Interface),原先出现在Mic ...
- 计蒜客-蒜场抽奖(AC自动机+状态压缩DP)
题解:题意不再说了,题目很清楚的. 思路:因为N<=10,所以考虑状态压缩 AC自动机中 val[1<<i]: 表示第i个字符串.AC自动机中fail指针是指当前后缀在其他串里面所能 ...
- CodeForces-508A~D篇 div.2
链接:https://codeforc.es/contest/1038 A题: #include<bits/stdc++.h> using namespace std; typedef l ...
- 【MySQL】ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
问题现象: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) 拒绝访问root用户 ...
- 理解Vue中的nextTick
参考博客:https://www.jianshu.com/p/a7550c0e164f
- 【Java Web开发学习】Spring MVC添加自定义Servlet、Filter、Listener
[Java Web开发学习]Spring MVC添加自定义Servlet.Filter.Listener 转载:https://www.cnblogs.com/yangchongxing/p/9968 ...
- Java中Object类常用的12个方法,你用过几个?
前言 Java 中的 Object 方法在面试中是一个非常高频的点,毕竟 Object 是所有类的“老祖宗”.Java 中所有的类都有一个共同的祖先 Object 类,子类都会继承所有 Object ...
- Spring AOP应用场景你还不知道?这篇一定要看!
回顾一下Spring AOP的知识 为什么会有面向切面编程(AOP)? 我们知道Java是一个面向对象(OOP)的语言,但它有一些弊端,比如当我们需要为多个不具有继承关系的对象引入一个公共行为,例如日 ...