Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot delete rows from a temporal history table

I've recently discovered temporal tables in SQL Server. I'd like to start using this functionality. However the biggest hurdle is not being able to delete records from it. Due to GDPR compliance this is an absolute must.

Deleting records from a history table obviously leads to the error:

Cannot delete rows from a temporal history table

So to be able to delete records from a history table I have to disable SYSTEM_VERSIONING, then delete, and then re-enable SYSTEM_VERSIONING. Unless there's another way I'm not aware of?

Since it's not possible to use GO's in a stored procedure/SqlCommand, how can I ensure deleting a history record does not mess with other transactions e.g. updates sent to the temporal table during deleting records from the history table will still result in records being added to the history table?

I've tried creating a stored procedure to wrap it in one transaction but this fails because the ALTER TABLE statement disabling the SYSTEM_VERSIONING is not executed yet leading to the same error.

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
like image 308
bdebaere Avatar asked Dec 12 '18 15:12

bdebaere


People also ask

How do I delete data from temporal history table?

To delete data from a system-period temporal table, use the DELETE FROM statement. For example, the owner of policy B345 decides to cancel insurance coverage. The data was deleted on September 1, 2011 (2011-09-01) from the table that was updated in the Updating data in a system-period temporal table topic.

How do I delete a versioned table in SQL?

To get the delete option, first, turn off the system_versioning setting using the alter table statement. After that, you'll notice that the tables, temporal table and history table become a regular table. You can also use the SSMS generate script option to drop the temporal table.

When System_time period is not defined?

? Cannot set SYSTEM_VERSIONING to ON when SYSTEM_TIME period is not defined. From the result it is clear that to enable system-versioning the table needs to have two period DATETIME2 columns with period definition in it. Period column 'StartTime' in a system-versioned temporal table cannot be nullable.


1 Answers

If you make the DELETE dynamic, your stored procedure will successfully ALTER the table, DELETE the records in question, and then ALTER it back.

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
like image 59
GreyOrGray Avatar answered Nov 14 '22 16:11

GreyOrGray