流的传输 C/S 数据库 三层数据库(200分)

  • 主题发起人 主题发起人 wudoo
  • 开始时间 开始时间
W

wudoo

Unregistered / Unconfirmed
GUEST, unregistred user!
本人在用Indy写一个c/s程序时发现一个问题,就是查询单表时,没有问题,但是传输统计表时就出现错误,有那位大侠遇过类似的问题,请指教,谢了!源码如:
server:
var
sCommand,ss: string;
AStream:TMemoryStream;
begin
AStream:=TMemoryStream.Create;
with AThread.Connection do begin
sCommand := ReadLn();
if pos('@',sCommand)>0 then begin
ss:=copy(sCommand,pos('@',sCommand)+1,length(sCommand));
sCommand:=copy(sCommand,1,pos('@',sCommand)-1);
end;
if SameText(sCommand, 'Q102') then begin
try
dmServer.clds0.Close;
dmServer.clds0.CommandText:=ss;
dmServer.clds0.Open;
dmServer.clds0.First;
dmServer.clds0.SaveToStream(AStream);
AStream.Position := 0;
OpenWriteBuffer();
WriteStream(AStream,true,true);
CloseWriteBuffer();
disconnect;
AStream.Free;
Except
on E: Exception do begin
disconnect;
AStream.Free;
end;
end;
end
end;
Client:
procedure TDm.myExecute(var clds:TClientDataSet;const sCmd,sqlStr:string);
var AStream:TMemoryStream;
IdTCPClient:TIdTCPClient;
begin
AStream:=nil;
IdTCPClient:=TIdTCPClient.Create(nil);
IdTCPClient.Host:=127.0.0.1;
IdTCPClient.Port:=8002;
///////////////////////////////////////////////
if not IdTCPClient.Connected then IdTCPClient.Connect(5000);
if not IdTCPClient.Connected Then exit;
with IdTCPClient do
try
if sCmd='Q' Then begin
WriteLn('Q102@'+sqlStr);
AStream:=TMemoryStream.Create;
ReadStream(AStream);
AStream.Position:=0;
clds.Close;
clds.LoadFromStream(aStream);
clds.Open;
clds.First;
AStream.Free;
IdTCPClient.Disconnect
except
on E: Exception do begin
IdTCPClient.Disconnect ;
end;
end;
end;
select * from aCustomer //没有问题
select sum(amount) from aCustomer group by customerno //有问题,数量出错
 
嘿,我也试过的,用clientDataSet带的方法存为流,有问题,你用下面这三个函数转换下就可以了
//把流转换成ClientDataSet可以接受的OleVariant类型
function TForm1.StreamToVar(Stream: TStream): OleVariant;
var
P: Pointer;
begin
Result := VarArrayCreate([0, Stream.size -1],Varbyte);
P := VarArrayLock(Result);
Try
Stream.Position := 0;
Stream.Read(P^, Stream.size);
Finally
VarArrayUnlock(Result);
end;
end;

//把ClientDataSet的数据集转换成流
function TForm1.VarToStream(Const Data: OleVariant): TStream;
var
P: Pointer;
Stream: TStream;
begin
Stream := TMemoryStream.Create;
P := VarArrayLock(Data);
try
Stream.write(P^, VarArrayHighBound(Data, 1)+1);
finally
VarArrayUnlock(Data);
end;
Result := Stream;
end;

//数据集转换成ClientDataSet可以接受的Variant类型
function TForm1.DataSetToVar(ADataSet: TDataSet; Recs: Integer): olevariant;
var //recs代表要转换的记录,-1为全部.
DPW: TDataPacketWriter;
V: OleVariant;
BK: TBookMarkStr;
begin
if ADataSet <> nil then
try
DPW := TDataPacketWriter.Create;
DPW.PacketOptions := [grMetaData];
ADataSet.DisableControls;
BK := ADataSet.Bookmark;
ADataSet.First;
DPW.GetDataPacket(ADataSet, Recs, V);
finally
DPW.Free;
ADataSet.Bookmark := BK;
ADataSet.EnableControls;
end;
Result := V;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
sql:string;
begin
sql:='select * from test';
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add(sql);
ADOQuery1.Open;
ClientDataSet2.Data := DataSetToVar(AdoQuery1, -1);

TestStream:= VarToStream(ClientDataSet2.Data);

ClientDataSet3.Data:=StreamToVar(TestStream);
ClientDataSet3.Active:=True;

{ ClientDataSet1.Close;
ClientDataSet1.CommandText:=sql;
ClientDataSet1.Execute;
ClientDataSet1.Open;
ClientDataSet1.Refresh;
ClientDataSet3.Data:=ClientDataSet1.Data;
ClientDataSet3.Active:=True;
showMessage(IntToStr(ClientDataSet3.DataSize)); }

// ClientDataSet3.SaveToStream(TestStream,dfBinary);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
TestStream:=TStream.Create;
end;
 
pladxhy:
请教一下TDataPacketWriter类何处可找到?
 
已找到TDataPacketWriter,试下先。
 
帮顶!

╭=========================================╮

80G海量源代码,控件,书籍全免费狂下不停!

http://www.source520.com

个人网站站长开发推广同盟,让所有人知道你的世界!

http://www.source520.com/search/search.asp

╰=========================================╯
 
pladxhy,
我试了,还是不行,情况跟直接用ClientDataSet的SaveToStream情况一样,依你的方法,我是这样试的,从ClientDataSet.data->stream->到服务器TCP/IP->客户端的TCP/IP->Stream->ClientDataSet.data;请问一下,你是如何传到客户端的呢?
 
接受答案了.
 
后退
顶部