ADD PERIOD FOR SYSTEM_TIME für Tabelle fehlgeschlagen


7

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?



Ja, überprüfen Sie auch die Kommentare. Ich habe eine solche Problemumgehung auch in diesem Forum gefunden, aber es hat nichts geändert. Ich muss verstehen, wie man die Zeiteinstellungen ändert, um diese Arbeit zu bekommen. Außerdem habe ich das Problem, auch wenn die Tabelle leer ist.
Gotqn

Antworten:


4

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 datetime2mit Präzision verwendet. Also ging ich zurück zur Quelle dieses Formats datetime2(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 muss datetime(0)( 2018-03-15 07:21:02zum Beispiel) und im Beispiel ist es SYSUTCDATETIME(). 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):

Geben Sie hier die Bildbeschreibung ein

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:

DECLARE @UTC DATETIME2(0) = GETUTCDATE();
DECLARE @SYSUTC DATETIME2(0) = SYSUTCDATETIME();

WHILE DATEPART(SECOND, @UTC) = DATEPART(SECOND, @SYSUTC)
BEGIN;
    SET @UTC  = GETUTCDATE();
    SET @SYSUTC  = SYSUTCDATETIME();
END;

SELECT @UTC AS [UTC]
      ,@SYSUTC AS [SYS UTC]
      ,DATEPART(SECOND, @UTC) AS [UTC sec]
      ,DATEPART(SECOND, @SYSUTC) AS [SYS UTC sec]
      ,CASE WHEN @UTC < @SYSUTC THEN 1 ELSE 0 END AS [TimeTravelPossible]
      ,CONVERT(DATETIME2(0), @UTC) AS [UTC date]
      ,CONVERT(DATETIME2(0), @SYSUTC) AS [SYS UTC date]
      ,IIF(CONVERT(DATETIME2(0), @UTC) = CONVERT(DATETIME2(0), @SYSUTC), 1, 0) AS [Are The Same];

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.

Geben Sie hier die Bildbeschreibung ein

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.

ALTER TABLE [dbo].[AnalysisCustomRollupsV2JoinGroups]
ADD [SysStartTime] DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN CONSTRAINT DF_AnalysisCustomRollupsV2JoinGroups_SysStart DEFAULT SYSUTCDATETIME()  
   ,[SysEndTime] DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN CONSTRAINT DF_AnalysisCustomRollupsV2JoinGroups_SysEnd DEFAULT CONVERT(DATETIME2, '9999-12-31 23:59:59.9999999'),   
PERIOD FOR SYSTEM_TIME ([SysStartTime], [SysEndTime]); 

ALTER TABLE [dbo].[AnalysisCustomRollupsV2JoinGroups]   
SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.AnalysisCustomRollupsV2JoinGroupsChanges));

1
Ich hatte eine seltsame Begegnung damit und bekam auch den gleichen Fehler wie Sie. Ich habe versucht, das Problem zu umgehen, indem ich jede Komponente der Änderung einzeln ausgeführt habe, aber die Sache "PERIOD FOR SYSTEM_TIME" ist sehr speziell. Ich habe es irgendwie zum Laufen gebracht, nachdem ich meine Start- / Endspalten hinzugefügt, dann gelöscht und dann bei einem letzten Versuch die gesamte Anweisung erneut ausgeführt habe - das hat funktioniert. Seien Sie sich nur bewusst, dass dies ein bekannter MS-Fehler ist
Legasthenikeraboko

@gotqn Danke für die Lösung
FindOutIslamNow

-1

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 `

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.