无法从时态历史表中删除行

bde*_*ere 8 t-sql sql-server

我最近在 SQL Server 中发现了临时表。我想开始使用这个功能。然而,最大的障碍是无法从中删除记录。由于符合 GDPR,这是绝对必须的。

从历史表中删除记录显然会导致错误:

无法从时态历史表中删除行

因此,为了能够从历史表中删除记录,我必须先禁用SYSTEM_VERSIONING,然后删除,然后重新启用SYSTEM_VERSIONING。除非有另一种我不知道的方式?

由于无法在存储过程/中使用 GO SqlCommand,我如何确保删除历史记录不会干扰其他事务,例如在从历史表中删除记录期间发送到临时表的更新仍将导致记录被添加到历史表?

我尝试创建一个存储过程将它包装在一个事务中,但这失败了,因为ALTER TABLE禁用 的语句SYSTEM_VERSIONING尚未执行,导致相同的错误。

CREATE PROCEDURE [dbo].[OrderHistoryDelete]
     (@Id UNIQUEIDENTIFIER)
AS
BEGIN
    BEGIN TRANSACTION

    ALTER TABLE [dbo].[Order] SET ( SYSTEM_VERSIONING = OFF )
    -- No GO possible here obviously.

    DELETE FROM [dbo].[OrderHistory] WITH (TABLOCKX) 
    WHERE [Id] = @Id

    ALTER TABLE [dbo].[Order] SET ( SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[OrderHistory]))

    COMMIT TRANSACTION
END
GO
Run Code Online (Sandbox Code Playgroud)

小智 10

如果您使DELETE动态,您的存储过程将成功ALTER的表,DELETE有问题的记录,然后ALTER它回来。

CREATE PROCEDURE [dbo].[OrderHistoryDelete]
     (@Id UNIQUEIDENTIFIER)
AS
BEGIN
    DECLARE @sql VARCHAR(MAX)

    BEGIN TRANSACTION

        ALTER TABLE [dbo].[Order] SET ( SYSTEM_VERSIONING = OFF )

        SET @sql = 'DELETE FROM [dbo].[OrderHistory] WITH (TABLOCKX) 
        WHERE [Id] = ''' + CAST(@Id AS VARCHAR(40)) + ''''
        EXEC (@sql)

        ALTER TABLE [dbo].[Order] SET ( SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[OrderHistory]))

    COMMIT TRANSACTION
END
Run Code Online (Sandbox Code Playgroud)

  • 对于动态 SQL,您应该使用“sp_executesql”而不是“EXEC”。 (5认同)