delphi - 将 TFDMemTable 数据附加到一个 XML 文件中

标签 delphi delphi-xe firedac

有没有办法将多个查询的所有数据库记录和结构保存到一个 XML 文件中?

我所做的是:

procedure CopyRecords(Sender: TObject);
begin
  try

  TFDQuery.SQL.Text := 'SELECT * FROM SAMPLE_TABLE1';
  TFDQuery.FetchOptions.Unidirectional := False;
  TFDQuery.Open;
  TFDQuery.FetchAll;

  TFDmemtable.Data := DM.qry_SQL.Data;
  TFDmemtable.First;

  while not TFDmemtable.Eof do
  begin
    TFDmemtable.Edit;

    TFDmemtable.Post;
    TFDmemtable.Next;
  end;

  TFDmemtable.SaveToFile('C:\Test.xml', sfXML); 
  finally
    TFDmemtable.Close;
  end;
end;

这对于一个查询来说效果很好,但如果我更改 SQL 文本并保留文件名,内容就会被覆盖。我想更改查询 (SQL.text) 并将所有查询数据保存到 一个 XML 文件中。

TFDQuery.SQL.Text := 'SELECT * FROM SAMPLE_TABLE1';
... save ...
TFDQuery.SQL.Text := 'SELECT * FROM SAMPLE_TABLE2';
... save (append) ...

最佳答案

如果您想按照您所描述的那样创建/附加到 Xml 文件,那么您实际上并不需要这样做 需要使用 FDMemTable。您可以直接从 FDQuery 执行如下所示的操作。

基本上你会看到

  • 以 XML 格式将 TFDQuery 保存到 TStringStream;
  • 使用以下命令将 StringStream 的内容加载到 XmlDocument 对象中 Windows 的 MSXML DOM 解析器;
  • 将先前保存的查询的 XML 文件加载到第二个 XmlDocument 中;和
  • Table 节点的内容从保存的查询复制到 第二个 XmlDocument 并保存文档。

代码:

uses

  Data.DB, ADOInt, Data.Win.ADODB, Vcl.StdCtrls, Vcl.Grids, Vcl.DBGrids,
  System.Classes, SysUtils, Variants, Vcl.Forms, Vcl.Controls, Vcl.ExtCtrls, Vcl.DBCtrls,
  FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf,
  FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async,
  FireDAC.Phys, FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf,
  FireDAC.DApt, FireDAC.Comp.DataSet, FireDAC.Comp.Client, FireDAC.Phys.MSSQL,
  FireDAC.Phys.MSSQLDef, FireDAC.VCLUI.Wait, FireDAC.Comp.UI,
  Dialogs, FireDAC.Stan.StorageXML, WinApi.MSXMLIntf, WinApi.MSXML;

type
  TForm1 = class(TForm)
    DataSource1: TDataSource;
    DBNavigator1: TDBNavigator;
    DBGrid1: TDBGrid;
    FDConnection1: TFDConnection;
    FDQuery1: TFDQuery;
    FDGUIxWaitCursor1: TFDGUIxWaitCursor;
    Button1: TButton;
    Memo1: TMemo;
    FDStanStorageXMLLink1: TFDStanStorageXMLLink;  // This is needed to save the Query to XML
    [...]
  protected
    procedure SaveToXML(FDQuery: TFDQuery);
  end;

const
  scSavedData = 'D:\delphi\code\firedac\SavedData.Xml';
  scSavedSingleQuery = 'D:\delphi\code\firedac\SavedSingleQuery.Xml';
  scSavedDataXML = '<?xml version="1.0" encoding="utf-8"?><Data/>';

procedure TForm1.SaveToXML(FDQuery: TFDQuery);
var
  SS : TStringStream;
  XmlDoc1,
  XMlDoc2 : IXMLDOMDocument2;
  NodeList: IXmlDomNodeList;
  nSource: IXmlDomNode;
  nDestination : IXmlDomNode;
  eDestination : IXmlDomElement;
begin
  SS := TStringStream.Create;
  XmlDoc1 := CoDomDocument.Create;
  try
    FDQuery.SaveToStream(SS, sfXML);
    XmlDoc1.loadXML(SS.DataString);
    NodeList := XmlDoc1.documentElement.selectNodes('//FDBS/Manager/TableList/Table');
    nSource := NodeList.item[0];
    //  At this point, nSource is the XML node which contains the data + metadata
    //  of the FDQuery's result set
    //  Next we splice it into an XML file of previously saved FDQuery result sets
    //  or create this file if it doesn't already exist

    XmlDoc2 := CoDomDocument.Create;
    if FileExists(scSavedData) then begin
      XmlDoc2.load(scSavedData)
    end
    else begin
      XmlDoc2.loadXML(scSavedDataXML);
    end;
    nDestination := nSource.cloneNode(True) as IXmlDomNode;
    XmlDoc2.documentElement.appendChild(nDestination);
    eDestination := nDestination as IXmlDomElement;
    eDestination.setAttribute('Sql', FDQuery.SQL.Text);

    Memo1.Lines.Text := XmlDoc2.documentElement.Xml;
    XmlDoc2.save(scSavedData);
  finally
    SS.Free; //  Only this needs to be freed
    //  all the other (interface) objects will be finalized as the procedure exits
  end;
end;

关于delphi - 将 TFDMemTable 数据附加到一个 XML 文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36137698/

相关文章:

delphi - 使用 FireDAC 连接到嵌入式 Firebird 2.5

android - Delphi xe7 android中的Messagedlg

Delphi 7.0和内存泄漏?

delphi - 重新引发异常的成本是多少?

Delphi XE - 调用 Crystal Reports

mysql - 使用 Delphi 和firedac 编辑MySQL 中的日期时间字段

delphi - DCEF3 - Chromium 版本

delphi - 编写像 PartitionManager 这样的低级程序

delphi - 如何强制密码编辑器出现 "Caps Lock is On"气球?

sql-server - 德尔福EMS FireDAC : How to pass parameter from client to server using EMS?