Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
Относится к: SQL Server 2016 (13.x) и более поздние версии
Azure SQL Database
Azure SQL Managed Instance
SQL Database в Microsoft Fabric
Данные в системной темпоральной таблице изменяются с помощью регулярных инструкций языка обработки данных (DML) с одной важной разницей: данные столбцов периода нельзя изменять напрямую. При обновлении данных им присваивается версия, и предыдущая версия каждой обновленной строки вставляется в таблицу истории. При удалении данных удаление носит логический характер, и строка перемещается из активной таблицы в таблицу истории; данные не удаляются безвозвратно.
Вставка данных
При вставке новых данных необходимо учесть PERIOD столбцы, если они не HIDDEN. Можно также использовать переключение разделов с темпоральными таблицами.
Добавление новых данных с видимыми столбцами периодов
Вы можете создать INSERT инструкцию, если у вас есть видимые PERIOD столбцы, следующим образом, чтобы учесть 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 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);