Ich habe:
- Tabelle mit vorhandenen Daten
- SQL Server 2016 SP1
- SQL Server Management Studio 17.5
Ich verwende die folgende Anweisung, um meine Tabelle zu einer zeitlichen zu machen:
ALTER TABLE [dbo].[AnalysisCustomRollupsV2JoinGroups]
ADD [SysStartTime] DATETIME2(0) GENERATED ALWAYS AS ROW START HIDDEN CONSTRAINT DF_AnalysisCustomRollupsV2JoinGroups_SysStart DEFAULT GETUTCDATE()
,[SysEndTime] DATETIME2(0) GENERATED ALWAYS AS ROW END HIDDEN CONSTRAINT DF_AnalysisCustomRollupsV2JoinGroups_SysEnd DEFAULT CONVERT(DATETIME2(0), '9999-12-31 23:59:59'),
PERIOD FOR SYSTEM_TIME ([SysStartTime], [SysEndTime]);
ALTER TABLE [dbo].[AnalysisCustomRollupsV2JoinGroups]
SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.AnalysisCustomRollupsV2JoinGroupsChanges));
Die Angelegenheit:
Auf meiner lokalen SQL-Instanz habe ich viele Datenbanken; Es ist sehr seltsam, dass die Abfrage bei einigen von ihnen erfolgreich ausgeführt wird, und bei einigen gibt es den folgenden Fehler:
Meldung 13542, Ebene 16, Status 0, Zeile 51 ADD PERIOD FOR SYSTEM_TIME in Tabelle 'dbo.AnalysisCustomRollupsV2JoinGroups' ist fehlgeschlagen, da offene Datensätze vorhanden sind, deren Periodenbeginn auf einen zukünftigen Wert festgelegt ist.
Wenn ich die Abfrage debugge / ausführe, wird die erste Abfrage manchmal erfolgreich ausgeführt.
Ich habe gelesen, dass dies daran liegen könnte, dass ich vorhandene Daten in der Tabelle habe. Also habe ich die Logik folgendermaßen geändert:
- Erstellen Sie eine Puffertabelle und füllen Sie sie mit allen Datensätzen
- Löschen Sie die Datensätze aus der Originaltabelle
- Erstellen Sie die Zeittabelle
- Verschieben Sie die Datensätze zurück und löschen Sie die Puffertabelle
und wieder ist es in einigen Datenbanken in Ordnung und in anderen nicht. Beim Versuch, das Problem zu beheben, habe ich Folgendes festgestellt :
Für das Startdatum habe ich das aktuelle UTC-Datum angegeben. Dies kann ein beliebiges Datum und eine beliebige Uhrzeit sein, die nicht in der Zukunft liegen. Beachten Sie jedoch, dass es sich um ein UTC-Datum handeln sollte. Wenn ich versucht hätte, GETDATE zu verwenden, da ich gerade in der britischen Sommerzeit bin, würde folgende Fehlermeldung angezeigt: Nachricht 13542, Ebene 16, Status 0, Zeile 51 ZEITRAUM FÜR SYSTEM_TIME HINZUFÜGEN in Tabelle 'TestAudit.dbo.SomeData' fehlgeschlagen, weil offene Datensätze vorhanden sind, deren Periodenbeginn auf einen zukünftigen Wert festgelegt ist.
Was bedeutet das oben Genannte? Ich muss die Maschinenzeit ändern? Oder weil mein lokaler Computer nicht auf UTC-Zeit ist, erhalte ich manchmal diesen Fehler?
Antworten:
Ich glaube, ich habe herausgefunden, wie ich mein Problem beheben kann, aber ich werde dies nicht als Antwort akzeptieren, da ich nicht erklären kann, was das Problem verursacht, und garantieren kann, dass dies jederzeit funktioniert. Es wurde nach vielen Tests behoben und ich werde froh sein, wenn jemand mehr Licht hierher bringen kann.
Ich habe nie
datetime2
mit Präzision verwendet. Also ging ich zurück zur Quelle dieses Formatsdatetime2(0)
- Ändern Sie die nicht-zeitliche Tabelle in eine systemversionierte zeitliche Tabelle . Der einzige Unterschied zu dem Skript, das ich verwendet habe, war die Datums- / Uhrzeitfunktion. Ich habe verwendet,GETUTCDATE()
weil ich nicht so genau sein mussdatetime(0)
(2018-03-15 07:21:02
zum Beispiel) und im Beispiel ist esSYSUTCDATETIME()
. Also habe ich es geändert.Ich habe ein Skript erstellt, das eine Datenbank löscht, falls vorhanden, eine Datenbank aus der Sicherung wiederherstellt und dann meinen Code in einer Schleife ausführt (wie gesagt, ich erhalte manchmal den Fehler und es war sehr schwierig, ihn zu reproduzieren).
Ich habe das Skript oft ausgeführt und es gab eine unterschiedliche Anzahl von Fehlern (manchmal 70%, manchmal 50%, manchmal unten):
Ich habe dies gefunden. Warum ist GETUTCDATE früher als SYSDATETIMEOFFSET? Diskussion über Unterschiede zwischen alten und neuen Datums- / Uhrzeitfunktionen. Erstellen Sie dann die folgende Abfrage:
Ich wollte nur überprüfen, ob ich
datetime2(0)
mit der Funktion sys und nicht mit der Funktion sys date time unterschiedliche Daten erhalten kann. Und natürlich ist es möglich.Vielleicht machen die Überprüfungen, die der Motor durchführt, so etwas, indem er das aktuelle Datum mit meinem neueren Datum vergleicht und dies den Fehler verursacht -
open records with start of period set to a value in the future.
Ich habe das Skript so geändert und letzte Nacht 1 000 Mal ausgeführt - es wurden keine Fehler generiert. Ich glaube, ich habe dieses spezielle Problem behoben, kann mich aber nicht sicher sein.
quelle
Dies funktionierte in SQL Server- und Azure SQL-Umgebungen (PaaS).
`ALTER TABLE [dbo]. [AnalysisCustomRollupsV2JoinGroups] ADD SysStartTime datetime2 (0) IMMER ERZEUGT, WENN DER REIHENSTART VERSTECKT IST DEFAULT CONVERT (datetime2 (0), '9999-12-31 23:59:59'), ZEITRAUM FÜR SYSTEM_TIME (SysStartTime, SysEndTime); GEHEN
ALTER TABLE [dbo]. [AnalysisCustomRollupsV2JoinGroups] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo]. [AnalysisCustomRollupsV2JoinGroups_History]));
GO `
quelle