Форум: "Сети";
Текущий архив: 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