Modifica dei dati in una tabella temporale con controllo delle versioni di sistemaModifying Data in a System-Versioned Temporal Table

QUESTO ARGOMENTO SI APPLICA A: sìSQL Server (a partire dalla versione 2016)sìDatabase SQL di AzurenoAzure SQL Data Warehouse noParallel Data Warehouse THIS TOPIC APPLIES TO: yesSQL Server (starting with 2016)yesAzure SQL DatabasenoAzure SQL Data Warehouse noParallel Data Warehouse

È possibile modificare i dati in una tabella temporale con controllo delle versioni di sistema usando istruzioni DML regolari, tenendo però presente che i dati della colonna periodo non possono essere modificati direttamente.Data in a system-versioned temporal table is modified using regular DML statements with one important difference: period column data cannot be directly modified. Quando i dati vengono aggiornati, sono sottoposti al controllo delle versioni e la versione precedente di ogni riga aggiornata viene inserita nella tabella di cronologia.When data is updated, it is versioned, with the previous version of each updated row is inserted into the history table. Quando vengono eliminati, l'eliminazione è logica e la riga viene spostata dalla tabella corrente alla tabella di cronologia senza che i dati siano eliminati definitivamente.When data is deleted, the delete is logical, with the row moved into the history table from the current table - it is not permanently deleted.

Inserimento di datiInserting data

Quando si inseriscono nuovi dati è necessario tenere conto delle colonne PERIOD se non sono HIDDEN.When you insert new data, you need to account for the PERIOD columns if they are not HIDDEN. Nelle tabelle temporali con controllo delle versioni di sistema è anche possibile usare il cambio della partizione.You can also use partition switching with system-versioned temporal tables.

Inserire nuovi dati con colonne periodo visibiliInsert new data with visible period columns

È possibile costruire l’istruzione INSERT quando si hanno colonne PERIOD visibili come le seguenti, per tenere conto delle nuove colonne PERIOD :You can construct your INSERT statement when you have visible PERIOD columns as follows to account for the new PERIOD columns:

  • Se si specifica l'elenco delle colonne nell’istruzione INSERT , è possibile omettere le colonne PERIOD , perché il sistema genera automaticamente i relativi valori.If you specify the column list in your INSERT statement, you can omit the PERIOD columns because system will generate values for these columns automatically.

    --Insert with column list and without period columns   
    INSERT INTO [dbo].[Department] ([DeptID] ,[DeptName] ,[ManagerID] ,[ParentDeptID])   
    VALUES(10, 'Marketing', 101, 1);  
    
  • Se si specificano le colonnePERIOD nell'elenco colonne nell’istruzione INSERT , è necessario specificare anche DEFAULT come relativo valore.If you do specify thePERIOD columns in the column list in your INSERT statement, then you need to specify DEFAULT as their value.

    INSERT INTO [dbo].[Department] ([DeptID] ,[DeptName] ,[ManagerID] ,[ParentDeptID], SysStartTime, SysEndTime)   
    VALUES(11, 'Sales', 101, 1, default, default);  
    
  • Se non si specifica l'elenco colonne nell’istruzione INSERT , specificare DEFAULT per le colonne PERIOD .If you do not specify the column list in your INSERT statement, specify DEFAULT for PERIOD columns.

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

Inserire dati in una tabella con colonne periodo HIDDENInsert data into a table with HIDDEN period columns

Se le colonne PERIOD vengono specificate come HIDDEN, quando si utilizza l’istruzione INSERT è necessario indicare solo i valori per le colonne visibili, senza specificare l'elenco colonne.If PERIOD columns are specified as HIDDEN, then you need only to specify the values for the visible columns when you use INSERT without specifying the column list. Non è necessario tenere conto delle nuove colonne PERIOD nell’istruzione INSERT .You do not need to account for the new PERIOD columns in your INSERT statement. In questo modo le applicazioni legacy continueranno a funzionare quando si abilita il controllo delle versioni di sistema nelle tabelle a cui verrà applicata la funzionalità.This behavior guarantees that your legacy applications will continue to work when you enable system-versioning on tables that will benefit from versioning.

CREATE TABLE [dbo].[CompanyLocation]  
(   
     [LocID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY  
   , [LocName] [varchar](50) NOT NULL  
   , [City] [varchar](50) NOT NULL  
   , [SysStartTime] [datetime2](0) GENERATED ALWAYS AS ROW START HIDDEN NOT NULL   
   , [SysEndTime] [datetime2](0) GENERATED ALWAYS AS ROW END HIDDEN NOT NULL   
PERIOD FOR SYSTEM_TIME ([SysStartTime], [SysEndTime])   
)    
WITH ( SYSTEM_VERSIONING = ON );   
GO   
INSERT INTO [dbo].[CompanyLocation]   
VALUES  ('Headquarters', 'New York');  

Inserimento di dati con PARTITION SWITCHInserting data using PARTITION SWITCH

Se la tabella corrente è partizionata è possibile usare il cambio di partizione per caricare in modo efficiente i dati in una partizione vuota oppure su più partizioni in parallelo.If the current table is partitioned, you can use partition switch as an efficient mechanism to load data into an empty partition or to load into multiple partitions in parallel.
La tabella di gestione temporanea usata nell'istruzione PARTITION SWITCH IN con una tabella temporale con controllo delle versioni di sistema deve avere la definizione di SYSTEM_TIME PERIOD , ma non deve essere necessariamente una tabella temporale con controllo delle versioni di sistema.The staging table that is used in the PARTITION SWITCH IN statement with a system-versioned temporal table must have SYSTEM_TIME PERIOD defined, but it does not need to be a system-versioned temporal table.
Ciò assicura l’esecuzione di controlli di coerenza temporale durante l'inserimento di dati in una tabella di gestione temporanea o quando il periodo SYSTEM_TIME viene aggiunto a una tabella di gestione temporanea già popolata.This ensures that temporal consistency checks are performed during the data insert into a staging table or when SYSTEM_TIME period is added to a pre-populated staging table.

/*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  
   , [SysStartTime] [datetime2](7) GENERATED ALWAYS AS ROW START NOT NULL  
   , [SysEndTime] [datetime2](7) GENERATED ALWAYS AS ROW END NOT NULL  
   , PERIOD FOR SYSTEM_TIME ( [SysStartTime], [SysEndTime] )   
) 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;  

Se si tenta di eseguire l’istruzione PARTITION SWITCH da una tabella priva di definizione del periodo verrà visualizzato il messaggio di errore: 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.If you try to perform PARTITION SWITCH from a table without period definition you’ll get error message: 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.

Aggiornamento datiUpdating data

I dati nella tabella corrente vengono aggiornati con una normale istruzione UPDATE .You update data in the current table with a regular UPDATE statement. È possibile aggiornare i dati nella tabella corrente dalla tabella di cronologia per lo scenario "oops".You can update data in the current table from the history table to for the "oops" scenario. Non è tuttavia possibile aggiornare le colonne PERIOD né aggiornare direttamente i dati nella tabella di cronologia se SYSTEM_VERSIONING = ON.However, you cannot update PERIOD columns and you cannot directly updated data in the history table while SYSTEM_VERSIONING = ON.
Impostare SYSTEM_VERSIONING = OFF e aggiornare le righe dalla tabella corrente e di cronologia, tenendo presente che in questo modo il sistema non conserverà la cronologia delle modifiche.Set SYSTEM_VERSIONING = OFF and update rows from current and history table but keep in mind that way system will not preserve history of changes.

Aggiornamento della tabella correnteUpdating the current table

In questo esempio, la colonna ManagerID viene aggiornata per ogni riga in cui DeptID = 10.In this example, the ManagerID column is updated for each row where the DeptID = 10. Non c’è alcun riferimento alle colonne PERIOD .The PERIOD columns are not referenced in any way.

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

Tuttavia, non è possibile aggiornare una colonna PERIOD né la tabella di cronologia.However, you cannot update a PERIOD column and you cannot update the history table. In questo esempio, il tentativo di aggiornare una colonna PERIOD genera un errore.In this example, an attempt to update a PERIOD column generates an error.

UPDATE [dbo].[Department]    
SET SysStartTime = '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'.  

Aggiornamento della tabella corrente dalla tabella di cronologiaUpdating the current table from the history table

È possibile usare l'istruzione UPDATE nella tabella corrente per ripristinare lo stato corrente della riga a uno specifico stato valido precedente (ripristino all'ultima versione di riga valida nota).You can use UPDATE on the current table to revert the actual row state to valid state at a specific point in time in the past (reverting to a “last good known row version”). Nell'esempio seguente i valori nella tabella di cronologia vengono ripristinati al 25-04-2015, quando DeptID = 10.The following example shows reverting to the values in the history table as of 2015-04-25 where the 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 ;  

Eliminazione di datiDeleting data

È possibile eliminare dati dalla tabella corrente con una normale istruzione DELETE .You delete data in the current table with a regular DELETE statement. La colonna periodo finale delle righe eliminate verrà popolata con l'ora di inizio della transazione sottostante.The end period column for deleted rows will be populated with the begin time of underlying transaction.
Non è possibile eliminare direttamente le righe dalla tabella di cronologia se SYSTEM_VERSIONING = ON.You cannot directly delete rows from history table while SYSTEM_VERSIONING = ON.
Impostare SYSTEM_VERSIONING = OFF ed eliminare le righe dalla tabella corrente e di cronologia, tenendo presente che in questo modo il sistema non conserverà la cronologia delle modifiche.Set SYSTEM_VERSIONING = OFF and delete rows from current and history table but keep in mind that way system will not preserve history of changes.
Le istruzioniTRUNCATE, SWITCH PARTITION OUT della tabella corrente e l'istruzione SWITCH PARTITION IN della tabella di cronologia non sono supportate se SYSTEM_VERSIONING = ON.TRUNCATE, SWITCH PARTITION OUT of current table and SWITCH PARTITION IN history table are not supported while SYSTEM_VERSIONING = ON.

Utilizzo di MERGE per modificare i dati in una tabella temporaleUsing MERGE to modify data in temporal table

L’operazioneMERGE è supportata con le stesse limitazioni delle istruzioni INSERT e UPDATE relativamente alle colonne PERIOD .MERGE operation is supported with the same limitations that INSERT and UPDATE statements have regarding PERIOD columns.

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 (DeptName)   
   VALUES (source.DeptName);  

Questo articolo è stato utile?Did this Article Help You? Commenti e suggerimentiWe’re Listening

Quali informazioni si stanno cercando? La ricerca ha restituito i risultati desiderati?What information are you looking for, and did you find it? Microsoft incoraggia gli utenti a inviare i propri commenti per migliorare i contenutiWe’re listening to your feedback to improve the content. Inviare eventuali commenti all'indirizzo sqlfeedback@microsoft.comPlease submit your comments to sqlfeedback@microsoft.com

Vedere ancheSee Also

Tabelle temporali Temporal Tables
Creazione di una tabella temporale con controllo delle versioni di sistema Creating a System-Versioned Temporal Table
Query sui dati in una tabella temporale con controllo delle versioni di sistema Querying Data in a System-Versioned Temporal Table
Modifica dello schema di una tabella temporale con controllo delle versioni di sistema Changing the Schema of a System-Versioned Temporal Table
Arresto del controllo delle versioni di sistema in una tabella temporale con controllo delle versioni di sistema Stopping System-Versioning on a System-Versioned Temporal Table