【问题标题】:Update temporal table without updating history更新临时表而不更新历史
【发布时间】:2018-06-17 13:11:01
【问题描述】:

我有一个时间表PersonPersonHistory

列:

[Id], [Name], [DepartmentId], [ModifiedBy], [SysStartTime], [SysEndTime]

在物理删除一行时,我想坚持ModifiedBy中删除该行的人,而不是在PersonHistory中添加2行。

关于如何实现这一目标的任何想法?

谢谢。

【问题讨论】:

标签: sql sql-server temporal-tables


【解决方案1】:

它可以做到,但它会有点hacky。此外,您将丢失将行更改为当前状态的任何人的历史记录(例如:user1 创建名称为“jams”的记录。user2 将名称更改为“james”。用户 3 删除了该行。在历史记录中,您不会看到 user2 从 'jams' 到 'james' 的编辑,只是 user3 删除了名为 'james' 的行)所以你失去了一点审计线索

这可能在触发器中起作用,我不确定,但如果您将相关表的删除操作限制为 SPROC,那么可以这样完成:

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

【讨论】:

  • 你说得对,我会丢失一些审计线索。我想我会更新该行然后删除它。但无论如何,感谢您为我的问题提供可能的解决方案。
猜你喜欢
  • 2014-05-21
  • 2021-10-18
  • 2020-12-01
  • 1970-01-01
  • 2011-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多