简体   繁体   中英

Sql Server Temporal table history

Is there a way to identify deleted rows in history from the table?

So when I perform an updated or a delete it moves data to the history, I want to know which rows in history were deleted

help

You can use the output clause. For example:

declare @ids table (id int);

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

select *
from @ids;

Use a semi-anti join between the temporal table and the history table based on the PK.

As an example...

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

And now the query retrieving deleted rows:

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

retrieving the last version of the deleted rows needs to add some extra SQL conditions

If you want to know which rows were deleted in history, just create an audit table and have a trigger in the real table.

For example, you have a table called "PeopleTbl".

1- You will create an audit table to store the history of "PeopleTbl". Let's create a table called "PeopleAuditTbl".

The structure of the "PeopleAuditTbl". Should have all the columns that you wish to keep track of and a time field and a TypeField(Delete, Inserted, or Updated).

2- Now in your "PeopleTbl". You will create a trigger that stores updated or delete (You can also store inserted records if you want.

The trigger for delete should be something like this.

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

If you are looking to use your Temporal History table to identify the records that have been deleted from the Main table, the following example demonstrates how this can be achieved:

-- 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)

Basically, we're looking at the union of the main and history tables ( select * from Invoice FOR SYSTEM_TIME ALL ) for any records where the latest version is no longer valid ( MAX(SysEndTime) < '9999-12-31' )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM