Local SQL (FireDAC)

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Arbeiten mit Anweisungen (FireDAC)

Allgemeine Informationen

Das Feature "Local SQL" ermöglicht die Ausführung von SQL-Anweisungen, wobei die TDataSet-Nachkommen anstatt der DB-Tabellen verwendet werden. Local SQL basiert auf der SQLite-Datenbank und unterstützt den SQLite-SQL-Dialekt (EN) zum größten Teil. Als Tabellenname wird der Name einer TDataSet ("Name"-Eigenschaftswert) oder alternativ ein angegebener Name verwendet. Jede abfragbare Datenmenge muss bei TFDLocalSQL, der Engine von Local SQL, registriert sein.

Alle Operationen zum Lesen und Schreiben werden über die TDataSet-API mit einigen Erweiterungen durchgeführt. Die Engine unterstützt FireDAC- und Nicht-FireDAC-Datenmengen. Local SQL arbeitet effektiver mit FireDAC-Datenmengen. Optional kann für Nicht-FireDAC-Datenmengen das IFDPhysLocalQueryAdapter-Interface als Adapterklasse implementiert und bei der Local SQL-Engine registriert werden.

Mögliche Anwendungen für Local SQL:

  • Heterogene Abfragen (abfragbare Datenmengen haben Ergebnismengen aus verschiedenen DBs).
  • Datenbanken im Arbeitsspeicher (TFDMemTables-Komponenten dienen als Datenmengen).
  • Erweiterter Offline-Modus. In diesem Fall kann eine Anwendung SQL-Abfragen durchführen, auch wenn auf die Haupt-DB nicht zugegriffen werden kann.
  • Erweiterter DataSnap-Client (die vom DataSnap-Treiber an den Client gelieferten Daten können lokal abgefragt werden).
  • Vereinfachte Migration. Entwickler können TDataSet-Objekte von Fremdherstellern in Anwendungen verwenden und über die FireDAC-API mit diesen Datenquellen arbeiten.

Konfiguration

FireDAC verwendet den SQLite-Treiber als Local SQL-Engine. Daher muss die Anwendung zuallererst über eine "lokale" SQLite-Verbindung verfügen. Dabei kann es sich um eine dateibasierte Verbindung zum Lesen/Schreiben, wie z. B. eine Verbindung im Arbeitsspeicher, handeln. Die Verwendung von Verbindungen im Arbeitsspeicher wird empfohlen. Führen Sie die folgenden Schritte aus, um eine derartige Verbindung einzurichten:

Die Anwendung muss die Datenmengen mit der Local SQL-Engine verbinden. Führen Sie dazu die folgenden Schritte aus:

  • Legen Sie eine TFDLocalSQL-Komponente auf dem Formular ab.
  • Setzen Sie deren Eigenschaft Connection auf ein lokales SQLite-Verbindungsobjekt.
  • Weisen Sie der Datenmengeneigenschaft Name einen Wert zu bzw. überprüfen Sie diesen. Dieser Schritt ist für Datenmengen erforderlich, die dynamisch im Code erstellt werden.
  • Setzen Sie für eine FireDAC-Datenmenge die Eigenschaft TFDAdaptedDataSet.LocalSQL auf die TFDLocalSQL-Instanz.
  • Oder verwenden Sie für FireDAC- und Nicht-FireDAC-Datenmengen die Sammlung TFDLocalSQL.DataSets, um TDataSet und den optionalen Adapter bei der Local SQL-Engine zu registrieren. Die DataSets-Sammlung ermöglicht auch das Festlegen eines alternativen Datenmengennamens.

Aktivieren Sie schließlich die folgenden Objekte:

  • Aktivieren Sie die lokale SQLite-Verbindung.
  • Aktivieren Sie die Local SQL-Engine durch Setzen von TFDLocalSQL.Active auf True.
Hinweis: Wenn die Anwendung Basisdatenmengen und lokale Datenmengen verwendet, die mit der SQLite-Verbindung verbunden sind, muss die Verbindung explizit aktiviert werden, bevor eine Datenmenge für diese Verbindung geöffnet/ausgeführt/vorbereitet werden kann. Andernfalls wird eine Exception ausgelöst.

Alternativ können Datenmengen mit der Ereignisbehandlungsroutine TFDLocalSQL.OnGetDataSet an die Local SQL-Engine übergeben werden.

Alle zugeordneten Datenmengen werden bei der Engine registriert, wenn die lokale Verbindung und die Local SQL-Engine aktiv sind. Beim Zuordnen einer neuen Datenmenge muss nichts neu geöffnet werden. Die Datenmenge wird automatisch registriert. Nach der Registrierung wird die Datenmenge geöffnet. Für eine TFDMemTable muss vor dem Öffnen eine definierte Struktur vorhanden sein. Wenn die Anwendung umfangreiche Datenmengenregistrierungen vornimmt, sollte die Local SQL-Engine davor deaktiviert und danach wieder aktiviert werden.

In der Anwendung kann mit TFDLocalSQL.SchemaName ein Schemapräfix eingerichtet werden, das in SQL-Abfragen verwendet wird. Die Anwendung kann mehrere mit derselben Verbindung verbundene TFDLocalSQLs mit oder ohne Schemanamen verwenden. Aber jeder TFDLocalSQL.SchemaName muss in einer SQLite-Verbindung eindeutig sein. Mit einem Schemanamen können Datenmengen in logische Gruppen eingeteilt werden. Wenn ein Schemaname angegeben ist, kann auf die Datenmenge in einer SQL-Anweisung mit <Datenmenge> oder <Schema>.<Datenmenge> verwiesen werden.

Optional kann in der Anwendung TFDLocalSQL.MultipleCursors auf False gesetzt werden, um das Klonen/Kopieren einer Datenmenge zu verhindern. SQLite erstellt zur Ausführung einer SQL-Anweisung, die auf die Datenmenge verweist, einen Cursor. Die TDataSet-API kann nur eine einzelne Position speichern. Um dies zu umgehen, klont FireDAC die FireDAC-Datenmenge mit TFDMemTable und kopiert eine Nicht-FireDAC-Datenmenge in eine TFDMemTable. Wenn der Programmierer sicher ist, dass eine Datenmenge pro Sekunde nur einmal verwendet wird, kann MultipleCursors auf False gesetzt werden, um die Leistung zu verbessern. Bei unidirektionalen Datenmengen wird das Setzen von MultipleCursors auf False nicht empfohlen.

Abfragen

Zur Durchführung einer Local SQL-Abfrage muss die Anwendung TFDQuery/TFDCommand verwenden und Connection/ConnectionName auf die lokale SQLite-Verbindung setzen, die auch für TFDLocalSQL.Connection festgelegt ist. Die Anwendung kann so SQL-Abfragen genau wie bei Nicht-Local SQL-Verbindungen ausführen.

Während der Verarbeitung einer Abfrage wird eine abfragbare Datenmenge mit DisableControls deaktiviert und aktiviert, wenn die Verarbeitung abgeschlossen ist. Setzen Sie TFDLocalSQL.DisableControls auf False, damit eine Datenmenge aktiviert bleibt. Vor dem Lesen einer Datenmenge wird die Ereignisbehandlungsroutine TFDLocalSQL.OnOpenDataSet aufgerufen.

Die Local SQL-Engine unterstützt mit einigen Einschränkungen den SQLite-SQL-Dialekt (EN). Die folgenden SQL-Anweisungen werden für TDataSet-Datenquellen nicht unterstützt:

  • ALTER TABLE ... ADD COLUMN. Ändern Sie stattdessen die Datenmengenstruktur.
  • DROP TABLE. Wird die Verknüpfung einer Datenmenge mit der Local SQL-Engine aufgehoben, wird sie automatisch entfernt (nicht freigegeben).
  • CREATE INDEX / DROP INDEX. Verwenden Sie statt der SQL-Indizes die Indizes der Datenmenge.
  • CREATE TRIGGER / DROP TRIGGER. Verwenden Sie statt der Trigger die Datenmengenereignisse.

Die Local SQL-Engine unterstützt Datenmengen mit mehreren Ergebnismengen nicht.

Die Local SQL-Engine unterstützt die SQL-Anweisungen INSERT/UPDATE/DELETE als Transaktionen und Speicherpunkte. Außerdem werden die entsprechenden SQL-Anweisungen in TDataSet-API-Aufrufe umgewandelt.

Die Local SQL-Engine unterstützt INSERT OR REPLACE, verwendet aber nur Primärschlüsselfelder, um einen zu ersetzenden Datensatz zu suchen, wenn eine Bedingung eines Primär- oder eindeutigen Schlüssels verletzt wird. Wenn nur einige Felder auf der Registerkarte INSERT OR REPLACE INTO (<Felderliste>) angegeben sind, erhalten die Felder, die nicht angegeben sind, beim Aktualisieren NULL-Werte.

Kompatibilität

Die Local SQL-Engine verwendet die TDataSet-API mit einigen vom IFDPhysLocalQueryAdapter-Interface bereitgestellten Erweiterungen. FireDAC-Datenmengen implementieren dieses Interface. Optional können Entwickler für Nicht-FireDAC-Datenmengen eine Klasse erstellen, die das Interface implementiert, und dessen Instanz der Eigenschaft TFDLocalSQL.DataSets[..].Adapter zuweisen.

Außerdem muss eine Datenmenge zum Durchführen von Local SQL-Operationen den folgenden Anforderungen entsprechen:

Operation Anforderungen
INSERT Obligatorisch:
  • Die Methode Append.
  • Die Methode Post.

Optional:

  • PSGetKeyFields muss Primärschlüsselfelder zurückgeben.
UPDATE Obligatorisch:
  • Die Methode Edit.
  • Die Methode Post.
  • Die Methode Locate.

Optional:

  • PSGetKeyFields muss Primärschlüsselfelder zurückgeben.
DELETE Obligatorisch:
  • Die Methode Delete.
  • Die Methode Locate.

Optional:

  • PSGetKeyFields muss Primärschlüsselfelder zurückgeben.
Sortieren / ORDER BY Optional:
  • Wenn afIndexFieldNames in IFDPhysLocalQueryAdapter.Features enthalten ist, wird die Eigenschaft IFDPhysLocalQueryAdapter.IndexFieldNames zum Sortieren der Datenmenge verwendet.
Filtern / WHERE Optional:
  • Wenn afRanges in IFDPhysLocalQueryAdapter.Features enthalten ist, wird die Methode IFDPhysLocalQueryAdapter.SetRange zum Filtern der Datenmenge verwendet.
  • Wenn afFilters in IFDPhysLocalQueryAdapter.Features enthalten ist, wird auch die Eigenschaft Filter verwendet.
Speicherpunkte Obligatorisch:
  • Wenn afCachedUpdates, afSavePoints in IFDPhysLocalQueryAdapter.Features enthalten ist , wird die Eigenschaft IFDPhysLocalQueryAdapter.Savepoint verwendet.
Transaktionen Obligatorisch:
  • Die Methode PSStartTransaction.
  • Die Methode PSEndTransaction.


Beispiel 1

Die folgende heterogene Abfrage verwendet SQL Anywhere- und Oracle-Tabellen und FireDAC-TFDQuerys:

 // setup connection and query to "Orders" table in SQL Anywhere DB
 FDConnection1.ConnectionDefName := 'ASA_Demo';
 FDConnection1.Connected := True;
 FDQuery1.Connection := FDConnection1;
 FDQuery1.SQL.Text := 'select * from Orders';
 // link dataset to Local SQL engine
 FDQuery1.LocalSQL := FDLocalSQL1;
 
 // setup connection and query to "Order Details" table in Oracle DB
 FDConnection2.ConnectionDefName := 'Oracle_Demo';
 FDConnection2.Connected := True;
 FDQuery2.Connection := FDConnection2;
 FDQuery2.SQL.Text := 'select * from "Order Details"';
 // link dataset to Local SQL engine
 FDQuery2.LocalSQL := FDLocalSQL1;
 
 // setup SQLite in-memory connection
 FDConnection3.DriverName := 'SQLite';
 FDConnection3.Connected := True;
 // link Local SQL to SQLite connection
 FDLocalSQL1.Connection := FDConnection3;
 FDLocalSQL1.Active := True;
 
 // execute SELECT query on above datasets
 FDQuery3.Connection := FDConnection3;
 FDQuery3.SQL.Text := 'SELECT * FROM FDQuery1 LEFT JOIN FDQuery2 ON FDQuery1.OrderID = FDQuery2.OrderID';
 FDQuery3.Active := True;


Beispiel 2

Die folgende heterogene Abfrage verwendet ADO-TADOQuerys und FireDAC-TFDQuerys:

 // setup connection and query to "Orders" table
 ADOQuery1.SQL.Text := 'select * from Orders';
 // link dataset to Local SQL engine
 with FDLocalSQL1.DataSets.Add do begin
   DataSet := ADOQuery1;
   Name := 'Orders';
 end;
 
 // setup connection and query to "Order Details" table
 ADOQuery2.SQL.Text := 'select * from "Order Details"';
 // link dataset to Local SQL engine
 with FDLocalSQL1.DataSets.Add do begin
   DataSet := ADOQuery2;
   Name := 'Order Details';
 end;
 
 // setup SQLite in-memory connection
 FDConnection1.DriverName := 'SQLite';
 FDConnection1.Connected := True;
 // link Local SQL to SQLite connection
 FDLocalSQL1.Connection := FDConnection1;
 FDLocalSQL1.Active := True;
 
 // execute SELECT query on above datasets
 FDQuery1.Connection := FDConnection1;
 FDQuery1.SQL.Text := 'SELECT * FROM Orders o LEFT JOIN "Order Details" od ON o.OrderID = od.OrderID';
 FDQuery1.Active := True;

Siehe auch

Beispiele