THÊM THỜI GIAN CHO HỆ THỐNG_TIME trên bàn không thành công


7

Tôi có:

  • bảng với dữ liệu hiện có
  • Máy chủ SQL 2016 SP1
  • Studio quản lý máy chủ SQL 17.5

Tôi đang sử dụng câu lệnh sau để biến bảng của mình thành một bảng tạm thời:

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));

Vấn đề:

Trong trường hợp SQL cục bộ của tôi, tôi có nhiều cơ sở dữ liệu; Thật kỳ lạ khi truy vấn chạy thành công trên một số trong số chúng và trên một số trong số chúng, nó gây ra lỗi sau:

Msg 13542, Cấp 16, Trạng thái 0, Dòng 51 THÊM THỜI GIAN CHO HỆ THỐNG_TIME trên bảng 'dbo.AnalysisCustomRollupsV2Joingroup' không thành công vì có các bản ghi mở với thời gian bắt đầu được đặt thành giá trị trong tương lai.

Đôi khi, khi tôi gỡ lỗi / thực hiện truy vấn, truy vấn ban đầu chạy thành công.

Tôi đọc, rằng điều này có thể là do tôi có dữ liệu hiện có trong bảng. Vì vậy, tôi đã thay đổi logic như thế này:

  • tạo bảng đệm và điền vào nó với tất cả các bản ghi
  • xóa các bản ghi từ bảng gốc
  • tạo bảng thời gian
  • di chuyển các bản ghi trở lại và thả bảng đệm

và một lần nữa, trên một số cơ sở dữ liệu thì không sao, và trên cơ sở dữ liệu khác thì không. Cố gắng giải quyết vấn đề tôi đã tìm thấy như sau:

Đối với StartDate tôi đã chỉ định ngày UTC hiện tại - đây có thể là bất kỳ ngày và giờ nào không có trong tương lai, mặc dù lưu ý rằng đó phải là ngày UTC. Nếu tôi đã thử sử dụng GETDATE, vì tôi hiện đang vào Giờ mùa hè của Anh, tôi sẽ gặp lỗi sau: Msg 13542, Cấp 16, Trạng thái 0, Dòng 51 THÊM THỜI GIAN CHO HỆ THỐNG_TIME trên bảng 'TestAudit.dbo.SomeData' không thành công vì có các bản ghi mở với thời gian bắt đầu được đặt thành một giá trị trong tương lai.

Những gì ở trên có nghĩa là gì? Tôi cần thay đổi thời gian máy? Hoặc do máy cục bộ của tôi không có thời gian UTC nên đôi khi tôi gặp lỗi này?



Vâng, kiểm tra các ý kiến, cũng. Tôi đã tìm thấy cách giải quyết như vậy trong diễn đàn này, nhưng nó không thay đổi gì. Tôi cần hiểu cách thay đổi cài đặt thời gian để có được công việc này. Ngoài ra, tôi đang gặp vấn đề ngay cả khi bảng trống.
gotqn

Câu trả lời:


4

Tôi nghĩ rằng tôi đã tìm ra cách khắc phục vấn đề của mình, nhưng tôi sẽ không chấp nhận đây là câu trả lời vì tôi không thể giải thích điều gì gây ra sự cố và đảm bảo điều này sẽ hoạt động bất cứ lúc nào. Đó là bản sửa lỗi được tìm thấy sau rất nhiều thử nghiệm và tôi sẽ rất vui nếu ai đó có thể mang lại nhiều ánh sáng hơn ở đây.


Tôi chưa bao giờ sử dụng datetime2với độ chính xác. Vì vậy, tôi đã quay trở lại nguồn của định dạng này datetime2(0)- Bảng thay đổi không tạm thời để trở thành Bảng tạm thời được phiên bản hệ thống . Sự khác biệt duy nhất với tập lệnh tôi đang sử dụng là hàm thời gian ngày. Tôi đã sử dụng GETUTCDATE()như tôi không cần phải được ưu tiên như vậy datetime(0)( 2018-03-15 07:21:02ví dụ) và trong ví dụ này là SYSUTCDATETIME() . Vì vậy, tôi đã thay đổi nó.

Tôi đã tạo một tập lệnh bỏ cơ sở dữ liệu nếu có, khôi phục cơ sở dữ liệu từ bản sao lưu và sau đó thực thi mã của tôi trong một vòng lặp (như tôi đã nói đôi khi tôi gặp lỗi và rất khó để tạo lại nó).

Tôi đã chạy một kịch bản rất nhiều lần và tôi đã nhận được số lần thất bại khác nhau (đôi khi 70%, đôi khi 50%, đôi khi bên dưới):

nhập mô tả hình ảnh ở đây

Tôi đã tìm thấy điều này Tại sao GETUTCDATE sớm hơn SYSDATETIMEOFFSET? thảo luận về sự khác biệt giữa các chức năng thời gian ngày cũ và mới. Sau đó xây dựng truy vấn sau:

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];

Tôi chỉ muốn kiểm tra xem tôi có thể nhận được các datetime2(0)ngày khác nhau bằng cách sử dụng sys chứ không phải chức năng thời gian ngày sys. Và tất nhiên là có thể.

nhập mô tả hình ảnh ở đây

Có thể, các kiểm tra mà động cơ đang thực hiện đang làm một cái gì đó như thế này, so sánh ngày hiện tại của nó với ngày mới hơn của tôi và điều này gây ra lỗi - open records with start of period set to a value in the future.

Tôi đã thay đổi tập lệnh như thế này và thực hiện 1.000 lần tối qua - không có lỗi nào được tạo. Vì vậy, tôi tin rằng tôi đã khắc phục vấn đề đặc biệt này, nhưng tôi không thể chắc chắn.

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
Tôi đã có một cuộc gặp gỡ kỳ lạ với điều này cũng nhận được lỗi tương tự như bạn. Tôi đã cố gắng hack xung quanh vấn đề bằng cách thực hiện từng thành phần của một thay đổi tại một thời điểm, nhưng điều "PERIOD FOR HỆ THỐNG_TIME" rất đặc biệt. Tôi bằng cách nào đó đã làm cho nó hoạt động sau khi thêm các cột bắt đầu / kết thúc của mình, sau đó thả chúng xuống, sau đó trên một nỗ lực cuối cùng để chạy lại toàn bộ câu lệnh - điều này đã hoạt động. Chỉ cần lưu ý rằng đây là một lỗi MS đã
dyslexicanaboko

@gotqn Cảm ơn giải pháp
FindOutIslamNow

-1

Điều này đã làm việc trên môi trường Sql Server và Azure SQL (PaaS).

`ALTER TABLE, [Phân tíchCustomRollupsV2Joingroup] THÊM SysStartTime datetime2 (0) TỪNG TỪNG TỪ BÂY GIỜ TỪ BÂY GIỜ TỪ BÂY GIỜ TỪ BÂY GIỜ, TỪNG ĐẾN TỪNG ĐẾN ĐƯỜNG CHUYỂN ĐỔI DEFAULT (datetime2 (0), '9999-12-31 23:59:59'), THỜI GIAN CHO HỆ THỐNG_TIME (SysStartTime, SysEndTime); ĐI

ALTER TABLE [dbo]. [Phân tíchCustomRollupsV2Joingroup] SET (HỆ THỐNG_VERSIONING = ON (HISTORY_TABLE = [dbo].

ĐI

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.