Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2016.04.10;
Скачать: CL | DM;

Вниз

передача Recordset через tcp   Найти похожие ветки 

 
dm37   (2010-07-21 12:02) [0]

Подскажите, как можно передать полученный recordset (ADO) в одной программе в другую через TCP
Нужно что-то типа (конечно такая конструкция не работает - rs - это указатель на recordset):
var
 ms: TMemoryStream;
 rs: _Recordset;
begin
 ms.Write(rs,SizeOf(rs));
 TcpClient1.SendStream(ms);
end;

Одна программа получает данные с SQL Server и раздаёт их другим клиентам по tcp ().
Может есть другой способ получения результата выполнения SQL-запроса, который позволит это сделать?


 
sniknik ©   (2010-07-21 12:42) [1]

> Нужно что-то типа (конечно такая конструкция не работает - rs - это указатель на recordset):
естественно, указатель с одной машины на другой ничего не значит.
копируй данные. есть возможность загнать их в ADOStream, а после передачи загрузить из него.

> Может есть другой способ получения результата выполнения SQL-запроса, который позволит это сделать?
трехзвенка, midas, soap, ...


 
dm37   (2010-07-21 14:12) [2]

если можно, то покажите на примере
нашёл один пример, но там идёт преобразование через XML, а это будет достаточно долго (есть правда через ADTG (Advanced Data Tablegram), но как его дальше использовать не понимаю):
var
 adoStream: OleVariant;
 St: TStrings;
begin
 // Сначала ADODB.RecordSet -> ADODB.Stream через XML
 adoStream := CreateOLEObject("ADODB.Stream");
 Variant(ARecordSet).Save(adoStream, adPersistXML);
 // Теперь XML -> TStrings
 St := TStringList.Create;
 St.Text := adoStream.ReadText(adoStream.Size);
 // Ну а теперь всё просто
 AddFromStrings(AName, St);
 // Чищу память
 St.Free;
 adoStream := UnAssigned;

Изначально я думал, что можно сделать так:
у _RecordSet есть метод Save(FileName: WideString, PersistFormat: TOleEnum)
сохранить данные в файл (только не на диске, а в памяти) и записать двоичные данные в TMemoryStream (поток сначало содержит структуру, где указывается тип данных следуемых далее в потоке) и всё это передать одним потоком по tcp.
Но с реализацией ничего пока не получилось, вообще это возможно?

Нужно что-бы работало по возможности быстро.


 
Медвежонок Пятачок ©   (2010-07-21 18:08) [3]

а это будет достаточно долго

"достаточно долго" - это когда сохранение данных рекордсета занимает больше времени, чем последущая передача этих данных по сети

так что на самом деле все наоборот - это "все достаточно быстро"


 
sniknik ©   (2010-07-22 00:18) [4]

> записать двоичные данные в TMemoryStream
procedure SendDataset(Content: TStream; DataSet: TADODataSet);
var
 adoStream: OleVariant;
 Buffer: Variant;
 PBuffer: pointer;
 size: integer;
begin
 adoStream:= CreateOLEObject("ADODB.Stream");
 try
   Variant(DataSet.Recordset).Save(adoStream, adPersistADTG);
   size:= adoStream.Size;

   Buffer := adoStream.Read(size);
   PBuffer:= VarArrayLock(Buffer);
   try
     Content.WriteBuffer(PBuffer^, size);
   finally
     VarArrayUnlock(Buffer);
   end;
 finally
   adoStream:= UnAssigned;
 end;
end;


 
dm37   (2010-07-22 07:03) [5]

Спасибо,
будем пробовать


 
dm37   (2010-07-22 07:24) [6]

Дополнительно вопрос:
в Buffer будет данные в формате который определяет ADO?
а если результат SQL-запроса получать в Linux (например, с PostgreSQL) и передавать его по сети, то формат данных в переменной Buffer (в потоке) будет другим?
Здесь наверно лучше использовать преобразование результат SQL-запроса в XML? Существуют стандарты на единый формат данных результата SQL-запроса?

имеется ввиду, что программа получения данных с SQL Server (PostgreSQL) будет написана под Linux, а не доступ к SQL Server (linux) из Windows через ODBC.

Спасибо.


 
Плохиш ©   (2010-07-22 10:49) [7]


> трехзвенка, midas, soap


> dm37   (21.07.10 14:12) [2]
>
> если можно, то покажите на примере

Этой теме посвящено больше двух трети толстенной книги "Руководство для разработчика" от указанной D7.


 
dm37   (2010-07-22 13:46) [8]

to sniknik
если не затруднит, то можно ещё пример обратного преобразования
TStream -> Recordset

Спасибо за помощь


 
dm37   (2010-07-22 14:46) [9]

В итоге получилось это. Укажите пожалуйста на возможные ошибки (но пока работает):
procedure AddRecordsetToStream(stream: TStream; const Recordset: _Recordset);
var
 rs: Variant;
begin
 if(Recordset = nil) then Exit;
 try
   rs:=CreateOleObject("ADODB.Recordset");
   rs:=Recordset;
   rs.Save(TStreamAdapter.Create(stream) as IUnknown, adPersistADTG);
 finally
 end;
end;

function RecordsetFromStream(const stream: TStream; pos: int64; size: int64): _Recordset;
var
 rs: Variant;
 temp: TStream;
begin
 Result := nil;
//  stream.Position:=pos;
 temp:=TMemoryStream.Create;
 temp.CopyFrom(stream,size);
 try
   temp.Position:=0;
   rs:=CreateOleObject("ADODB.Recordset");
   rs.Open(TStreamAdapter.Create(temp) as IUnknown);
   Result:=IUnknown(rs) as _Recordset;
 finally
   temp.Free;
 end;
end;


 
Slym ©   (2010-07-23 09:24) [10]

dm37   (22.07.10 14:46) [9]
TStreamAdapter.Create(stream) as IUnknown

точно не помню - он точно самоуничтожится? так надежней
procedure AddRecordsetToStream(stream: TStream; Recordset: _Recordset);
var
 st:TStreamAdapter;
 rs:variant;
begin
if(Recordset = nil) then Exit;
st:=TStreamAdapter.Create(stream);
try
  rs:=Recordset as IDispatch;
  rs.Save(st as IUnknown, adPersistADTG);
finally
 st.Free;
end;
end;



Страницы: 1 вся ветка

Текущий архив: 2016.04.10;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.004 c
6-1279699331
dm37
2010-07-21 12:02
2016.04.10
передача Recordset через tcp


2-1410864109
Rakim
2014-09-16 14:41
2016.04.10
Steam


15-1438153716
Kerk
2015-07-29 10:08
2016.04.10
Делаю сегодня в полдень вебинар про статический анализ, приходите


4-1273238553
Pashka.cool
2010-05-07 17:22
2016.04.10
BlueTooth не удаётся обуздать уже несколькими способами.


2-1410889995
Alex_C
2014-09-16 21:53
2016.04.10
Читать TRegistry под Win7 без прав админа