Sql Server 临时表历史记录

问题描述

有没有办法从表中识别历史记录中已删除的行?

因此,当我执行更新或删除操作时,会将数据移动到历史记录中,我想知道历史记录中的哪些行被删除

帮助

解决方法

您可以使用 output 子句。例如:

declare @ids table (id int);

delete from t
    output deleted.id into @ids
    where . . .;

select *
from @ids;
,

基于PK在时态表和历史表之间使用半反连接。

,

举个例子...

CREATE SCHEMA _CHRONO;
GO

CREATE TABLE dbo.TEMPO
(
ID          INT IDENTITY PRIMARY KEY,SOME_DATA   VARCHAR(32),_DH_DEB     DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,_DH_FIN     DATETIME2 GENERATED ALWAYS AS ROW END   HIDDEN NOT NULL,PERIOD FOR SYSTEM_TIME (_DH_DEB,_DH_FIN)
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = _CHRONO.TEMPO));
GO

INSERT INTO dbo.TEMPO VALUES ('a data'),('another data')
GO

DELETE FROM dbo.TEMPO WHERE SOME_DATA LIKE '%other%'
GO

现在查询检索已删除的行:

SELECT CT.*
FROM   _CHRONO.TEMPO AS CT
       LEFT OUTER JOIN dbo.TEMPO AS T
          ON CT.ID = T.ID

获取删除行的最后一个版本需要添加一些额外的SQL条件

,

如果你想知道历史记录中删除了哪些行,只需创建一个审计表并在真实表中设置一个触发器即可。

例如,您有一个名为“PeopleTbl”的表。

1- 您将创建一个审计表来存储“PeopleTbl”的历史记录。让我们创建一个名为“PeopleAuditTbl”的表。

“PeopleAuditTbl”的结构。应该包含您希望跟踪的所有列、时间字段和类型字段(删除、插入或更新)。

2- 现在在您的“PeopleTbl”中。您将创建一个触发器来存储更新或删除(如果需要,您也可以存储插入的记录。

删除触发器应该是这样的。

ALTER TRIGGER T_PeopleTbl
    ON PeopleTbl
    AFTER DELETE
AS
INSERT INTO PeopleAuditTbl(
        //Fields you want to store
        Date,TypeField
    )
    SELECT
        //Fields you want to store
        GETDate(),'DELETE'
    FROM DELETED

,

如果您希望使用 Temporal History 表来识别已从 Main 表中删除的记录,以下示例演示了如何实现:

-- Create a Temporal Table for demonstration purposes
CREATE TABLE dbo.Invoice
(
  InvoiceId int identity(1,1) PRIMARY KEY CLUSTERED,InvoiceDate date NOT NULL
  -- Other fields...,SysStartTime datetime2 GENERATED ALWAYS AS ROW START,SysEndTime datetime2 GENERATED ALWAYS AS ROW END,PERIOD FOR SYSTEM_TIME (SysStartTime,SysEndTime)
 )
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.InvoiceHistory));
go

-- Create some dummy data
insert into Invoice(InvoiceDate) values ('2020-01-01'),('2020-02-01')
go
WAITFOR DELAY '00:00:03'
go
delete from Invoice where InvoiceId=1
go

-- Get Current Records
select * from Invoice

-- Get Deleted Records
;with cte as
(
    select InvoiceId,MAX(SysEndTime) [SysEndTime]
    from Invoice FOR SYSTEM_TIME ALL
    group by InvoiceId
    having MAX(SysEndTime) < '9999-12-31'
)
select i.*
from Invoice FOR SYSTEM_TIME ALL i
inner join cte c on (i.InvoiceId=c.InvoiceId and i.SysEndTime=c.SysEndTime)

基本上,我们正在查看主表和历史表的联合(select * from Invoice FOR SYSTEM_TIME ALL)以获取最新版本不存在的任何记录更长的有效时间 (MAX(SysEndTime) )