Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2016.04.10;
Скачать: [xml.tar.bz2];

Вниз

передача 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;
Скачать: [xml.tar.bz2];

Наверх





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


2-1410370393
ROBIN
2014-09-10 21:33
2016.04.10
путь к файлу по клику мыши


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


2-1410257499
Смирнов А.И.
2014-09-09 14:11
2016.04.10
список определенных url из TWebBrowser


15-1438194003
Дмитрий С
2015-07-29 21:20
2016.04.10
Оптимизация сетки бронирования автопарка.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский