更新时间 table 而不更新历史
Update temporal table without updating history
我有时间 table Person
和 PersonHistory
。
列:
[Id], [Name], [DepartmentId], [ModifiedBy], [SysStartTime], [SysEndTime]
当物理删除一行时,我想保留谁在 ModifiedBy
中删除了该行,而不向 PersonHistory
添加 2 行。
关于如何实现此目标的任何想法?
谢谢。
可以做到,但会有点麻烦。此外,您将丢失将行更改为当前状态的任何人的历史记录(例如:用户 1 创建名称为 'jams' 的记录。用户 2 将名称更改为 'james'。用户 3 删除了该行。在历史记录中您不会看到用户 2 从 'jams' 到 'james' 的编辑,只是用户 3 删除了名称为 'james' 的行,所以您丢失了一些审计线索
这可能在触发器中有效,我不确定,但如果您将相关 table 的删除操作限制在存储过程中,则可以像这样完成:
CREATE PROC [People].[Person_Delete]
(
@Id INT,
@DeletedBy VARCHAR(255)
)
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION
--===========================================================================================
--TURN OFF SYSTEM VERSIONING FOR THE TARGET TABLE
--===========================================================================================
IF (SELECT temporal_type FROM sys.tables WHERE object_id = OBJECT_ID('People.Person', 'U')) = 2
BEGIN
EXEC(N'
PRINT(''Deactivating SYSTEM_VERSIONING for People.Person...'')
ALTER TABLE People.Person
SET (SYSTEM_VERSIONING = OFF)
ALTER TABLE People.Person
DROP PERIOD FOR SYSTEM_TIME
')
END
--===========================================================================================
--UPDATE THE ModifiedBy VALUE
--===========================================================================================
UPDATE People.Person
SET ModifiedBy = @DeletedBy
WHERE Id = @Id
--===========================================================================================
--TURN ON SYSTEM VERSIONING FOR THE TARGET TABLE
--===========================================================================================
IF (SELECT temporal_type FROM sys.tables WHERE object_id = OBJECT_ID('People.Person', 'U')) = 0
BEGIN
EXEC(N'
PRINT(''Activating SYSTEM_VERSIONING for People.Person...'')
ALTER TABLE People.Person
ADD PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime)
ALTER TABLE People.Person
SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE=People.PersonHistory, DATA_CONSISTENCY_CHECK=ON))
')
END
--===========================================================================================
--DELETE THE RECORD
--===========================================================================================
DELETE People.Person
WHERE Id = @Id
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION
;THROW;
END CATCH
END
我有时间 table Person
和 PersonHistory
。
列:
[Id], [Name], [DepartmentId], [ModifiedBy], [SysStartTime], [SysEndTime]
当物理删除一行时,我想保留谁在 ModifiedBy
中删除了该行,而不向 PersonHistory
添加 2 行。
关于如何实现此目标的任何想法?
谢谢。
可以做到,但会有点麻烦。此外,您将丢失将行更改为当前状态的任何人的历史记录(例如:用户 1 创建名称为 'jams' 的记录。用户 2 将名称更改为 'james'。用户 3 删除了该行。在历史记录中您不会看到用户 2 从 'jams' 到 'james' 的编辑,只是用户 3 删除了名称为 'james' 的行,所以您丢失了一些审计线索
这可能在触发器中有效,我不确定,但如果您将相关 table 的删除操作限制在存储过程中,则可以像这样完成:
CREATE PROC [People].[Person_Delete]
(
@Id INT,
@DeletedBy VARCHAR(255)
)
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION
--===========================================================================================
--TURN OFF SYSTEM VERSIONING FOR THE TARGET TABLE
--===========================================================================================
IF (SELECT temporal_type FROM sys.tables WHERE object_id = OBJECT_ID('People.Person', 'U')) = 2
BEGIN
EXEC(N'
PRINT(''Deactivating SYSTEM_VERSIONING for People.Person...'')
ALTER TABLE People.Person
SET (SYSTEM_VERSIONING = OFF)
ALTER TABLE People.Person
DROP PERIOD FOR SYSTEM_TIME
')
END
--===========================================================================================
--UPDATE THE ModifiedBy VALUE
--===========================================================================================
UPDATE People.Person
SET ModifiedBy = @DeletedBy
WHERE Id = @Id
--===========================================================================================
--TURN ON SYSTEM VERSIONING FOR THE TARGET TABLE
--===========================================================================================
IF (SELECT temporal_type FROM sys.tables WHERE object_id = OBJECT_ID('People.Person', 'U')) = 0
BEGIN
EXEC(N'
PRINT(''Activating SYSTEM_VERSIONING for People.Person...'')
ALTER TABLE People.Person
ADD PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime)
ALTER TABLE People.Person
SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE=People.PersonHistory, DATA_CONSISTENCY_CHECK=ON))
')
END
--===========================================================================================
--DELETE THE RECORD
--===========================================================================================
DELETE People.Person
WHERE Id = @Id
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION
;THROW;
END CATCH
END