Generieren von Aktualisierungsanweisungen (FireDAC)

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Bearbeiten von Daten (FireDAC)

Allgemeine Informationen

Beim Aufruf der folgenden Datenmengenmethoden durch die Datenbankanwendung werden unterschiedliche Aktualisierungsmodi verwendet:

FireDAC generiert hierfür automatisch SQL-Anweisungen zur Datenaktualisierung. Dem SQL-Anweisungsgenerator von FireDAC sind die Datenbankidentitätsfelder, Sequenzen, Trigger, speziellen Datentypen (Oracle BLOB/CLOB/BFILE usw.) bekannt, und er generiert je nach verbundenem DBMS eine effiziente SQL-Anweisung. Dadurch wird die Anzahl der Fälle, in denen ein Entwickler manuelle SQL-Anweisungen verwenden muss, reduziert. In FireDAC müssen Entwickler nicht unbedingt TFDUpdateSQL verwenden, das zum Überschreiben der SQL-Aktualisierungsanweisungen eingesetzt werden kann.

Beim Eintragen eines neuen Datensatzes in eine Oracle-Tabelle, wobei das ID-Feld durch einen Trigger aus einer Sequenz gefüllt wird und IMAGE dem Typ BLOB hat, generiert FireDAC beispielsweise die folgende SQL-Anweisung:

 INSERT INTO OracleTab (NAME, DT, IMAGE)
 VALUES (:NEW_NAME, :NEW_DT, EMPTY_BLOB())
 RETURNING :NEW_ID, :NEW_IMAGE

1. FROM, INTO und UPDATE

FireDAC verwendet die Haupttabelle (die erste) in der "SELECT ... FROM ..."-Anweisung als Name der zu aktualisierenden Tabelle. Diese Tabelle wird auch zum Abrufen der mkPrimaryKeyFields-Metadaten verwendet. Mit UpdateOptions.UpdateTableName geben Sie die zu aktualisierende Tabelle an. Dies ist erforderlich, wenn:

  • Die Datenmenge TFDStoredProc ist.
  • TFDQuery keine SELECT-Abfrage enthält.
  • FireDAC den Namen der zu aktualisierenden Tabelle nicht korrekt aus der Abfrage abrufen kann.
  • Die Anwendung Aktualisierungen an eine bestimmte Tabelle umleiten muss.

2. WHERE

UpdateOptions.UpdateMode steuert die Generierung der WHERE-Klausel zum Eintragen von Aktualisierungen und Löschungen. Der Vorgabewert upWhereKeyOnly verwendet in der WHERE-Klausel nur die eindeutigen Kennzeichnungsspalten und stellt einen effizienten und sicheren Weg zum Lokalisieren der zu aktualisierenden Zeile dar. Wenn keine eindeutigen Kennzeichnungsspalten angeben sind und keine Kennzeichnungsspalte für Zeilen gefunden wird, setzt FireDAC UpdateOptions.UpdateMode auf upWhereAll. Wenn die folgenden Felder in der WHERE-Klausel angegeben sind, kann dies zum Fehler "Keine Zeilen gefunden führen":

  • DOUBLE-, FLOAT-, TIME- und DATETIME-Felder und andere gleitkommabasierten Felder können zu Genauigkeitsverlusten beim Wertevergleich führen.
  • Textfelder können eine ungültige Codierung oder zusätzliche Leerstellen enthalten, was zu erfolglosen Vergleichen führt.
  • Andere ähnliche Fehler können auftreten.

In solchen Fällen erhält die Anwendung eine Exception:

 [FireDAC][DApt]-400. Update command updated [0] instead of [1] record.

Entsprechend kann mehr als ein Datensatz aktualisiert werden, wenn Spalten in der WHERE-Klausel eine Zeile nicht eindeutig kennzeichnen. Die Exception lautet dann folgendermaßen:

 [FireDAC][DApt]-400. Update command updated [4] instead of [1] record.

Um diese Probleme zu beheben, können Sie:

  • Korrekte eindeutige Kennzeichnungsspalten bereitstellen.
  • Einige Felder mit WHERE-Verwendung deaktivieren, indem Sie pfInWhere aus der entsprechenden TField.ProviderFlags-Eigenschaft ausschließen.
  • Diese Fehler durch Setzen von UpdateOptions.CountUpdatedRecords auf False unterdrücken.

Hinweis: Zur Vermeidung der obigen Probleme bei einer SQL Server-Tabelle, die auch über Trigger verfügt, sollte für die Trigger anfänglich SET NOCOUNT ON angegeben werden. Wenn das nicht möglich ist, dann setzen Sie UpdateOptions.CountUpdatedRecords auf False.

3. SET und VALUES

UpdateOptions.UpdateChangedFields steuert die Felder, die in die "UPDATE SET ..."- oder "INSERT VALUES ..."-Klauseln einbezogen werden. Wenn Sie diese Eigenschaft auf True setzen, werden nur die geänderten Felder einbezogen, wodurch Folgendes erreicht wird:

  • Minimierung des Verkehrs beim Eintragen von Aktualisierungen
  • Vermeidung von unnötigen Bedingungsverletzungen
  • Vermeidung des zusätzlichen Auslösens von Triggern
  • Minimierung der Generierung des Wiederholungsprotokolls

Wenn Sie diese Eigenschaft auf False setzen, werden alle Felder einbezogen, wodurch dieselbe erzeugte Anweisung zum Eintragen aller Aktualisierungen wiederverwendet und die DBMS-Arbeit zur Vorbereitung der Anweisungen minimiert werden kann.

Schließen Sie pfInUpdate aus der entsprechenden TField.ProviderFlags-Eigenschaft aus, um alle Aktualisierungen für Spalten zu deaktivieren.

4. RETURNING und weitere SELECT-Anweisungen

UpdateOptions.RefreshMode = rmOnDemand steuert die automatische Aktualisierung von Spaltenwerten, die vom DBMS nach dem Einfügen oder Aktualisieren eines Datensatzes geändert worden sein könnten. Für folgende Spalten kann nach dem Einfügen eines Datensatzes eine Aktualisierung erforderlich sein:

  • Auto-Inkrementierungsspalten
  • Berechnete Datenbankspalten
  • Spalten mit Vorgabewerten
  • Kennzeichnungsspalten für Zeilen
  • Zeitstempelspalten
  • Spalten, die von einem Trigger aktualisiert wurden

Für folgende Spalten kann nach dem Aktualisieren eines Datensatzes eine Aktualisierung erforderlich sein:

  • Berechnete Datenbankspalten
  • Zeitstempelspalten
  • Spalten, die von einem Trigger aktualisiert wurden

Ja nach DBMS-Features werden die zusätzlichen Klauseln/Anweisungen generiert und die aktualisierten Spaltenwerte zurückgegeben:

  • Oracle, Firebird, PostgreSQL – RETURNING-Klausel
  • DB2 – die "SELECT ... FROM FINAL TABLE"-Klausel
  • SQL Server, SQL Anywhere, SQLite – der SQL-Stapel mit einer zusätzlichen SELECT-Anweisung
  • andere – eine zusätzliche SELECT-Anweisung

5. Zwischenspeichern von Aktualisierungsanweisungen

In machen Fällen kann durch Setzen von UpdateChangedFields auf False die Leistung verbessert werden. Und zusammen mit einigen anderen Einstellungen, wie der Eigenschaft UpdateOptions.FastUpdates, ist es sogar möglich, eine bessere Leistung durch Vermeiden von zusätzlichen Abfragen und Aktivieren der Zwischenspeicherung der generierten Aktualisierungsanweisungen beim Eintragen von Aktualisierungen zu erzielen.

FastUpdates = True entspricht:

Siehe auch