Aracılığıyla paylaş


Sistem sürümüne sahip bir zamana bağlı tablodaki verileri sorgulama

Şunlar için geçerlidir: SQL Server 2016 (13.x) ve sonraki sürümleri Microsoft Fabric'te Azure SQL VeritabanıAzure SQL Yönetilen ÖrneğiSQL veritabanı

Bir zaman tablosundaki verilerin en son (geçerli) durumunu almak istediğinizde, zamansal olmayan bir tabloyu sorguladığınız gibi sorgulayabilirsiniz. PERIOD sütunları gizli değilse, değerleri bir SELECT * sorgusunda görünür. PERIOD sütunlarını HIDDENolarak belirttiyseniz, bu sütunların değerleri SELECT * sorguda görünmez. PERIOD sütunları gizlendiğinde, bu sütunların değerlerini döndürmek üzere, özellikle PERIOD maddesinde SELECT sütunlarına başvurmanız gerekir.

Herhangi bir zaman tabanlı analiz türü gerçekleştirmek için, geçerli ve geçmiş tablolarındaki verileri sorgulamak için zamana özgü dört alt uyarı içeren yeni FOR SYSTEM_TIME yan tümcesini kullanın. Bu tümceler hakkında daha fazla bilgi için bkz. Zamansal tablolar ve FROM tümcesi artı 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 sorgudaki her tablo için bağımsız olarak belirtilebilir. Ortak tablo ifadeleri, tablo değerli işlevler ve saklı prosedürler içinde kullanılabilir. Zamansal bir tabloyla tablo diğer adı kullanılırken, FOR SYSTEM_TIME yan tümcesi zamansal tablo adı ile diğer ad arasına eklenmelidir (bkz. AS OF alt tümcesini kullanarak belirli bir zaman için sorgu ikinci örneği).

AS OF alt uyarısını kullanarak belirli bir süre için sorgulama

Verilerin durumunu geçmişte belirli bir zamanda olduğu gibi yeniden oluşturmanız gerektiğinde AS OF alt modülünü kullanın. PERIOD sütun tanımlarında belirtilen datetime2 türünün kesinliğiyle verileri yeniden yapılandırabilirsiniz.

AS OF alt harfi sabit değişmez değerlerle veya değişkenlerle kullanılabilir, böylece zaman koşulunu dinamik olarak belirtebilirsiniz. Sağlanan değerler UTC saati olarak yorumlanır.

Bu ilk örnek, dbo.Department tablosunun geçmişteki belirli bir tarihteki durumunu AS OF döndürür.

-- 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';

Bu ikinci örnek, satırların bir alt kümesi için zaman içinde iki nokta arasındaki değerleri karşılaştırır.

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;

Zamansal sorgularda AS OF alt bendi olan görünümler kullanılır

Görünümlerin kullanılması, karmaşık zaman noktası analizinin gerekli olduğu senaryolarda yararlıdır. Yaygın bir örnek, önceki ayın değerleriyle bugün bir iş raporu oluşturmaktır.

Müşteriler genellikle yabancı anahtar ilişkilerine sahip birçok tablo içeren normalleştirilmiş bir veritabanı modeline sahiptir. Tüm tablolar kendi tempolarında bağımsız olarak değiştiğinden, bu normalleştirilmiş modeldeki verilerin geçmişteki bir noktaya nasıl baktığını öğrenmek zor olabilir.

Bu durumda, en iyi seçenek bir görünüm oluşturmak ve AS OF alt dosyasını görünümün tamamına uygulamaktır. SQL Server, görünüm tanımına katılan tüm zamana bağlı tablolara AS OF yan tümcesini saydam bir şekilde uyguladığından, bu yaklaşımı kullanmak, veri erişim katmanının modellemesini zamansal analizden bağımsız hale getirmenizi sağlar. Ayrıca, aynı görünümde zamansal olmayan tablolarla zamansal tabloları birleştirebilirsiniz ve AS OF yalnızca geçici tablolara uygulanır. Görünüm en az bir zamana bağlı tabloya başvurmuyorsa, görünüme zamansal sorgulama cümlecikleri uygulamak hata verir.

Aşağıdaki örnek kod, üç zamansal tabloyu birleştiren bir görünüm oluşturur: Department, CompanyLocationve 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

AS OF alt öğesini ve datetime2 sabitini kullanarak görünümü sorgulayabilirsiniz.

/* Querying view AS OF */
SELECT * FROM [vw_GetOrgChart]
FOR SYSTEM_TIME AS OF '2021-09-01 T10:00:00.7230011';

Zaman içinde belirli satırlarda yapılan değişiklikleri sorgulama

geçerli tablodaki belirli bir satıra (veri denetimi olarak da bilinir) ilişkin tüm geçmiş değişiklikleri almanız gerektiğinde, FROM ... TO, BETWEEN ... AND ve CONTAINED IN zamansal alt öğeleri yararlı olur.

İlk iki alt bent, belirtilen bir süreyle çakışan satır sürümlerini (yani, belirtilen dönemden önce başlayan ve sonra bitenleri) döndürürken, CONTAINED IN yalnızca belirtilen dönem sınırları içinde bulunanları döndürür.

Yalnızca geçerli olmayan satır sürümlerini arıyorsanız, en iyi sorgu performansı için geçmiş tablosunu doğrudan sorgulamanız gerekir. Geçerli ve geçmiş verileri herhangi bir kısıtlama olmadan sorgulamanız gerektiğinde ALL kullanın.

/* 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;