问题 如何结合来自不同数据库的数据?


我想到了从不同的数据库中结合两个选择的必要性,即paradox(在bde中)和ms sql server。

目前bde(通过 TQuery)仅用于程序的这一部分(即dbgrid)。现在我需要添加一些存储在ms sql server数据库中的数据(我通常使用它 TADOQuery)到同一个网格。

虽然查询是在完全不同的表上执行的,但是列的结果集的命名和输入类似(我的意思是,如果我有这些表,比如说,在ms sql server数据库中,我可以使用一个简单的联合)。

有没有办法在delphi7中统一从这些中选择的记录集,我可以将结果用作dbgrid的数据源?


5492
2017-12-19 07:31


起源

我不知道delphi,但在.net中我们有Lists,你可以将所有相同类型的记录添加到List中,然后将其转换为DataTable。 - Mahdi Tahsildari
BDE支持(或支持)异构查询 - 请参阅 docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/...。 IIRC我十多年前曾用过一些快速的数据管理器。 - Gerry Coll
+1,不错的问题。 - jachguate


答案:


您可以使用由例如的定义创建的clientdataset。 SQL-Server数据集的数据集并添加paradox数据集的数据。在你的情况下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;

另一个尝试可能是为paradox创建一个链接服务器,我没试过......

http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/SQL_Server_2008/Q_24067488.html


5
2017-12-19 07:36



虽然我无法访问 experts-exchange.com 无论如何,感谢(即+1)与链接服务器的想法。也许有一天我会尝试一下。并接受 - 为了 TClientDataSet。我设法完成了我的任务。非常感谢 - horgh


没问题 AnyDAC LocalSQL。您可以使用任何DataSet执行SQL,不仅可以选择SQL,插入,更新,删除SQL。


4
2017-12-19 13:24



为Anydac LocalSQL +1。它允许“异构”查询。 - GeorgeJ
不幸的是,我倾向于使用内置功能。不过,谢谢。 - horgh


您可以使用内置功能 的TClientdataSet 联合数据的功能 附加 从第二个数据集到第一个数据集的数据。

有不同的方法,我首选的方法是因为简单的代码是添加两个DataSetProviders并将其链接到每个DataSet,例如

dspBDE.DataSet := MyTQuery;
dspADO.DataSet := MyAdoQuery;

然后,到 打开 您的DataSet,您可以这样做:

MyClientDataSet.Data := dspBDE.Data;
MyClientDataSet.AppendData(dspADO.Data, True);

为了使其工作,两个DataSet都必须匹配字段编号和数据类型。由于您的结构类似,如果不自动发生,您可以在SQL中进行类型转换。


3
2017-12-19 15:04



+1 - 这将简化工作 TClientDataSet。谢谢 - horgh


BDE支持(或支持) 异构查询 这允许查询跨越多个数据集,但使用有限的SQL语法。

IIRC我十多年前曾用过一些快速的数据,但我记不起具体细节了 - 多年来我都没有触及过BDE。


2
2017-12-19 10:27



真的很高兴你:“我多年没碰过BDE了“我正在等待我能够不耐烦地对自己说同样的事情))... - horgh


几年前(Delphi 7)我使用了TxQuery,但我不知道它是否还在开发中

我发现了这个 链接


0
2017-12-19 09:19