Fråga efter data i en systemversionsbaserad temporal tabell
gäller för: SQL Server 2016 (13.x) och senare versioner
Azure SQL Database
Azure SQL Managed Instance
SQL-databas i Microsoft Fabric
När du vill hämta det senaste (aktuella) datatillståndet i en temporal tabell kan du fråga på samma sätt som du kör frågor mot en icke-temporal tabell. Om de PERIOD
kolumnerna inte är dolda visas deras värden i en SELECT *
fråga. Om du har angett PERIOD
kolumner som HIDDEN
visas inte deras värden i en SELECT *
fråga. När de PERIOD
kolumnerna är dolda måste du referera till de PERIOD
kolumnerna specifikt i SELECT
-satsen för att returnera värdena för dessa kolumner.
Om du vill utföra alla typer av tidsbaserad analys använder du den nya FOR SYSTEM_TIME
-satsen med fyra tidsspecifika underklisklar för att fråga efter data i de aktuella tabellerna och historiktabellerna. Mer information om dessa klausuler finns i Temporal-tabeller och FROM-klausul plus JOIN, APPLY, PIVOT
AS OF <date_time>
FROM <start_date_time> TO <end_date_time>
BETWEEN <start_date_time> AND <end_date_time>
CONTAINED IN (<start_date_time>, <end_date_time>)
ALL
FOR SYSTEM_TIME
kan anges separat för varje tabell i en fråga. Den kan användas i vanliga tabelluttryck, tabellvärdesfunktioner och lagrade procedurer. När du använder ett tabellalias med en temporal tabell måste FOR SYSTEM_TIME
-satsen inkluderas mellan det temporala tabellnamnet och aliaset (se Fråga för en specifik tidpunkt med AS OF
-underklausulen andra exemplet).
Fråga efter en viss tid med hjälp av underklausulen AS OF
Använd AS OF
-underpunkten när du behöver rekonstruera datatillståndet som det var vid en viss tidpunkt i det förflutna. Du kan rekonstruera data med precisionen av datetime2-typen som angavs i PERIOD
-kolumndefinitionerna.
AS OF
-underklausulen kan användas med konstanter eller variabler, så att du kan ange tidsvillkoret dynamiskt. De angivna värdena tolkas som UTC-tid.
Det här första exemplet returnerar tillståndet för dbo.Department-tabellen AS OF
på ett specifikt datum i det förflutna.
-- State of entire table AS OF specific date in the past
SELECT [DeptID],
[DeptName],
[ValidFrom],
[ValidTo]
FROM [dbo].[Department]
FOR SYSTEM_TIME AS OF '2021-09-01 T10:00:00.7230011';
I det här andra exemplet jämförs värdena mellan två tidpunkter för en delmängd rader.
DECLARE @ADayAgo DATETIME2;
SET @ADayAgo = DATEADD(DAY, -1, SYSUTCDATETIME());
-- Comparison between two points in time for subset of rows
SELECT D_1_Ago.[DeptID],
D.[DeptID],
D_1_Ago.[DeptName],
D.[DeptName],
D_1_Ago.[ValidFrom],
D.[ValidFrom],
D_1_Ago.[ValidTo],
D.[ValidTo]
FROM [dbo].[Department]
FOR SYSTEM_TIME AS OF @ADayAgo AS D_1_Ago
INNER JOIN [Department] AS D
ON D_1_Ago.[DeptID] = [D].[DeptID]
AND D_1_Ago.[DeptID] BETWEEN 1 AND 5;
Använd vyer med AS OF
underklausul i tidsfrågor
Att använda vyer är användbart i scenarier när komplex analys av tidpunkt krävs. Ett vanligt exempel är att generera en affärsrapport idag med värdena för föregående månad.
Vanligtvis har kunderna en normaliserad databasmodell, som omfattar många tabeller med sekundärnyckelrelationer. Det kan vara svårt att ta reda på hur data från den normaliserade modellen tittade på en tidigare tidpunkt, eftersom alla tabeller ändras oberoende av varandra i sin egen takt.
I det här fallet är det bästa alternativet att skapa en vy och tillämpa delklausulen AS OF
på hela vyn. Med den här metoden kan du frikoppla modellering av dataåtkomstskiktet från punkt-i-tid-analys, eftersom SQL Server tillämpar AS OF
-satsen transparent för alla temporala tabeller som deltar i vydefinitionen. Dessutom kan du kombinera temporala tabeller med icke-temporala tabeller i samma vy och AS OF
tillämpas endast på temporala tabeller. Om vyn inte refererar till minst en temporal tabell misslyckas tillämpningen av temporala frågesatser på den med ett fel.
Följande exempelkod skapar en vy som kopplar samman tre temporala tabeller: Department
, CompanyLocation
och LocationDepartments
:
CREATE VIEW [dbo].[vw_GetOrgChart]
AS
SELECT [CompanyLocation].LocID,
[CompanyLocation].LocName,
[CompanyLocation].City,
[Department].DeptID,
[Department].DeptName
FROM [dbo].[CompanyLocation]
LEFT JOIN [dbo].[LocationDepartments]
ON [CompanyLocation].LocID = LocationDepartments.LocID
LEFT JOIN [dbo].[Department]
ON LocationDepartments.DeptID = [Department].DeptID;
GO
Du kan fråga vyn med hjälp av AS OF
-underklienten och en datetime2 literal:
/* Querying view AS OF */
SELECT * FROM [vw_GetOrgChart]
FOR SYSTEM_TIME AS OF '2021-09-01 T10:00:00.7230011';
Fråga efter ändringar i specifika rader över tid
De temporala underclausesna FROM ... TO
, BETWEEN ... AND
och CONTAINED IN
är användbara när du behöver hämta alla historiska ändringar för en specifik rad i den aktuella tabellen (kallas även för en datagranskning).
De första två underclauses returnerar radversioner som överlappar en angiven period (det vill säga de som startade före den angivna perioden och avslutades efter den), medan CONTAINED IN
endast returnerar de som fanns inom angivna periodgränser.
Om du bara söker efter icke-aktuella radversioner bör du fråga historiktabellen direkt för bästa frågeprestanda. Använd ALL
när du behöver köra frågor mot aktuella och historiska data utan några begränsningar.
/* Query using BETWEEN...AND sub-clause*/
SELECT [DeptID],
[DeptName],
[ValidFrom],
[ValidTo],
IIF(YEAR(ValidTo) = 9999, 1, 0) AS IsActual
FROM [dbo].[Department]
FOR SYSTEM_TIME BETWEEN '2021-01-01' AND '2021-12-31'
WHERE DeptId = 1
ORDER BY ValidFrom DESC;
/* Query using CONTAINED IN sub-clause */
SELECT [DeptID],
[DeptName],
[ValidFrom],
[ValidTo]
FROM [dbo].[Department]
FOR SYSTEM_TIME CONTAINED IN ('2021-04-01', '2021-09-25')
WHERE DeptId = 1
ORDER BY ValidFrom DESC;
/* Query using ALL sub-clause */
SELECT [DeptID],
[DeptName],
[ValidFrom],
[ValidTo],
IIF(YEAR(ValidTo) = 9999, 1, 0) AS IsActual
FROM [dbo].[Department]
FOR SYSTEM_TIME ALL
ORDER BY [DeptID],
[ValidFrom] DESC;