当前位置:主页>仓库管理软件> 列表

如何把Variant存入数据库中,然后再读出来呢? 找进销存软件系统设计

销售管理软件版1楼: 如何把Variant存入数据库中,然后再读出来呢?
数据库(SQL Server)中应该声明一个什么样的字段类型呢?
如:
vVar : Variant;
vVar := VarArrayOf([''Name1'',''Name2'',''Name3'']);
如何把vVar存入数据库的一条记录的某歌字段中。

2楼: 把Variant转成流,再存进数据库里.读取的时候再转回来.给你两个转换函数.


procedure TNdFileSystem.StreamToVariant (Stream : TMemoryStream; var v : OleVariant); //Stream流转换成olevariant
var
p : pointer;
begin
v := VarArrayCreate ([0, Stream.Size - 1], varByte);
p := VarArrayLock (v);
Stream.Position := 0;
Stream.Read (p^, Stream.Size);
VarArrayUnlock (v);
end;


procedure TNdFileSystem.VariantToStream (const v : olevariant; Stream : TMemoryStream); //olevariant流转换成Stream
var
p: Pointer;
begin
p := VarArrayLock(v);
try
Stream.Write(p^, VarArrayHighBound(v,1) + 1);
finally
VarArrayUnlock(v);
end;
end; 如畅销进销存专业版

3楼: 刚才测试了一下,不行呀。


我首先将vVar1读到流SM中,再从SM读到vVar2中,访问vVar2中的值不正确。
procedure TForm1.TestVarToStream;
var
vVar1: OleVariant;
vVar2: OleVariant;
SM: TMemoryStream;
begin
vVar1 := VarArrayOf([''Name1'',''Name2'',''Name3'']);

SM := TMemoryStream.Create;
try
VariantToStream(vVar1, SM);

StreamToVariant(SM, vVar2);
if VarIsArray(vVar2) then
begin
showmessage(VarToStr(vVar2[0]));
showmessage(VarToStr(vVar2[1]));
showmessage(VarToStr(vVar2[2]));
end
else
showmessage(''Fail'');
finally
SM.Free;
end;
end;

4楼: Midas 中有相关的代码

5楼: 使用 SConnect.pas 中的

TDataBlock

TDataBlockInterpreter

6楼: 能具体些吗?

销售管理软件版7楼: TDataBlock 封装了数据块,也可以看作是字节数组

而 TDataBlockInterpreter 则可以将 Variant 写入这个数据块
或者从这个数据块中读取

而对你来说,从 TDataBlock 再写入数据库或从数据库中读取
以及从 Stream 中读取或写入,都是很容易的事情

8楼: 因为 TDataBlockInterpreter 的 ReadVariant 和 WriteVariant 都声明为私有的方法



所以需要对 SConnect 做一点小小的改动

打开 SConnect.pas 另存到当前目录下

将 TDataBlockInterpreter 开头的 private 改为 public

至于调用的方法如下:

procedure TForm1.Button1Click(Sender: TObject);
var
m, n: Variant;
da: IDataBlock;
di: TDataBlockInterpreter;
fs: TFileStream;
vs: TVarFlags;
begin
m := ''1234gfsadgfds'';

m := VarArrayCreate([0, 4], varVariant);

m[0] := ''faslfda'';
m[2] := ''fjlas''+''_32423'';

da := TDataBlock.Create as IDataBlock;
di := TDataBlockInterpreter.Create(nil, '''');
di.WriteVariant(m, da);

//将 Variant 写入文件,和写入数据库类似
fs := TFileStream.Create(''var_data.dat'', fmCreate);
fs.CopyFrom(da.Stream, da.Size);
FreeAndNil(fs);

//从文件中读取

fs := TFileStream.Create(''var_data.dat'', fmOpenRead);
da.Clear;
da.Stream.CopyFrom(fs, fs.Size);
FreeAndNil(fs);

//还原
n := di.ReadVariant(vs, da);



ShowMessage(n[2] + ''*'' + n[0]);
end;

9楼: 多人接受答案了。

10楼: 可以再用 zlib 压缩一下, 可能会更节省空间

11楼: 不知道benhacker说的函数能否解决同样的问题,我看见很到地方都提到用这两个函数,可是我怎么
试也不行呀

procedure TNdFileSystem.StreamToVariant (Stream : TMemoryStream; var v : OleVariant); //Stream流转换成olevariant
var
p : pointer;
begin
v := VarArrayCreate ([0, Stream.Size - 1], varByte);
p := VarArrayLock (v);
Stream.Position := 0;
Stream.Read (p^, Stream.Size);
VarArrayUnlock (v);
end;

procedure TNdFileSystem.VariantToStream (const v : olevariant; Stream : TMemoryStream); //olevariant流转换成Stream
var
p: Pointer;
begin
p := VarArrayLock(v);
try
Stream.Write(p^, VarArrayHighBound(v,1) + 1);
finally
VarArrayUnlock(v);
end;
end;

12楼: 这个方法有一个前提:

那就是假设 Variant 变量是一个 varByte 类型的数组
如果是其它类型,则肯定是不行的 如进销存软件系统设计