Aracılığıyla paylaş


Sistem sürümüne sahip bir zamana bağlı tablodaki verileri değiştirme

Şunlar için geçerlidir: SQL Server 2016 (13.x) ve sonraki sürümler Azure SQL DatabaseAzure SQL Managed InstanceSQL database in Microsoft Fabric

Sistem sürümüne sahip bir zamana bağlı tablodaki veriler normal veri işleme dili (DML) deyimleri kullanılarak değiştirilir ve önemli bir fark vardır: dönem sütunu verileri doğrudan değiştirilemez. Veriler güncelleştirildiğinde sürüm oluşturulur ve güncelleştirilen her satırın önceki sürümü geçmiş tablosuna eklenir. Veriler silindiğinde silme mantıksaldır ve satır geçerli tablodan geçmiş tablosuna taşınır; veriler kalıcı olarak silinmez.

Veri ekleme

Yeni veri eklediğinizde, PERIODdeğilse HIDDEN sütunlarını hesaba eklemeniz gerekir. Zamansal tablolarla bölüm değiştirme özelliğini de kullanabilirsiniz.

Görünür dönem sütunlarıyla yeni veri girme

INSERT sütunlarını hesaba katmak için, görünür PERIOD sütunlarınız olduğunda aşağıdaki gibi PERIOD deyiminizi oluşturabilirsiniz:

INSERT deyiminizde sütun listesini belirtirseniz, sistem bu sütunlar için değerleri otomatik olarak oluşturduğundan PERIOD sütunlarını atlayabilirsiniz.

-- Insert with column list and without period columns
INSERT INTO [dbo].[Department] (
      [DeptID],
      [DeptName],
      [ManagerID],
      [ParentDeptID]
)
VALUES (10, 'Marketing', 101, 1);

PERIOD deyiminizde sütun listesindeki INSERT sütunlarını belirtirseniz, değerleri olarak DEFAULT belirtmeniz gerekir.

INSERT INTO [dbo].[Department] (
   DeptID,
   DeptName,
   ManagerID,
   ParentDeptID,
   ValidFrom,
   ValidTo
)
VALUES (11, 'Sales', 101, 1, DEFAULT, DEFAULT);

INSERT deyiminizde sütun listesini belirtmezseniz, DEFAULT sütunlar için PERIOD belirtin.

-- Insert without a column list and DEFAULT values for period columns
INSERT INTO [dbo].[Department]
VALUES(12, 'Production', 101, 1, DEFAULT, DEFAULT);

Gizli dönem sütunları içeren bir tabloya veri ekleme

PERIOD sütunlar HIDDENolarak belirtilirse, PERIOD ifadenizde INSERT sütunlarını hesaba katmanıza gerek yoktur. Bu davranış, sürüm oluşturmadan yararlanan tablolarda sistem sürümü oluşturmayı etkinleştirdiğinizde eski uygulamalarınızın çalışmaya devam etmesi garanti eder.

CREATE TABLE [dbo].[CompanyLocation] (
    [LocID] [int] IDENTITY(1, 1) NOT NULL PRIMARY KEY,
    [LocName] [varchar](50) NOT NULL,
    [City] [varchar](50) NOT NULL,
    [ValidFrom] [datetime2] GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
    [ValidTo] [datetime2] GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
    PERIOD FOR SYSTEM_TIME([ValidFrom], [ValidTo])
)
WITH (SYSTEM_VERSIONING = ON);
GO

INSERT INTO [dbo].[CompanyLocation]
VALUES ('Headquarters', 'New York');

PARTITION SWITCH kullanarak veri ekleme

Geçerli tablo bölümlenmişse, verileri boş bir bölüme yüklemek veya paralel olarak birden çok bölüme yüklemek için verimli bir mekanizma olarak PARTITION SWITCH kullanabilirsiniz.

PARTITION SWITCH IN deyiminde zamansal tabloyla birlikte kullanılan hazırlama tablosunun SYSTEM_TIME PERIOD tanımlanmış olması gerekir, ancak zamansal tablo olması gerekmez. Bu, hazırlama tablosuna veri ekleme sırasında veya önceden doldurulmuş bir hazırlama tablosuna SYSTEM_TIME süre eklendiğinde zamansal tutarlılık denetimlerinin gerçekleştirilmesini sağlar.

/* Create staging table with period definition for SWITCH IN temporal table */
CREATE TABLE [dbo].[Staging_Department_Partition2] (
    [DeptID] [int] NOT NULL,
    [DeptName] [varchar](50) NOT NULL,
    [ManagerID] [int] NULL,
    [ParentDeptID] [int] NULL,
    [ValidFrom] [datetime2] GENERATED ALWAYS AS ROW START NOT NULL,
    [ValidTo] [datetime2] GENERATED ALWAYS AS ROW END NOT NULL,
    PERIOD FOR SYSTEM_TIME([ValidFrom], [ValidTo])
) ON [PRIMARY]

/* Create aligned primary key */
ALTER TABLE [dbo].[Staging_Department_Partition2]
ADD CONSTRAINT [Staging_Department_Partition2_PK]
PRIMARY KEY CLUSTERED ([DeptID] ASC) ON [PRIMARY];

/*
Create and enforce constraints for partition boundaries.
Partition 2 contains rows with DeptID > 100 and DeptID <=200
*/
ALTER TABLE [dbo].[Staging_Department_Partition2]
WITH CHECK ADD CONSTRAINT [chk_staging_Department_partition_2] CHECK (
   [DeptID] > N'100'
   AND [DeptID] <= N'200'
);

ALTER TABLE [dbo].[Staging_Department_Partition2]
CHECK CONSTRAINT [chk_staging_Department_partition_2];

/*Load data into staging table*/
INSERT INTO [dbo].[staging_Department] (
    [DeptID],
    [DeptName],
    [ManagerID],
    [ParentDeptID]
    )
VALUES (101, 'D101', 1, NULL);

/*Use PARTITION SWITCH IN to efficiently add data to current table */
ALTER TABLE [Staging_Department]
SWITCH TO [dbo].[Department] PARTITION 2;

Bir tablodan dönem tanımı olmadan PARTITION SWITCH gerçekleştirmeye çalışırsanız bir hata iletisi alırsınız.

Msg 13577, Level 16, State 1, Line 25 ALTER TABLE SWITCH statement failed on table 'MyDB.dbo.Staging_Department_2015_09_26' because target table has SYSTEM_TIME PERIOD while source table does not have it.

Verileri güncelleştirme

Geçerli tablodaki verileri normal bir UPDATE deyimiyle güncelleştirirsiniz. Felaket senaryosu için geçmiş tablodan mevcut tablodaki verileri güncelleyebilirsiniz. Ancak, PERIOD sütunlarını güncelleştiremez ve SYSTEM_VERSIONING = ONgeçmiş tablosundaki verileri doğrudan güncelleştiremezsiniz.

SYSTEM_VERSIONINGOFF olarak ayarlayıp geçerli ve geçmiş tablolarındaki satırları güncellerseniz, sistem değişikliklerin geçmişini korumaz.

Geçerli tabloyu güncelleştirme

Bu örnekte, ManagerIDDeptIDolduğu her satır için 10 sütunu güncelleştirilir. PERIOD sütunlarına hiçbir şekilde başvurulmuyor.

UPDATE [dbo].[Department]
SET [ManagerID] = 501
WHERE [DeptID] = 10;

Ancak, PERIOD sütununu güncelleştiremez ve geçmiş tablosunu güncelleştiremezsiniz. Bu örnekte, bir PERIOD sütununu güncelleştirme girişimi bir hata oluşturur.

UPDATE [dbo].[Department]
SET ValidFrom = '2015-09-23 23:48:31.2990175'
WHERE DeptID = 10;

ifade aşağıdaki hatayı oluşturur.

Msg 13537, Level 16, State 1, Line 3
Cannot update GENERATED ALWAYS columns in table 'TmpDev.dbo.Department'.

Geçerli tabloyu, geçmiş tablosundan güncelleştir

Geçerli tablodaki UPDATE kullanarak gerçek satır durumunu geçmişte belirli bir noktada geçerli bir duruma döndürebilirsiniz. Bunu, son iyi bilinen satır sürümünegeri dönmek olarak düşünün. Aşağıdaki örnek, 25 Nisan 2015 itibarıyla, DeptID'ün 10 olduğu duruma göre geçmiş tablosundaki değerlere geri dönüldüğünü göstermektedir.

UPDATE Department
SET DeptName = History.DeptName
FROM Department
FOR SYSTEM_TIME AS OF '2015-04-25' AS History
WHERE History.DeptID = 10
    AND Department.DeptID = 10;

Verileri sil

Geçerli tablodaki verileri normal bir DELETE deyimiyle silersiniz. Silinen satırların bitiş dönemi sütunu, temel alınan işlemin başlangıç saatiyle doldurulur. SYSTEM_VERSIONING ONiken geçmiş tablosundaki satırları doğrudan silemezsiniz. SYSTEM_VERSIONING = OFF ayarlar ve geçerli ve geçmiş tablolarındaki satırları silerseniz, sistem değişikliklerin geçmişini korumaz.

SYSTEM_VERSIONING = ONsırasında aşağıdaki ifadeler desteklenmiyor:

  • TRUNCATE
  • Geçerli tablo için SWITCH PARTITION OUT
  • Geçmiş tablosu için SWITCH PARTITION IN

Zamansal tablodaki verileri değiştirmek için MERGE kullanma

MERGE işlemi, INSERT sütunlarıyla ilgili olarak, UPDATE ve PERIOD deyimlerinin sahip olduğu aynı sınırlamalarla desteklenir.

CREATE TABLE DepartmentStaging (
    DeptId INT,
    DeptName VARCHAR(50)
);
GO

INSERT INTO DepartmentStaging
VALUES (1, 'Company Management');

INSERT INTO DepartmentStaging
VALUES (10, 'Science & Research');

INSERT INTO DepartmentStaging
VALUES (15, 'Process Management');

MERGE dbo.Department AS target
USING (
    SELECT DeptId, DeptName
    FROM DepartmentStaging
    ) AS source(DeptId, DeptName)
    ON (target.DeptId = source.DeptId)
WHEN MATCHED
    THEN UPDATE SET DeptName = source.DeptName
WHEN NOT MATCHED
    THEN
        INSERT (DeptId, DeptName)
        VALUES (source.DeptId, source.DeptName);