更新时态表而不更新历史记录

时间:2018-06-17 13:11:02

标签: sql sql-server temporal-tables

我有一个带有PersonH​​istory的临时表Person。

Collumns:[Id],[Name],[DepartmentId],[ModifiedBy],[SysStartTime]和[SysEndTime]。

在物理上删除一行时,我想继续删除ModifiedBy中的行,而不向PersonH​​istory添加2行。

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

感谢。

1 个答案:

答案 0 :(得分:1)

它可以做但但有点hacky。此外,您将丢失将行更改为当前状态的人员的历史记录(EG:user1创建名称为' jams'。user2将名称更改为' james'。用户3已删除在历史记录中,您不会看到用户2从“jams' james”中进行编辑,只是用户3删除了该行名字' 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