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
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.
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.
? 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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With