2016-03-21 16 views
0

Gibt es eine Möglichkeit, alle Datenbankeinträge und -strukturen für mehrere Abfragen in einer XML-Datei zu speichern?TFDMemTable-Daten an eine XML-Datei anhängen

Was ich getan habe ist:

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; 

Dies ist für eine Abfrage funktioniert gut, aber wenn ich den SQL-Text zu ändern und halten die Datei die comtents nennen wird außer Kraft gesetzt. Ich möchte die Abfrage (SQL.text) ändern und alle Abfragedaten in eine XML-Datei speichern.

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

Antwort

3

Wenn Sie in eine XML-Datei erstellen/anhängen, wie Sie beschrieben haben, müssen Sie nicht tatsächlich Notwendigkeit, eine FDMemTable zu verwenden. Sie können etwas tun, was ich unten gezeigt habe, direkt von Ihrer FDQuery.

Wie Sie es sehen werden grundsätzlich

  • Speichert eine TFDQuery zu einem TStringStream im XML-Format;
  • Lädt den Inhalt des StringStream in ein XmlDocument-Objekt mit Windows MSXML-DOM-Parser;
  • Lädt eine XML-Datei von zuvor gespeicherten Abfragen in ein zweites XmlDocument; und
  • Kopiert den Inhalt des Knotens Table aus der gespeicherten Abfrage in das zweite XmlDocument und speichert das Dokument.

Code:

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; 
+0

Dank! Es ist sehr nützlich – Steve88