Sql-Server
更改臨時表的行為以記錄實際值更改而不是虛擬更新
目前,我閱讀的有關臨時表的文章將清理的責任推給了應用程式碼。是否可以將臨時表配置為記錄特定列值的更改,而不是在表上呼叫更新語句時?
預期行為的範例:
USE Master; GO -- Create test database CREATE DATABASE [TemporalTables]; GO USE TemporalTables; GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- Hidden period columns CREATE TABLE [dbo].[PersonHistory]( [PersonID] [int] NOT NULL, [EmailAddress] [varchar](75) NULL, [IsSubscribed] [bit] NULL, [SysStartTime] datetime2 NOT NULL, [SysEndTime] datetime2 NOT NULL ); CREATE CLUSTERED COLUMNSTORE INDEX IX_PersonHistory ON PersonHistory; CREATE NONCLUSTERED INDEX IX_PersonHistory_ID_PERIOD_COLUMNS ON PersonHistory (SysEndTime, SysStartTime, PersonID); GO CREATE TABLE [dbo].[Person]( [PersonID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED, [EmailAddress] [varchar](75) NULL, [IsSubscribed] [bit] NULL, [SysStartTime] datetime2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL, [SysEndTime] datetime2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL, PERIOD FOR SYSTEM_TIME (SysStartTime,SysEndTime) ) WITH ( SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.PersonHistory) ); -- Current Time UTC SELECT sysutcdatetime(); -- Value: 2017-03-14 16:11:56.6294004 --Insert Rows INSERT [dbo].[Person] ([EmailAddress], [IsSubscribed]) VALUES ('SD.Burman@gmail.com', 1); GO INSERT [dbo].[Person] VALUES ('RD.Burman@gmail.com', 1); GO INSERT [dbo].[Person] ([EmailAddress], [IsSubscribed], [SysStartTime], [SysEndTime]) VALUES ('AR.Rehman@gmail.com', 1, default, default); GO -- Query the main table SELECT *, SysStartTime, SysEndTime FROM dbo.Person -- Shows all changes for specific PK (for inserts to show up) SELECT *, SysStartTime, SysEndTime FROM dbo.Person FOR SYSTEM_TIME ALL where Personid IN (1,2,3); -- Current Time UTC SELECT sysutcdatetime(); -- Value: 2017-03-14 16:13:27.0374068 --Update Rows (Actual Updates) UPDATE [dbo].[Person] SET [EmailAddress] = 'SD.Burman@hotmail.com' WHERE [EmailAddress] = 'SD.Burman@gmail.com'; GO UPDATE [dbo].[Person] SET [EmailAddress] = 'RD.Burman@hotmail.com' WHERE [EmailAddress] = 'RD.Burman@gmail.com'; GO --Update Rows (Dummy Update) UPDATE [dbo].[Person] SET [EmailAddress] = 'AR.Rehman@gmail.com' WHERE [EmailAddress] = 'AR.Rehman@gmail.com'; GO -- Query the history table SELECT * FROM dbo.PersonHistory -- !!! -- What I'd want is that the Id = 3 update to not get saved since the data did not change. -- Also a way I can limit the number of columns I want this behavior on. -- PersonID EmailAddress IsSubscribed SysStartTime SysEndTime -- ----------- --------------------------------------------------------------------------- ------------ --------------------------- --------------------------- -- 1 SD.Burman@gmail.com 1 2017-03-14 16:12:29.5018193 2017-03-14 16:13:27.0374068 -- 2 RD.Burman@gmail.com 1 2017-03-14 16:12:29.5118172 2017-03-14 16:13:27.1484051 -- !!!
強調此行為的類似問題:
我正在尋找上述行為的解決方法。
更改數據擷取將能夠處理這個(甚至是自定義觸發器),但我正在探索是否可以獲得具有選擇性歷史記錄的臨時表的好處。
挑戰在於,我們有一個
syncdatatime
經常接觸列的 ETL 作業,我們希望排除或包含某些列,並且只記錄實際數據值發生變化時,最好使用時態表。
在進一步的潛水中,這似乎目前屬於:管理系統版本化臨時表中歷史數據的保留作為該問題的反動解決方案,而不是先前的配置。
他們提出了三種方法:
- 拉伸數據庫
- 表分區
- 自定義清理腳本
我發現了其他一些不錯的文章,它們部分回答了我的問題,但是,如果我可以在數據創建而不是清理時管理這種行為,我會很高興,所以我會請求更多資訊以防有人擁有它,或者如果這在未來發生變化。
其他文章: