我最近在SQL Server中发现了临时表。我想开始使用此功能。但是,最大的障碍是无法从中删除记录。由于符合GDPR,这是绝对必须的。
从历史记录表中删除记录显然会导致错误:
无法从时间历史记录表中删除行
为了能够从历史表中删除记录,我必须禁用SYSTEM_VERSIONING
,然后删除,然后重新启用SYSTEM_VERSIONING
。除非有我不知道的另一种方式?
由于无法在存储过程/ SqlCommand
中使用GO,因此如何确保删除历史记录不会与其他事务混淆,例如在从历史记录表中删除记录的过程中发送到临时表的更新仍然会导致将记录添加到历史记录表中吗?
我尝试创建一个存储过程以将其包装在一个事务中,但这失败了,因为未执行禁用ALTER TABLE
的{{1}}语句,但会导致相同的错误。
SYSTEM_VERSIONING
答案 0 :(得分:1)
如果使WHERE
动态,则存储过程将成功UPDATE People
SET Username = CONCAT('domainname\',LEFT([E-mailAddress],CHARINDEX('@',[E-mailAddress])-1))
WHERE
Username <> CONCAT('domainname\',LEFT([E-mailAddress],CHARINDEX('@',[E-mailAddress])-1));
表,DELETE
有问题的记录,然后ALTER
将其返回。
DELETE
答案 1 :(得分:0)
我从来没有遇到过这样的问题,但是我的存储过程有点不同-我要删除记录的CSV,然后STRING_SPLIT
并在临时表中实现它们。然后,将该表连接到目标历史记录表。
这里是完整的工作示例(仅一个输入值)。首先创建表并添加一些示例数据:
DROP TABLE IF EXISTS [dbo].[StackOverflow];
GO
CREATE TABLE [dbo].[StackOverflow]
(
[Col1] INT PRIMARY KEY
,[Col2] VARCHAR(32)
,[SysStartTime] DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL
,[SysEndTime] DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL
,PERIOD FOR SYSTEM_TIME ([SysStartTime],[SysEndTime])
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.StackOverflowChanges));
GO
INSERT INTO [dbo].[StackOverflow] ([Col1], [Col2])
VALUES (1, 'value 1')
,(2, 'value 2')
,(3, 'value 3');
GO
UPDATE [dbo].[StackOverflow]
SET [Col2] = [Col2] + ' v2'
GO
SELECT *
FROM [dbo].[StackOverflow];
SELECT *
FROM [dbo].[StackOverflowChanges];
GO
然后,创建存储过程:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE OR ALTER PROCEDURE [dbo].[usp_StackOverflow_Delete]
(
@Col1 INT
)
AS
BEGIN;
SET NOCOUNT, XACT_ABORT ON;
DROP TABLE IF EXISTS #RecordsTobeDeleted;
CREATE TABLE #RecordsTobeDeleted
(
[Col1] INT
);
INSERT INTO #RecordsTobeDeleted ([Col1])
VALUES (@Col1);
BEGIN TRY
BEGIN TRANSACTION;
ALTER TABLE [dbo].[StackOverflow] SET ( SYSTEM_VERSIONING = OFF )
DELETE [dbo].[StackOverflowChanges]
FROM [dbo].[StackOverflowChanges] SOC
INNER JOIN #RecordsTobeDeleted R
ON SOC.[Col1] = R.[Col1];
ALTER TABLE [dbo].[StackOverflow] SET ( SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[StackOverflowChanges]))
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
BEGIN;
ROLLBACK TRANSACTION;
END;
THROW;
END CATCH
SET NOCOUNT, XACT_ABORT ON;
END;
GO
现在从历史记录表中删除一条记录:
EXEC [dbo].[usp_StackOverflow_Delete] @Col1 = 1;
SELECT *
FROM [dbo].[StackOverflow];
SELECT *
FROM [dbo].[StackOverflowChanges];
清理:
ALTER TABLE [dbo].[StackOverflow] SET ( SYSTEM_VERSIONING = OFF )
DROP TABLE IF EXISTS [dbo].[StackOverflow];
DROP TABLE IF EXISTS [dbo].[StackOverflowChanges];