Как объединить данные из разных баз данных?
Я столкнулся с необходимостью объединить два выбора из разных баз данных, а именно Paradox (в BDE) и MS SQL Server.
В настоящее время BDE (через TQuery
) используется только в этой части программы (т.е. dbgrid). Теперь мне нужно добавить некоторые данные, хранящиеся в базе данных MS SQL Server (с которой я обычно использую TADOQuery
) к той же сетке.
Хотя запросы выполняются для совершенно разных таблиц, результирующий набор столбцов именуется и печатается одинаково (я имею в виду, если бы у меня были эти таблицы, скажем, в базе данных сервера MS SQL, я мог бы использовать для этого тривиальное объединение).
Есть ли способ объединить наборы записей, выбранные из них в delphi7, чтобы я мог использовать результат в качестве источника данных для dbgrid?
5 ответов
Вы можете использовать клиентский набор данных, созданный по определению, например. набор данных вашего набора данных SQL-Server и добавить данные вашего набора данных парадокс. TFieldDefArray может быть пустым в вашем случае.
type
TMyFieldDef = Record
Name: String;
Size: Integer;
DataType: TFieldType;
end;
TFieldDefArray = array of TMyFieldDef;
function GetClientDSForDS(ADataSet: TDataSet; AFieldDefArray: TFieldDefArray; AClientDataSet: TClientDataSet = nil; WithRecords: Boolean = true)
: TClientDataSet;
var
i: Integer;
Function NoAutoInc(ft: TFieldType): TFieldType;
begin
if ft = ftAutoInc then
Result := ftInteger
else
Result := ft;
end;
begin
if Assigned(AClientDataSet) then
Result := AClientDataSet
else
Result := TClientDataSet.Create(nil);
Result.Close;
Result.FieldDefs.Clear;
for i := 0 to ADataSet.FieldCount - 1 do
begin
Result.FieldDefs.Add(ADataSet.Fields[i].FieldName, NoAutoInc(ADataSet.Fields[i].DataType), ADataSet.Fields[i].Size);
end;
for i := 0 to High(AFieldDefArray) do
Result.FieldDefs.Add(AFieldDefArray[i].Name, AFieldDefArray[i].DataType, AFieldDefArray[i].Size);
Result.CreateDataSet;
for i := 0 to ADataSet.FieldCount - 1 do
begin
Result.FieldByName(ADataSet.Fields[i].FieldName).DisplayLabel := ADataSet.Fields[i].DisplayLabel;
Result.FieldByName(ADataSet.Fields[i].FieldName).Visible := ADataSet.Fields[i].Visible;
end;
if WithRecords then
begin
ADataSet.First;
while not ADataSet.Eof do
begin
Result.Append;
for i := 0 to ADataSet.FieldCount - 1 do
begin
Result.FieldByName(ADataSet.Fields[i].FieldName).Assign(ADataSet.Fields[i]);
end;
Result.Post;
ADataSet.Next;
end;
end;
end;
другой попыткой может быть создание связанного сервера для парадокса, я не пробовал это...
http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/SQL_Server_2008/Q_24067488.html
Нет проблем с AnyDAC LocalSQL. Вы можете выполнять SQL с любым DataSet, не только выбирать SQL, вставлять, обновлять, удалять SQL тоже.
Вы можете использовать встроенную функциональность TClientDataSet для объединения данных, добавляя данные из второго набора данных к данным первого.
Есть разные способы сделать это, я предпочитаю один, потому что простым кодом будет добавить два DataSetProviders и связать его с каждым из ваших DataSets, например
dspBDE.DataSet := MyTQuery;
dspADO.DataSet := MyAdoQuery;
Затем, чтобы открыть свой DataSets, вы можете просто сделать:
MyClientDataSet.Data := dspBDE.Data;
MyClientDataSet.AppendData(dspADO.Data, True);
Чтобы это работало, оба DataSet должны соответствовать номеру поля и типам данных. Так как ваши структуры похожи, вы можете работать с типизацией в SQL, если это не происходит автоматически.
BDE поддерживает (или поддерживает) гетерогенные запросы. Это позволяет запросам охватывать более одного набора данных, но с ограниченным синтаксисом SQL.
IIRC Я использовал несколько более десяти лет назад для некоторых быстрых и грязных данных, но я не могу вспомнить особенности - я годами не касался BDE.
Несколько лет назад (Delphi 7) я использовал TxQuery, но я не знаю, находится ли он в разработке
Я нашел эту ссылку