如何将记录集作为结果返回?(50分)

  • 主题发起人 主题发起人 question
  • 开始时间 开始时间
Q

question

Unregistered / Unconfirmed
GUEST, unregistred user!
比如,我希望在客户端调用应用服务器上的一个方法后得到一个数据集合,
类似 Query1.Dataset := SocketConnection1.AppServer.GetAllUserInfo;
可这个返回的结果参数如何在应用服务器中定义?
 
一般不这么搞.
一定这么搞
那就用OLEVARIANT/VARINAT
 
To 不夜城:
>一般不这么搞
想问问那一般是如何搞的?
 
to question:
可以看一下帮助对 TDataSetProvider 的 OnDataRequest 事件解释中的Example,
很详细的。大体是用与DataSetProvider相连的DataSet取得符合条件的数据集,再将
DataSetProvider的Data属性返回赋给客户端ClientDataSet的Data属性(都是OleVariant),
数据集就传给了ClientDataSet,可以利用ClientDataSet对数据集进行操作了。
所以你返回数据集的接口方法可以将数据集作为OleVariant类型的参数或结果。
 
To bbkxjy:
能给个具体的代码吗?
如果我在服务器上定义了一个 GetAllUserInfo 方法,其中的代码如:
...
ADOQuery.Close;
ADOQuery.Sql.Clear;
ADOQuery.Sql.Append ('SELECT NAME,SEX,AGE FROM DB_0001(NOLOCK) WHERE Address like %李店%');
ADOQuery.Open;
我如何返回这个结果集到客户端?
如果不使用 ClientDataSet 能实现吗?
谢谢!
 
你的意思是不通过DatasetProvider? 如果那样的话也能做到, 不过很麻烦.
如果全用自定义结构的话还稍微简单点.
首先你要在服务端将ADOQuery的结果集生成自定义的结构, 然后将该结构打包成
OleVariant, 然后传给client, client再将该OleVariant解开.(如果不用自定义结构的话
服务端打包容易, delphi有函数可以将Dataset直接打包成OleVariant, 但由于你客户端
不使用clientdataset, 如果你自己分析这个OleVairant以取得数据, 那个工作量相当于
自己写个ClientDataset).
 
To Another_eYes:
如何将数据打包成OleVariant和在客户端如何还原?
例如:我需要从服务器端传递一个文件流到客户端,如何发送和接收?
 
其实打包成OleVariant很简单, 举个例子说明吧, 自己体会一下:
function StreamToOleVariant(Stream: TMemoryStream): OleVariant;
var
p: PChar;
begin
Result := VarArrayCreate([0, Stream.Size-1], varByte);
p := VarArrayLock(Result);
Move(Stream.Memory^, p^, Stream.Size);
VarArrayUnlock(Result);
end;

function OleVariantToStream(Ole: OleVariant): TMemoryStream;
var
p: PChar;
l: Integer;
begin
Result := nil;
l := VarArrayDimCount(Ole);
if l = 0 then
Exit;
p := VarArrayLock(Ole);
Result := TMemoryStream.Create;
Result.WriteBuffer(p^, l);
VarArrUnlock(Ole);
Result.Seek(0,0);
end;
 
多人接受答案了。
 
我也来贴一下,DataSetToOleVariant,来自康伟的主页,上面也有跟eyes的例子相似
的函数。就是把数据拷到二维的Variant数组中,在客户端把这个OleVariant解开就行。
procedure CreateVarArrayFromDataset(var varResultSet: OleVariant;
ADataset : TDataset);
var
m : Integer;
nRecords, nColumns, nCurRec : Integer;
begin

nRecords := -1;
nColumns := -1;

try
{ Create the array... }
{ Set size to 0..m-1 where m equals the number of columns. }
nColumns := Max(0, ADataset.FieldCount-1);

{Each item is an array of size (0..n) where n equals the number of records.
Entry 0 is where we store the column name. }
nRecords := Max(0, ADataset.RecordCount);

varResultSet := VarArrayCreate([0, nColumns, 0, nRecords], varVariant);

for m := 0 to nColumnsdo

varResultSet[m, 0] := ADataset.Fields[m].DisplayLabel;

{ Populate from result set. }
ADataset.First;
nCurRec := 1;
{ Current record number. }
while not ADataset.Eofdo
begin

{ Put in field values. }
for m := 0 to nColumnsdo

varResultSet[m, nCurRec] := ADataset.Fields[m].Value;

ADataset.Next;
Inc(nCurRec);
end;

except
on E: Exceptiondo

raise Exception.Create('CreateVarArrayFromDataset() - ' +
IntToStr(nRecords) +
' rec,'+IntToStr(nColumns)+'cols,'+E.Message);
end;

end;

 
后退
顶部