Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Относится к: SQL Server 2016 (13.x) и более поздние версии
База данных SQL Azure
Управляемый экземпляр SQL Azure
SQL Database в Microsoft Fabric
Данные в системной темпоральной таблице изменяются с помощью регулярных инструкций языка обработки данных (DML) с одной важной разницей: данные столбцов периода нельзя изменять напрямую. Когда данные обновляются, они становятся версионными, и предыдущая версия каждой обновлённой строки вставляется в таблицу истории. Когда данные удаляются, удаление происходит логично, и строка переносится в таблицу истории из текущей таблицы; Данные не удаляются навсегда.
Вставка данных
При вставке новых данных необходимо учесть PERIOD столбцы, если они не HIDDEN. Можно также использовать переключение разделов с темпоральными таблицами.
Добавление новых данных с видимыми столбцами периодов
Постройте свою INSERT выписку с учётом видимых PERIOD столбцов следующим образом:
Если в инструкции INSERT указан список столбцов, можно опустить PERIOD столбцы, так как система автоматически создает значения для этих столбцов.
-- Insert with column list and without period columns
INSERT INTO [dbo].[Department]
(
[DeptID],
[DeptName],
[ManagerID],
[ParentDeptID]
)
VALUES (10, 'Marketing', 101, 1);
Если вы указываете столбцы в списке столбцов в инструкцииPERIOD, необходимо указать INSERTDEFAULT их значение.
INSERT INTO [dbo].[Department]
(
DeptID,
DeptName,
ManagerID,
ParentDeptID,
ValidFrom,
ValidTo
)
VALUES (11, 'Sales', 101, 1, DEFAULT, DEFAULT);
Если список столбцов в инструкции INSERT не указан, укажите DEFAULT для PERIOD столбцов.
-- Insert without a column list and DEFAULT values for period columns
INSERT INTO [dbo].[Department]
VALUES (
12,
'Production',
101,
1,
DEFAULT,
DEFAULT
);
Добавление данных в таблицу со скрытыми столбцами периодов
Если PERIOD столбцы указаны как HIDDEN, вам не нужно учитывать PERIOD столбцы в инструкции INSERT . Это поведение гарантирует, что устаревшие приложения продолжают работать при включении системного управления версиями в таблицах, которые получают преимущества от управления версиями.
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
Если текущая таблица разделена на разделы, вы можете эффективно PARTITION SWITCH загружать данные в пустой раздел или одновременно загружать их в несколько разделов.
Промежуточная таблица, используемая в инструкции PARTITION SWITCH IN при работе с временной таблицей, должна иметь определение SYSTEM_TIME PERIOD, но сама она не обязана быть временной таблицей. Это гарантирует, что проверки временной согласованности выполняются во время вставки данных в промежуточную таблицу или при SYSTEM_TIME добавлении периода в предварительно заполненную промежуточную таблицу.
/* 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;
Если вы пытаетесь выполнить PARTITION SWITCH из таблицы без определения периода, вы получите сообщение об ошибке:
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.
Обновление данных
Данные в текущей таблице обновляются с помощью регулярной UPDATE инструкции. Вы можете обновить данные в текущей таблице из таблицы истории для сценария катастрофы. Однако нельзя обновлять PERIOD столбцы, и вы не можете напрямую обновлять данные в таблице истории, пока SYSTEM_VERSIONING = ON.
Если вы задаёте SYSTEM_VERSIONING для OFF и обновляете строки из текущих и исторических таблиц, то система не сохраняет историю изменений.
Обновление текущей таблицы
В этом примере столбец ManagerID обновляется для каждой строки, в которой DeptID равно 10. На столбцы PERIOD никак не ссылаются.
UPDATE [dbo].[Department]
SET [ManagerID] = 501
WHERE [DeptID] = 10;
Однако вы не можете обновить столбец PERIOD, и вы не можете обновить таблицу журнала. В этом примере попытка обновить PERIOD столбец создает ошибку.
UPDATE [dbo].[Department]
SET ValidFrom = '2015-09-23 23:48:31.2990175'
WHERE DeptID = 10;
Утверждение вызывает следующую ошибку.
Msg 13537, Level 16, State 1, Line 3
Cannot update GENERATED ALWAYS columns in table 'TmpDev.dbo.Department'.
Обновите текущую таблицу из таблицы истории.
Вы можете использовать UPDATE на текущей таблице для возврата текущего состояния строки в допустимое состояние в определенный момент времени в прошлом. Подумайте об этом как о возврате к последней хорошо известной версии строки. В следующем примере показан возврат к значениям в таблице истории по состоянию на 25 апреля 2015 года, где DeptID это 10.
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;
Удаление данных
Вы удаляете данные в текущей таблице с помощью обычной DELETE инструкции. Столбец конечного периода для удаленных строк заполняется временем начала базовой транзакции. Вы не можете напрямую удалять строки из таблицы истории, пока SYSTEM_VERSIONING является ON. Если вы устанавливаете SYSTEM_VERSIONING = OFF и удаляете строки из текущих и журналов таблиц, система не сохраняет журнал изменений.
Следующие утверждения не поддерживаются при SYSTEM_VERSIONING = ON:
TRUNCATE-
SWITCH PARTITION OUTдля текущей таблицы -
SWITCH PARTITION INдля таблицы истории
Использование MERGE для изменения данных в темпоральной таблице
Операция MERGE поддерживается с теми же ограничениями, что и операторы INSERT и UPDATE в отношении столбцов PERIOD.
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 INTO 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);