Aktualisieren von Daten in einer temporalen Tabelle für Systemzeitraum
Das Aktualisieren von Daten in einer temporalen Tabelle für Systemzeitraum führt dazu, dass Zeilen in die zugehörige Protokolltabelle eingefügt werden.
Informationen zu dieser Task
Hinweis: Zeitmarkenwertkonflikte können auftreten, wenn mehrere Transaktionen dieselbe Zeile aktualisieren. Wenn diese Konflikte auftreten, bestimmt die Einstellung für den Datenbankkonfigurationsparameter systime_period_adj , ob Zeitmarkenanpassungen vorgenommen werden oder ob Transaktionen fehlschlagen. Das Beispiel Mehrere Änderungen an einer Zeile durch unterschiedliche
Transaktionen im Abschnitt Weitere Beispiele bietet weitere Details. Anwendungsprogrammierer sollten die Verwendung von SQLCODE- oder SQLSTATE-Werten erwägen, um potenzielle auf die Anpassung von Zeitmarkenwerten bezogene Rückkehrcodes über SQL-Anweisungen zu handhaben.
Prozedur
Zum Aktualisieren von Daten in einer temporalen Tabelle für
Systemzeitraum
wird die Anweisung UPDATE verwendet.
Zum Beispiel wurde festgestellt, dass es einige Fehler in den Versicherungsdeckungssummen für einen Kunden gab, und die folgenden Daten wurden am 28. Februar 2011 (2011-02-28) in der Beispieltabelle aktualisiert, die Daten im
Einfügen von Daten in eine System-Perioden-Zeittafel-Thema hinzugefügt hatte.
Die folgende Tabelle enthält die ursprünglichen Daten der Tabelle
policy_info.| policy_id | coverage | sys_start | sys_end | ts_id |
|---|---|---|---|---|
| A123 | 12000 | 31.01.2010- 22.31.33. 495925000000 |
9999-12-30- 00.00.00.000000000000 |
31.01.2010- 22.31.33. 495925000000 |
| B345 | 18000 | 31.01.2010- 22.31.33. 495925000000 |
9999-12-30- 00.00.00.000000000000 |
31.01.2010- 22.31.33. 495925000000 |
| C567 | 20000 | 31.01.2010- 22.31.33. 495925000000 |
9999-12-30- 00.00.00.000000000000 |
31.01.2010- 22.31.33. 495925000000 |
- Die Deckung (coverage) für die Police C567 soll 25000 betragen.
UPDATE policy_info SET coverage = 25000 WHERE policy_id = 'C567';Die Aktualisierung der Police C567 hat Auswirkungen auf die temporale Tabelle für Systemzeitraum sowie die zugehörige Protokolltabelle und führt dazu, dass die folgenden Aktionen ausgeführt werden:- Der Deckungswert für die Zeile mit der Police C567 wird auf 25000 aktualisiert.
- In der temporalen Tabelle für Systemzeitraum aktualisiert der Datenbankmanager
die Werte von
sys_startundts_idauf das Datum der Aktualisierung. - Die ursprüngliche Zeile wird in die Protokolltabelle versetzt. Der Datenbankmanager
aktualisiert den Wert für
sys_endauf das Datum der Aktualisierung. Diese Zeile kann als gültige Deckung für die Police C567 von 2010-01-31-22.31.33.495925000000 bis 2011-02-28-09.10.12.649592000000 interpretiert werden.
Tabelle 2. Aktualisierte Daten in der temporalen Tabelle für Systemzeitraum (policy_info) policy_id coverage sys_start sys_end ts_id A123 12000 31.01.2010-
22.31.33.
4959250000009999-12-30-
00.00.00.00000000000031.01.2010-
22.31.33.
495925000000B345 18000 31.01.2010-
22.31.33.
4959250000009999-12-30-
00.00.00.00000000000031.01.2010-
22.31.33.
495925000000C567 25000 28.02.2011-
09.10.12.
6495920000009999-12-30-
00.00.00.00000000000028.02.2011-
09.10.12.
649592000000Tabelle 3. Protokolltabelle (hist_policy_info) nach Aktualisierung policy_id coverage sys_start sys_end ts_id C567 20000 31.01.2010-
22.31.33.
49592500000028.02.2011-
09.10.12.
64959200000031.01.2010-
22.31.33.
495925000000
Weitere Beispiele
Der folgende Abschnitt enthält weitere Beispiele zur Aktualisierung von temporalen Tabellen für Systemzeitraum.- Zeitangaben
- Im folgenden Beispiel wird im Rahmen der Tabellenaktualisierung ein Zeitraum
angegeben. Die folgende Aktualisierung wird nach der im Abschnitt Vorgehensweise
beschriebenen Aktualisierung ausgeführt.
Diese Aktualisierung gibt einen Fehler zurück, da implizit versucht wird, Protokollzeilen zu aktualisieren. Die Anweisung SELECT fragt explizit die TabelleUPDATE (SELECT * FROM policy_info FOR SYSTEM_TIME AS OF '2010-01-31-22.31.33.495925000000') SET coverage = coverage + 1000;policy_infound implizit die zugehörige Protokolltabelle ab (hist_policy_info). Die Zeile C567 inhist_policy_infowürde von SELECT zurückgegeben, aber Zeilen in einer Protokolltabelle, auf die implizit zugegriffen wurde, können nicht aktualisiert werden. - Mehrere Änderungen an einer Zeile durch unterschiedliche Transaktionen
- Im folgenden Beispiel führen zwei Transaktionen gleichzeitig SQL-Anweisungen für die
Tabelle
policy_infoaus. In diesem Beispiel werden die Zeitmarken der Einfachheit halber durch einen Platzhalter und nicht durch einen Systemuhrwert angegeben. Beispielsweise wird anstelle von 2010-01-31-22.31.33.495925000000 der Platzhalter T1 verwendet. Platzhalter mit einer höheren Nummerierung weisen auf nachfolgende Aktionen innerhalb der Transaktion hin. T5 ist zum Beispiel ein späterer Zeitpunkt als T4.Beim Einfügen oder Aktualisieren mehrerer Zeilen innerhalb einer einzelnen SQL-Transaktion sind die Werte für die Zeilenbeginnspalten für alle betroffenen Zeilen identisch. Dieser Wert stammt aus dem Ablesen der Systemuhr zu dem Zeitpunkt, an dem die erste Datenänderungsanweisung in der Transaktion ausgeführt wird. Zum Beispiel verfügen alle der Transaktion ABC zugeordneten Zeiten über den Zeitwert T1.
Nach den Einfügungen in T1 und T2würde die TabelleTransaktion ABC Transaktion XYZ T1: INSERT INTO policy_info (policy_id, coverage) VALUES ('S777',7000);T2: INSERT INTO policy_info (policy_id, coverage) VALUES ('T888',8000);T3: COMMIT;T4: UPDATE policy_info SET policy_id = 'X999' WHERE policy_id = 'T888';T5: INSERT INTO policy_info (policy_id, coverage) VALUES ('Y555',9000);T6: COMMIT;policy_infowie folgt aussehen und die Protokolltabelle wäre leer (hist_policy_info). Der Wert max in der Spaltesys_endwird mit dem maximalen Standardwert für den Datentyp TIMESTAMP (12) gefüllt.Nach der Aktualisierung durch die Transaktion ABC zum Zeitpunkt T4 entsprechen die Policeninformationen den Daten in den folgenden Tabellen. Alle Zeilen in der TabelleTabelle 4. Einfügungen unterschiedlicher Transaktionen in die Tabelle 'policy_info' policy_id coverage sys_start sys_end ts_id S777 7000 T1 Max. T1 T888 8000 T2 Max. T2 policy_infogeben die Einfügungs- und Aktualisierungsaktivitäten von Transaktion ABC wieder. Die Spaltensys_startundts_idfür diese Zeilen werden mit dem Zeitwert von T1 gefüllt, der den Zeitpunkt der ersten Datenänderungsanweisung in der Transaktion ABC angibt. Die von der Transaktion XYZ eingefügten Policeninformationen wurden aktualisiert und die ursprüngliche Zeile wird in die Protokolltabelle versetzt.Tabelle 5. Unterschiedliche Transaktionen nach Aktualisierung der Tabelle 'policy_info' policy_id coverage sys_start sys_end ts_id S777 7000 T1 Max. T1 X999 8000 T1 Max. T1 Die Protokolltabelle enthält einen Wert fürTabelle 6: Protokolltabelle nach Aktualisierung durch unterschiedliche Transaktionen policy_id coverage sys_start sys_end ts_id T888 8000 T2 T1 T2 sys_end, der vor dem Wert vonsys_startliegt. In dieser Situation könnte die Aktualisierung zum Zeitpunkt T4 nicht ausgeführt werden und die Transaktion ABC würde fehlschlagen (SQLSTATE 57062, SQLCODE SQL20528N). Zum Vermeiden solcher Fehler kann der Datenbankkonfigurationsparameter systime_period_adj auf den Wert YES gesetzt werden, wodurch es dem Datenbankmanager möglich ist, die Zeitmarke der Beginnspalte für Zeile anzupassen (SQLSTATE 01695, SQLCODE SQL5191W). Die Zeitmarkesys_startfür die Aktualisierung zum Zeitpunkt T4 in Transaktion ABC wird auf den Zeitpunkt T2 zuzüglich eines Deltas (T2+delta) gesetzt. Die Anpassung bezieht sich nur auf die Aktualisierung zum Zeitpunkt T4; alle anderen von der Transaktion ABC durchgeführten Änderungen verwenden weiterhin die Zeitmarke für den Zeitpunkt T1 (z. B. die Einfügung der Police mitpolicy_idY555). Nach dieser Anpassung und der Ausführung der Transaktion ABC enthalten die Tabellen für Versicherungspolicen die folgenden Daten:Tabelle 7: Unterschiedliche Transaktionen nach Zeitanpassung (policy_info) policy_id coverage sys_start sys_end ts_id S777 7000 T1 Max. T1 X999 8000 T2+delta Max. T1 Y555 9000 T1 Max. T1 Tabelle 8. Protokolltabelle nach Zeitanpassung (hist_policy_info) policy_id coverage sys_start sys_end ts_id T888 8000 T2 T2+delta T2 - Mehrere Änderungen an einer Zeile innerhalb einer Transaktion
- Im folgenden Beispiel nimmt eine Transaktion mehrere Änderungen an einer Zeile
vor: Unter Verwendung der Tabellen für Versicherungspolicen aus dem vorherigen Beispiel fährt die Transaktion ABS fort und aktualisiert die Police mit
policy_idX999 zum Zeitpunkt T6 (T6 war ursprünglich eine Anweisung COMMIT).
Diese Zeile wurde nun wie folgt geändert:Transaktion ABC T6: UPDATE policy_info SET policy_id = 'R111' WHERE policy_id = 'X999';T7: COMMIT;- Erstellt als Richtlinie T888 von Transaktion XYZ zum Zeitpunkt T2.
- Aktualisiert als Richtlinie X999 von Transaktion ABC zum Zeitpunkt T4.
- Aktualisiert als Richtlinie R111 von Transaktion ABC zum Zeitpunkt T6.
Tabelle 9. Dieselbe Transaktion nach Aktualisierung (policy_info) policy_id coverage sys_start sys_end ts_id S777 7000 T1 Max. T1 R111 8000 T1 Max. T1 Y555 9000 T1 Max. T1 Der Datenbankmanager verwendet die Transaktionsstart-ID (Tabelle 10: Protokolltabelle nach Aktualisierung durch dieselbe Transaktion (hist_policy_info) policy_id coverage sys_start sys_end ts_id T888 8000 T2 T2+delta T2 ts_id), um die für die Zeilenänderung verantwortliche Transaktion eindeutig zu identifizieren. Beim Einfügen oder Aktualisieren mehrerer Zeilen innerhalb einer einzelnen SQL-Transaktion sind die Werte der Spalte für die Transaktionsstart-ID für alle Zeilen identisch und unterscheiden sich von den Werten, die von anderen Transaktionen für diese Spalte generiert wurden. Vor der Generierung einer Protokollzeile stellt der Datenbankmanager fest, dass sich die letzte Aktualisierung der Zeile auf die Transaktion bezieht, die zum Zeitpunkt T1 (ts_idist T1) gestartet wurde; da dieser Wert der Transaktionsstartzeit für die Transaktion entspricht, die die aktuelle Änderung durchführt, wird keine Protokollzeile generiert. Dersys_start-Wert für die Zeile in der Tabellepolicy_infowird in den Zeitpunkt T1 geändert. - Aktualisieren einer Sicht
- Eine Sicht, die auf eine temporale Tabelle für Systemzeitraum oder eine bitemporale Tabelle verweist, kann nur aktualisiert werden, wenn die Sichtdefinition nicht die Klausel FOR SYSTEM_TIME enthält. Die folgende Anweisung UPDATE aktualisiert die Tabelle
policy_infound generiert Protokollzeilen.
Eine Sicht, die auf eine temporale Tabelle für Systemzeitraum oder eine bitemporale Tabelle mit einer Sichtdefinition verweist, die die Klausel FOR SYSTEM_TIME enthält, kann durch Definieren eines Triggers INSTEAD OF aktualisierbar gemacht werden. Das folgende Beispiel aktualisiert die TabelleCREATE VIEW viewA AS SELECT * FROM policy_info; UPDATE viewA SET col2 = col2 + 1000;regular_table.CREATE VIEW viewB AS SELECT * FROM policy_info; FOR SYSTEM_TIME BETWEEN TIMESTAMP '2010-01-01 10:00:00' AND TIMESTAMP '2011-01-01 10:00:00'; CREATE TRIGGER update INSTEAD OF UPDATE ON viewB REFERENCING NEW AS n FOR EACH ROW UPDATE regular_table SET col1 = n.id; UPDATE viewB set id = 500;