MERGE (Transact-SQL)MERGE (Transact-SQL)

Si applica a:Applies to: sìSQL ServerSQL Server (tutte le versioni supportate) yesSQL ServerSQL Server (all supported versions) Sìdatabase SQL di AzureAzure SQL DatabaseYesdatabase SQL di AzureAzure SQL Database sìAzure Synapse AnalyticsAzure Synapse AnalyticsyesAzure Synapse AnalyticsAzure Synapse AnalyticsSi applica a:Applies to: sìSQL ServerSQL Server (tutte le versioni supportate) yesSQL ServerSQL Server (all supported versions) Sìdatabase SQL di AzureAzure SQL DatabaseYesdatabase SQL di AzureAzure SQL Database sìAzure Synapse AnalyticsAzure Synapse AnalyticsyesAzure Synapse AnalyticsAzure Synapse Analytics

Esegue operazioni di inserimento, aggiornamento o eliminazione in una tabella di destinazione dai risultati di un join con una tabella di origine.Runs insert, update, or delete operations on a target table from the results of a join with a source table. Sincronizzare, ad esempio, due tabelle inserendo, aggiornando o eliminando righe in una tabella in base alle differenze trovate nell'altra tabella.For example, synchronize two tables by inserting, updating, or deleting rows in one table based on differences found in the other table.

Nota

MERGE è attualmente in anteprima per Azure Synapse Analytics.MERGE is currently in preview for Azure Synapse Analytics.

Suggerimento per le prestazioni: il comportamento condizionale descritto per l'istruzione MERGE funziona meglio quando le due tabelle hanno una combinazione complessa di caratteristiche corrispondenti.Performance Tip: The conditional behavior described for the MERGE statement works best when the two tables have a complex mixture of matching characteristics. Ad esempio, inserire una riga se non esiste o aggiornare una riga se corrisponde.For example, inserting a row if it doesn't exist, or updating a row if it matches. Quando si aggiorna semplicemente una tabella in base alle righe di un'altra tabella, ottenere prestazioni e scalabilità migliori con le istruzioni INSERT, UPDATE e DELETE di base.When simply updating one table based on the rows of another table, improve the performance and scalability with basic INSERT, UPDATE, and DELETE statements. Ad esempio:For example:

INSERT tbl_A (col, col2)  
SELECT col, col2
FROM tbl_B
WHERE NOT EXISTS (SELECT col FROM tbl_A A2 WHERE A2.col = tbl_B.col);  

Icona di collegamento a un argomento Convenzioni della sintassi Transact-SQLTopic link icon Transact-SQL Syntax Conventions

SintassiSyntax


-- SQL Server and Azure SQL Database
[ WITH <common_table_expression> [,...n] ]  
MERGE
    [ TOP ( expression ) [ PERCENT ] ]
    [ INTO ] <target_table> [ WITH ( <merge_hint> ) ] [ [ AS ] table_alias ]  
    USING <table_source> [ [ AS ] table_alias ]
    ON <merge_search_condition>  
    [ WHEN MATCHED [ AND <clause_search_condition> ]  
        THEN <merge_matched> ] [ ...n ]  
    [ WHEN NOT MATCHED [ BY TARGET ] [ AND <clause_search_condition> ]  
        THEN <merge_not_matched> ]  
    [ WHEN NOT MATCHED BY SOURCE [ AND <clause_search_condition> ]  
        THEN <merge_matched> ] [ ...n ]  
    [ <output_clause> ]  
    [ OPTION ( <query_hint> [ ,...n ] ) ]
;  
  
<target_table> ::=  
{
    [ database_name . schema_name . | schema_name . ]  
  target_table  
}  
  
<merge_hint>::=  
{  
    { [ <table_hint_limited> [ ,...n ] ]  
    [ [ , ] INDEX ( index_val [ ,...n ] ) ] }  
}  

<merge_search_condition> ::=  
    <search_condition>  
  
<merge_matched>::=  
    { UPDATE SET <set_clause> | DELETE }  
  
<merge_not_matched>::=  
{  
    INSERT [ ( column_list ) ]
        { VALUES ( values_list )  
        | DEFAULT VALUES }  
}  
  
<clause_search_condition> ::=  
    <search_condition> 

Nota

Per visualizzare la sintassi Transact-SQL per SQL Server 2014 e versioni precedenti, vedere Documentazione delle versioni precedenti.To view Transact-SQL syntax for SQL Server 2014 and earlier, see Previous versions documentation.

-- MERGE (Preview) for Azure Synapse Analytics 
[ WITH <common_table_expression> [,...n] ]  
MERGE
    [ INTO ] <target_table> [ [ AS ] table_alias ]  
    USING <table_source> [ [ AS ] table_alias ]
    ON <merge_search_condition>  
    [ WHEN MATCHED [ AND <clause_search_condition> ]  
        THEN <merge_matched> ] [ ...n ]  
    [ WHEN NOT MATCHED [ BY TARGET ] [ AND <clause_search_condition> ]  
        THEN <merge_not_matched> ]  
    [ WHEN NOT MATCHED BY SOURCE [ AND <clause_search_condition> ]  
        THEN <merge_matched> ] [ ...n ]
    [ OPTION ( <query_hint> [ ,...n ] ) ]
;  -- The semi-colon is required, or the query will return syntax  error. 

ArgomentiArguments

WITH <common_table_expression>WITH <common_table_expression>
Specifica la vista o il set di risultati denominato temporaneo, noto anche come espressione di tabella comune, definito nell'ambito di un'istruzione MERGE.Specifies the temporary named result set or view, also known as common table expression, that's defined within the scope of the MERGE statement. Il set di risultati deriva da una query semplice e l'istruzione MERGE vi fa riferimento.The result set derives from a simple query and is referenced by the MERGE statement. Per altre informazioni, vedere WITH common_table_expression (Transact-SQL).For more information, see WITH common_table_expression (Transact-SQL).

TOP ( expression ) [ PERCENT ]TOP ( expression ) [ PERCENT ]
Specifica il numero o la percentuale di righe interessate.Specifies the number or percentage of affected rows. Il valore di expression può essere un numero o una percentuale delle righe.expression can be either a number or a percentage of the rows. Le righe cui viene fatto riferimento nell'espressione TOP non vengono disposte in alcun ordine.The rows referenced in the TOP expression are not arranged in any order. Per altre informazioni, vedere TOP (Transact-SQL).For more information, see TOP (Transact-SQL).

La clausola TOP viene applicata dopo l'unione in join dell'intera tabella di origine con l'intera tabella di destinazione e dopo la rimozione delle righe unite in join non qualificate per un'azione di inserimento, aggiornamento o eliminazione.The TOP clause applies after the entire source table and the entire target table join and the joined rows that don't qualify for an insert, update, or delete action are removed. La clausola TOP riduce ulteriormente il numero di righe unite in join in base al valore specificato.The TOP clause further reduces the number of joined rows to the specified value. Le azioni di inserimento, aggiornamento o eliminazione vengono applicate alle righe unite in join rimanenti in modo non ordinato.The insert, update, or delete actions apply to the remaining joined rows in an unordered way. Ciò significa che le righe vengono distribuite tra le azioni definite nelle clausole WHEN senza alcun ordine.That is, there's no order in which the rows are distributed among the actions defined in the WHEN clauses. La specifica della clausola TOP (10), ad esempio, influisce su 10 righe.For example, specifying TOP (10) affects 10 rows. Di queste righe, 7 possono essere aggiornate e 3 inserite oppure 1 riga può essere eliminata, 5 aggiornate, 4 inserite e così via.Of these rows, 7 may be updated and 3 inserted, or 1 may be deleted, 5 updated, and 4 inserted, and so on.

Poiché l'istruzione MERGE esegue un'analisi completa di entrambe le tabelle di origine e di destinazione, l'uso della clausola TOP per modificare una tabella di grandi dimensioni creando più batch a volte influisce sulle prestazioni di I/O.Because the MERGE statement does a full table scan of both the source and target tables, I/O performance is sometimes affected when using the TOP clause to modify a large table by creating multiple batches. In questo scenario è importante assicurarsi che tutti i batch successivi abbiano come destinazione nuove righe.In this scenario, it's important to ensure that all successive batches target new rows.

database_namedatabase_name
Nome del database in cui si trova target_table .The name of the database in which target_table is located.

schema_nameschema_name
Nome dello schema a cui appartiene la tabella target_table .The name of the schema to which target_table belongs.

target_tabletarget_table
Tabella o vista rispetto alla quale vengono associate le righe di dati di <table_source> in base a <clause_search_condition>.The table or view against which the data rows from <table_source> are matched based on <clause_search_condition>. target_table rappresenta la destinazione di qualsiasi operazione di inserimento, aggiornamento o eliminazione specificata dalle clausole WHEN dell'istruzione MERGE.target_table is the target of any insert, update, or delete operations specified by the WHEN clauses of the MERGE statement.

Se target_table è una vista, qualsiasi azione eseguita su di essa deve soddisfare le condizioni per l'aggiornamento delle viste.If target_table is a view, any actions against it must satisfy the conditions for updating views. Per altre informazioni, vedere Modificare i dati tramite una vista.For more information, see Modify Data Through a View.

target_table non può essere una tabella remota.target_table can't be a remote table. Per target_table non può essere definita alcuna regola.target_table can't have any rules defined on it.

[AS] table_alias[ AS ] table_alias
Un nome alternativo per fare riferimento alla tabella target_table .An alternative name to reference a table for the target_table .

USING <table_source>USING <table_source>
Specifica l'origine dati corrispondente alle righe di dati in target_table in base a <merge_search condition>.Specifies the data source that's matched with the data rows in target_table based on <merge_search condition>. Il risultato di questa corrispondenza determina le azioni che le clausole WHEN dell'istruzione MERGE devono eseguire.The result of this match dictates the actions to take by the WHEN clauses of the MERGE statement. <table_source> può essere una tabella remota o una tabella derivata con accesso a tabelle remote.<table_source> can be a remote table or a derived table that accesses remote tables.

<table_source> può essere una tabella derivata che usa il costruttore di valori di tabella di Transact-SQLTransact-SQL per creare una tabella specificando più righe.<table_source> can be a derived table that uses the Transact-SQLTransact-SQL table value constructor to construct a table by specifying multiple rows.

[AS] table_alias[ AS ] table_alias
Un nome alternativo per fare riferimento alla tabella table_source.An alternative name to reference a table for the table_source.

Per altre informazioni sulla sintassi e gli argomenti di questa clausola, vedere FROM (Transact-SQL).For more information about the syntax and arguments of this clause, see FROM (Transact-SQL).

ON <merge_search_condition>ON <merge_search_condition>
Specifica le condizioni in base alle quali viene creato il join tra <table_source> e target_table per stabilire i punti di corrispondenza.Specifies the conditions on which <table_source> joins with target_table to determine where they match.

Attenzione

È importante specificare solo le colonne della tabella di destinazione da usare ai fini della corrispondenza,It's important to specify only the columns from the target table to use for matching purposes. ovvero specificare colonne della tabella di destinazione confrontate con quella corrispondente della tabella di origine.That is, specify columns from the target table that are compared to the corresponding column of the source table. Non provare a migliorare le prestazioni relative all'esecuzione delle query filtrando le righe della tabella di destinazione nella clausola ON, specificando ad esempio AND NOT target_table.column_x = value.Don't attempt to improve query performance by filtering out rows in the target table in the ON clause; for example, such as specifying AND NOT target_table.column_x = value. Questa operazione potrebbe comportare la restituzione di risultati imprevisti e non corretti.Doing so may return unexpected and incorrect results.

WHEN MATCHED THEN <merge_matched>WHEN MATCHED THEN <merge_matched>
Specifica che tutte le righe di *target_table corrispondenti alle righe restituite da <table_source> ON <merge_search_condition> e che soddisfano eventuali condizioni di ricerca aggiuntive vengono aggiornate oppure eliminate in base alla clausola <merge_matched>.Specifies that all rows of *target_table, which match the rows returned by <table_source> ON <merge_search_condition>, and satisfy any additional search condition, are either updated or deleted according to the <merge_matched> clause.

Nell'istruzione MERGE possono essere presenti al massimo due clausole WHEN MATCHED.The MERGE statement can have, at most, two WHEN MATCHED clauses. Se vengono specificate due clausole, alla prima deve essere associata una clausola AND <search_condition>.If two clauses are specified, the first clause must be accompanied by an AND <search_condition> clause. Per ogni riga specificata, la seconda clausola WHEN MATCHED viene applicata solo nel caso in cui non venga applicata la prima.For any given row, the second WHEN MATCHED clause is only applied if the first isn't. Se sono presenti due clausole WHEN MATCHED, è necessario che una specifichi un'azione UPDATE e l'altra un'azione DELETE.If there are two WHEN MATCHED clauses, one must specify an UPDATE action and one must specify a DELETE action. Quando nella clausola <merge_matched> viene specificato UPDATE e più righe di <table_source> corrispondono a una riga di target_table in base a <merge_search_condition>, SQL ServerSQL Server restituisce un errore.When UPDATE is specified in the <merge_matched> clause, and more than one row of <table_source> matches a row in target_table based on <merge_search_condition>, SQL ServerSQL Server returns an error. L'istruzione MERGE non può aggiornare la stessa riga più di una volta né aggiornare ed eliminare la stessa riga.The MERGE statement can't update the same row more than once, or update and delete the same row.

WHEN NOT MATCHED [ BY TARGET ] THEN <merge_not_matched>WHEN NOT MATCHED [ BY TARGET ] THEN <merge_not_matched>
Specifica che in target_table deve essere inserita una riga per ogni riga restituita da <table_source> ON <merge_search_condition> che non corrisponde a una riga in target_table , ma che soddisfa un'eventuale condizione di ricerca aggiuntiva.Specifies that a row is inserted into target_table for every row returned by <table_source> ON <merge_search_condition> that doesn't match a row in target_table , but satisfies an additional search condition, if present. I valori da inserire vengono specificati dalla clausola <merge_not_matched>.The values to insert are specified by the <merge_not_matched> clause. Nell'istruzione MERGE può essere presente una sola clausola WHEN NOT MATCHED [ BY TARGET ].The MERGE statement can have only one WHEN NOT MATCHED [ BY TARGET ] clause.

WHEN NOT MATCHED BY SOURCE THEN <merge_matched>WHEN NOT MATCHED BY SOURCE THEN <merge_matched>
Specifica che tutte le righe di *target_table che non corrispondono alle righe restituite da <table_source> ON <merge_search_condition> e che soddisfano eventuali condizioni di ricerca aggiuntive vengono aggiornate oppure eliminate in base alla clausola <merge_matched>.Specifies that all rows of *target_table, which don't match the rows returned by <table_source> ON <merge_search_condition>, and that satisfy any additional search condition, are updated or deleted according to the <merge_matched> clause.

Nell'istruzione MERGE possono essere presenti al massimo due clausole WHEN NOT MATCHED BY SOURCE.The MERGE statement can have at most two WHEN NOT MATCHED BY SOURCE clauses. Se vengono specificate due clausole, alla prima deve essere associata una clausola AND <clause_search_condition>.If two clauses are specified, then the first clause must be accompanied by an AND <clause_search_condition> clause. Per ogni riga specificata, la seconda clausola WHEN NOT MATCHED BY SOURCE viene applicata solo nel caso in cui non venga applicata la prima.For any given row, the second WHEN NOT MATCHED BY SOURCE clause is only applied if the first isn't. Se sono presenti due clausole WHEN NOT MATCHED BY SOURCE, è necessario che una specifichi un'azione UPDATE e l'altra un'azione DELETE.If there are two WHEN NOT MATCHED BY SOURCE clauses, then one must specify an UPDATE action and one must specify a DELETE action. <clause_search_condition> può fare riferimento solo a colonne della tabella di destinazione.Only columns from the target table can be referenced in <clause_search_condition>.

Se da <table_source> non viene restituita alcuna riga, non è possibile accedere alle colonne della tabella di origine.When no rows are returned by <table_source>, columns in the source table can't be accessed. Se l'azione di aggiornamento o eliminazione specificata nella clausola <merge_matched> fa riferimento a colonne della tabella di origine, viene restituito l'errore 207 (Nome di colonna non valido).If the update or delete action specified in the <merge_matched> clause references columns in the source table, error 207 (Invalid column name) is returned. La clausola WHEN NOT MATCHED BY SOURCE THEN UPDATE SET TargetTable.Col1 = SourceTable.Col1 può provocare, ad esempio, un errore nell'istruzione poiché non è possibile accedere a Col1 nella tabella di origine.For example, the clause WHEN NOT MATCHED BY SOURCE THEN UPDATE SET TargetTable.Col1 = SourceTable.Col1 may cause the statement to fail because Col1 in the source table is inaccessible.

AND <clause_search_condition>AND <clause_search_condition>
Specifica qualsiasi condizione di ricerca valida.Specifies any valid search condition. Per altre informazioni, vedere Condizione di ricerca(Transact-SQL).For more information, see Search Condition (Transact-SQL).

<table_hint_limited>
Specifica uno o più hint di tabella applicati alla tabella di destinazione per ogni azione di inserimento, aggiornamento o eliminazione eseguita dall'istruzione MERGE.Specifies one or more table hints to apply on the target table for each of the insert, update, or delete actions done by the MERGE statement. La parola chiave WITH e le parentesi sono obbligatorie.The WITH keyword and the parentheses are required.

Le opzioni NOLOCK e READUNCOMMITTED non sono consentite.NOLOCK and READUNCOMMITTED aren't allowed. Per altre informazioni sugli hint di tabella, vedere Hint di tabella (Transact-SQL).For more information about table hints, see Table Hints (Transact-SQL).

La specifica di un hint TABLOCK in una tabella di destinazione di un'istruzione INSERT equivale alla specifica dell'hint TABLOCKXSpecifying the TABLOCK hint on a table that's the target of an INSERT statement has the same effect as specifying the TABLOCKX hint. poiché determina l'acquisizione di un blocco esclusivo sulla tabella.An exclusive lock is taken on the table. Quando viene specificato, FORCESEEK viene applicato all'istanza implicita della tabella di destinazione unita in join con la tabella di origine.When FORCESEEK is specified, it applies to the implicit instance of the target table joined with the source table.

Attenzione

La specifica di READPAST con WHEN NOT MATCHED [BY TARGET] THEN INSERT può provocare l'esecuzione di operazioni INSERT che violano i vincoli UNIQUE.Specifying READPAST with WHEN NOT MATCHED [ BY TARGET ] THEN INSERT may result in INSERT operations that violate UNIQUE constraints.

INDEX ( index_val [ ,...n ] )INDEX ( index_val [ ,...n ] )
Specifica il nome o l'ID di uno o più indici della tabella di destinazione per eseguire un join implicito con la tabella di origine.Specifies the name or ID of one or more indexes on the target table for doing an implicit join with the source table. Per altre informazioni, vedere Hint di tabella (Transact-SQL).For more information, see Table Hints (Transact-SQL).

<output_clause>
Restituisce una riga per ogni riga in target_table aggiornata, inserita o eliminata, senza alcun ordine specifico.Returns a row for every row in target_table that's updated, inserted, or deleted, in no particular order. Nella clausola di output è possibile specificare $action .$action can be specified in the output clause. $action è una colonna di tipo nvarchar(10) che restituisce uno dei tre valori per ogni riga: "INSERT", "UPDATE" o "DELETE", secondo l'azione eseguita su tale riga.$action is a column of type nvarchar(10) that returns one of three values for each row: 'INSERT', 'UPDATE', or 'DELETE', according to the action done on that row. Per altre informazioni sugli argomenti e il comportamento di questa clausola, vedere Clausola OUTPUT (Transact-SQL).For more information about the arguments and behavior of this clause, see OUTPUT Clause (Transact-SQL).

OPTION ( <query_hint> [ ,...n ] )OPTION ( <query_hint> [ ,...n ] )
Specifica che vengono utilizzati hint di ottimizzazione per personalizzare il modo in cui il Motore di database elabora l'istruzione.Specifies that optimizer hints are used to customize the way the Database Engine processes the statement. Per altre informazioni, vedere Hint per la query (Transact-SQL).For more information, see Query Hints (Transact-SQL).

<merge_matched>
Specifica l'azione di aggiornamento o eliminazione applicata a tutte le righe di target_table che non corrispondono alle righe restituite da <table_source> ON <merge_search_condition> e che soddisfano eventuali condizioni di ricerca aggiuntive.Specifies the update or delete action that's applied to all rows of target_table that don't match the rows returned by <table_source> ON <merge_search_condition>, and which satisfy any additional search condition.

UPDATE SET <set_clause>UPDATE SET <set_clause>
Specifica l'elenco di colonne o di nomi di variabile da aggiornare nella tabella di destinazione e i valori in base ai quali eseguire l'aggiornamento.Specifies the list of column or variable names to update in the target table and the values with which to update them.

Per altre informazioni sugli argomenti di questa clausola, vedere UPDATE (Transact-SQL).For more information about the arguments of this clause, see UPDATE (Transact-SQL). L'impostazione di una variabile sullo stesso valore di una colonna non è supportata.Setting a variable to the same value as a column isn't supported.

DELETEDELETE
Specifica che le righe corrispondenti alle righe di target_table vengono eliminate.Specifies that the rows matching rows in target_table are deleted.

<merge_not_matched>
Specifica i valori da inserire nella tabella di destinazione.Specifies the values to insert into the target table.

( column_list )( column_list )
Elenco di una o più colonne della tabella di destinazione in cui inserire i dati.A list of one or more columns of the target table in which to insert data. Le colonne devono essere specificate come un nome costituito da una sola parte.Columns must be specified as a single-part name or else the MERGE statement will fail. Il valore di column_list deve essere racchiuso tra parentesi e delimitato da virgole.column_list must be enclosed in parentheses and delimited by commas.

VALUES ( values_list )VALUES ( values_list )
Elenco di costanti, variabili o espressioni separate da virgole, che restituiscono valori da inserire nella tabella di destinazione.A comma-separated list of constants, variables, or expressions that return values to insert into the target table. Le espressioni non possono contenere un'istruzione EXECUTE.Expressions can't contain an EXECUTE statement.

DEFAULT VALUESDEFAULT VALUES
Forza l'immissione nella riga inserita dei valori predefiniti associati a ogni colonna.Forces the inserted row to contain the default values defined for each column.

Per altre informazioni su questa clausola, vedere INSERT (Transact-SQL).For more information about this clause, see INSERT (Transact-SQL).

<search_condition>
Definisce le condizioni di ricerca per specificare <merge_search_condition> o <clause_search_condition>.Specifies the search conditions to specify <merge_search_condition> or <clause_search_condition>. Per altre informazioni sugli argomenti di questa clausola, vedere Condizione di ricerca (Transact-SQL).For more information about the arguments for this clause, see Search Condition (Transact-SQL).

<graph search pattern>
Specifica il modello di corrispondenza del grafico.Specifies the graph match pattern. Per altre informazioni sugli argomenti di questa clausola, vedere MATCH (Transact-SQL)For more information about the arguments for this clause, see MATCH (Transact-SQL)

OsservazioniRemarks

Nota

In Azure Synapse Analytics, il comando MERGE (anteprima) presenta le differenze seguenti rispetto a SQL Server e al database SQL di Azure.In Azure Synapse Analytics, the MERGE command (preview) has following differences compared to SQL server and Azure SQL database.

  • Un'azione di aggiornamento di MERGE viene implementata come una coppia di azioni di eliminazione e inserimento.A MERGE update is implemented as a delete and insert pair. Il numero di righe interessate da un'azione di aggiornamento di MERGE include le righe eliminate e inserite.The affected row count for a MERGE update includes the deleted and inserted rows.
  • Durante l'anteprima, il comando MERGE non funziona con le tabelle con vincoli UNIQUE.During the preview, the MERGE command does not work with tables with UNIQUE constraints. Questo problema verrà presto risolto in una versione futura.This will be fixed in a later release soon.
  • In questa tabella viene descritto il supporto per le tabelle con tipi di distribuzione diversi:The support for tables with different distribution types is described in this table:
CLAUSOLA MERGE in Azure Synapse AnalyticsMERGE CLAUSE in Azure Synapse Analytics Supporto della tabella di distribuzione TARGETSupported TARGE distribution table Supporto della tabella di distribuzione SOURCESupported SOURCE distribution table CommentoComment
WHEN MATCHEDWHEN MATCHED HASH, ROUND_ROBIN, REPLICATEHASH, ROUND_ROBIN, REPLICATE Tutti i tipi di distribuzioneAll distribution types
NOT MATCHED BY TARGETNOT MATCHED BY TARGET HASHHASH Tutti i tipi di distribuzioneAll distribution types Usare UPDATE/DELETE FROM…JOIN per sincronizzare le due tabelle.Use UPDATE/DELETE FROM…JOIN to synchronize two tables.
NOT MATCHED BY SOURCENOT MATCHED BY SOURCE Tutti i tipi di distribuzioneAll distribution types Tutti i tipi di distribuzioneAll distribution types Usare UPDATE/DELETE FROM…JOIN per sincronizzare le due tabelle.Use UPDATE/DELETE FROM…JOIN to synchronize two tables.

È necessario specificare almeno una delle tre clausole MATCHED, le quali possono essere tuttavia specificate in qualsiasi ordine.At least one of the three MATCHED clauses must be specified, but they can be specified in any order. Non è possibile aggiornare una variabile più di una volta nella stessa clausola MATCHED.A variable can't be updated more than once in the same MATCHED clause.

Tutte le azioni di inserimento, aggiornamento o eliminazione specificate nella tabella di destinazione dall'istruzione MERGE sono limitate da qualsiasi vincolo definito sulla tabella, inclusi vincoli di integrità referenziale di propagazione.Any insert, update, or delete action specified on the target table by the MERGE statement are limited by any constraints defined on it, including any cascading referential integrity constraints. Se IGNORE_DUP_KEY è ON per qualsiasi indice univoco nella tabella di destinazione, MERGE ignora questa impostazione.If IGNORE_DUP_KEY is ON for any unique indexes on the target table, MERGE ignores this setting.

Nell'istruzione MERGE è necessario utilizzare un punto e virgola (;) come carattere di terminazione.The MERGE statement requires a semicolon (;) as a statement terminator. In caso contrario, viene generato l'errore 10713.Error 10713 is raised when a MERGE statement is run without the terminator.

Se usato dopo MERGE, @@ROWCOUNT (Transact-SQL) restituisce al client il numero complessivo di righe inserite, aggiornate ed eliminate.When used after MERGE, @@ROWCOUNT (Transact-SQL) returns the total number of rows inserted, updated, and deleted to the client.

MERGE è una parola chiave completamente riservata se il livello di compatibilità del database è impostato su 100 o un valore più elevato.MERGE is a fully reserved keyword when the database compatibility level is set to 100 or higher. Nonostante l'istruzione MERGE sia disponibile per i livelli di compatibilità del database 90 e 100, se il livello di compatibilità è impostato su 90, la parola chiave non è completamente riservata.The MERGE statement is available under both 90 and 100 database compatibility levels; however, the keyword isn't fully reserved when the database compatibility level is set to 90.

Non usare l'istruzione MERGE quando si usa la replica di aggiornamento in coda.Don't use the MERGE statement when using queued updating replication. MERGE e il trigger per l'aggiornamento in coda non sono compatibili.The MERGE and queued updating trigger aren't compatible. Sostituire l'istruzione MERGE con un'istruzione INSERT o UPDATE.Replace the MERGE statement with an insert or an update statement.

Implementazione dei triggerTrigger Implementation

Per ogni azione di inserimento, aggiornamento o eliminazione specificata nell'istruzione MERGE, in SQL ServerSQL Server vengono attivati i trigger AFTER corrispondenti definiti nella tabella di destinazione, senza garantire l'ordine di attivazione dei trigger per le azioni.For every insert, update, or delete action specified in the MERGE statement, SQL ServerSQL Server fires any corresponding AFTER triggers defined on the target table, but doesn't guarantee on which action to fire triggers first or last. I trigger definiti per la stessa azione rispettano l'ordine specificato dall'utente.Triggers defined for the same action honor the order you specify. Per altre informazioni sull'impostazione dell'ordine di attivazione dei trigger, vedere Specifica dei primi e degli ultimi trigger.For more information about setting trigger firing order, see Specify First and Last Triggers.

Se per la tabella di destinazione è abilitato un trigger INSTEAD OF definito nella tabella stessa per un'azione di inserimento, aggiornamento o eliminazione eseguita da un'istruzione MERGE, è necessario che per tale tabella sia abilitato un trigger INSTEAD OF per tutte le azioni specificate nell'istruzione MERGE.If the target table has an enabled INSTEAD OF trigger defined on it for an insert, update, or delete action done by a MERGE statement, it must have an enabled INSTEAD OF trigger for all of the actions specified in the MERGE statement.

Se in target_table è definito un trigger INSTEAD OF UPDATE o INSTEAD OF DELETE, le operazioni di aggiornamento o eliminazione non vengono eseguite,If any INSTEAD OF UPDATE or INSTEAD OF DELETE triggers are defined on target_table , the update or delete operations aren't run. ma vengono attivati i trigger e le tabelle inserite ed eliminate vengono popolate di conseguenza.Instead, the triggers fire and the inserted and deleted tables then populate accordingly.

Se in target_table è definito un trigger INSTEAD OF INSERT, l'operazione di inserimento non viene eseguita,If any INSTEAD OF INSERT triggers are defined on target_table , the insert operation isn't performed. ma la tabella viene popolata di conseguenza.Instead, the table populates accordingly.

AutorizzazioniPermissions

È necessario disporre dell'autorizzazione SELECT per la tabella di origine e dell'autorizzazione INSERT, UPDATE o DELETE per quella di destinazione.Requires SELECT permission on the source table and INSERT, UPDATE, or DELETE permissions on the target table. Per altre informazioni, vedere gli articoli relativi a SELECT, INSERT, UPDATE e DELETE nella sezione Autorizzazioni.For more information, see the Permissions section in the SELECT, INSERT, UPDATE, and DELETE articles.

Ottimizzazione delle prestazioni delle istruzioni MERGEOptimizing MERGE Statement Performance

L'istruzione MERGE consente di sostituire le istruzioni DML singole con un'unica istruzione.By using the MERGE statement, you can replace the individual DML statements with a single statement. In questo modo è possibile migliorare le prestazioni delle query poiché le operazioni vengono eseguite in un'unica istruzione, riducendo di conseguenza al minimo il numero di elaborazioni dei dati delle tabelle di origine e di destinazione.This can improve query performance because the operations are performed within a single statement, therefore, minimizing the number of times the data in the source and target tables are processed. I vantaggi in termini di prestazioni dipendono tuttavia dalla disponibilità di join ed indici corretti e da altre considerazioni appropriate.However, performance gains depend on having correct indexes, joins, and other considerations in place.

Procedure consigliate per gli indiciIndex Best Practices

Per migliorare le prestazioni delle istruzioni MERGE, si consiglia di attenersi alle linee guida relative agli indici seguenti:To improve the performance of the MERGE statement, we recommend the following index guidelines:

  • Creare un indice univoco e di copertura sulle colonne di join della tabella di origine.Create an index on the join columns in the source table that is unique and covering.
  • Creare un indice cluster univoco nelle colonne di join della tabella di destinazione.Create a unique clustered index on the join columns in the target table.

Tali indici garantiscono l'univocità delle chiavi di join e l'ordinamento dei dati contenuti nelle tabelle.These indexes ensure that the join keys are unique and the data in the tables is sorted. Le prestazioni delle query risultano migliorate poiché Query Optimizer non deve eseguire alcuna ulteriore elaborazione della convalida per individuare e aggiornare righe duplicate né è necessario eseguire operazioni di ordinamento aggiuntive.Query performance is improved because the query optimizer does not need to perform extra validation processing to locate and update duplicate rows and additional sort operations are not necessary.

Procedure consigliate per l'operatore JOINJOIN Best Practices

Per migliorare le prestazioni delle istruzioni MERGE e garantire che vengano ottenuti risultati corretti, si consiglia di attenersi alle linee guida relative ai join seguenti:To improve the performance of the MERGE statement and ensure correct results are obtained, we recommend the following join guidelines:

  • Nella clausola ON <merge_search_condition> specificare solo condizioni di ricerca che determinano i criteri per la corrispondenza dei dati nelle tabelle di origine e di destinazione,Specify only search conditions in the ON <merge_search_condition> clause that determine the criteria for matching data in the source and target tables. ovvero specificare solo colonne della tabella di destinazione confrontate con quelle corrispondenti della tabella di origine.That is, specify only columns from the target table that are compared to the corresponding columns of the source table.
  • Non includere confronti con altri valori, ad esempio una costante.Do not include comparisons to other values such as a constant.

Per filtrare le righe delle tabelle di origine o di destinazione, effettuare una delle operazioni indicate di seguito.To filter out rows from the source or target tables, use one of the following methods.

  • Specificare la condizione di ricerca per applicare il filtro alla riga nella clausola WHEN appropriata,Specify the search condition for row filtering in the appropriate WHEN clause. ad esempio WHEN NOT MATCHED AND S.EmployeeName LIKE 'S%' THEN INSERT....For example, WHEN NOT MATCHED AND S.EmployeeName LIKE 'S%' THEN INSERT....
  • Definire una vista sull'origine o sulla destinazione che restituisca le righe filtrate e faccia riferimento alla vista come la tabella di origine o di destinazione.Define a view on the source or target that returns the filtered rows and reference the view as the source or target table. Se la vista viene definita sulla tabella di destinazione, qualsiasi azione eseguita su tale vista deve soddisfare le condizioni per l'aggiornamento delle viste.If the view is defined on the target table, any actions against it must satisfy the conditions for updating views. Per altre informazioni sull'aggiornamento di dati tramite una vista, vedere Modifica di dati tramite una vista.For more information about updating data by using a view, see Modifying Data Through a View.
  • Usare la clausola WITH <common table expression> per filtrare le righe delle tabelle di origine o di destinazione.Use the WITH <common table expression> clause to filter out rows from the source or target tables. Questo metodo è analogo alla specifica di criteri di ricerca aggiuntivi nella clausola ON e può produrre risultati non corretti.This method is similar to specifying additional search criteria in the ON clause and may produce incorrect results. Si consiglia di evitare l'utilizzo di questo metodo o di eseguirne un test accurato prima di implementarlo.We recommend that you avoid using this method or test thoroughly before implementing it.

L'operazione di join nelle istruzioni MERGE viene ottimizzata in modo analogo a un join in un'istruzione SELECT.The join operation in the MERGE statement is optimized in the same way as a join in a SELECT statement. Questo significa che, durante l'elaborazione di join in SQL Server, Query Optimizer sceglie il metodo di elaborazione del join più efficiente tra quelli possibili.That is, when SQL Server processes joins, the query optimizer chooses the most efficient method (out of several possibilities) of processing the join. Quando le dimensioni dell'origine e della destinazione sono simili e le linee guida relative agli indici descritte in precedenza vengono applicate alle tabelle di origine e di destinazione, un operatore merge join è il piano di query più efficiente.When the source and target are of similar size and the index guidelines described previously are applied to the source and target tables, a merge join operator is the most efficient query plan. poiché entrambe le tabelle vengono sottoposte ad analisi una sola volta e non è necessario ordinare i dati.This is because both tables are scanned once and there is no need to sort the data. Quando le dimensioni della tabella di origine sono inferiori rispetto a quelle della tabella di destinazione, è preferibile usare un operatore nested loops.When the source is smaller than the target table, a nested loops operator is preferable.

Per forzare l'utilizzo di un join specifico, è possibile indicare la clausola OPTION (<query_hint>) nelle istruzioni MERGE.You can force the use of a specific join by specifying the OPTION (<query_hint>) clause in the MERGE statement. Si consiglia di non utilizzare hash join come hint per la query per le istruzioni MERGE poiché questo tipo di join non utilizza indici.We recommend that you do not use the hash join as a query hint for MERGE statements because this join type does not use indexes.

Procedure consigliate per la parametrizzazioneParameterization Best Practices

Se un'istruzione SELECT, INSERT, UPDATE o DELETE viene eseguita senza parametri, Query Optimizer di SQL Server può scegliere di parametrizzare l'istruzione internamente,If a SELECT, INSERT, UPDATE, or DELETE statement is executed without parameters, the SQL Server query optimizer may choose to parameterize the statement internally. ovvero di sostituire con parametri i valori letterali contenuti nella query.This means that any literal values that are contained in the query are substituted with parameters. Ad esempio, l'istruzione INSERT dbo.MyTable (Col1, Col2) VALUES (1, 10), può essere implementata internamente come INSERT dbo.MyTable (Col1, Col2) VALUES (@p1, @p2).For example, the statement INSERT dbo.MyTable (Col1, Col2) VALUES (1, 10), may be implemented internally as INSERT dbo.MyTable (Col1, Col2) VALUES (@p1, @p2). Questo processo, denominato parametrizzazione semplice, consente di migliorare la capacità del motore relazionale di trovare una corrispondenza tra le nuove istruzioni SQL e i piani di esecuzione esistenti compilati in precedenza.This process, called simple parameterization, increases the ability of the relational engine to match new SQL statements with existing, previously-compiled execution plans. Le prestazioni delle query possono risultare migliorate poiché viene ridotta la frequenza di compilazioni e ricompilazioni delle query stesse.Query performance may be improved because the frequency of query compilations and recompilations are reduced. Query Optimizer non applica il processo di parametrizzazione semplice alle istruzioni MERGE.The query optimizer does not apply the simple parameterization process to MERGE statements. Di conseguenza, le prestazioni delle istruzioni MERGE che contengono valori letterali potrebbero non corrispondere a quelle di singole istruzioni INSERT, UPDATE o DELETE poiché viene compilato un nuovo piano ogni volta che l'istruzione MERGE viene eseguita.Therefore, MERGE statements that contain literal values may not perform as well as individual INSERT, UPDATE, or DELETE statements because a new plan is compiled each time the MERGE statement is executed.

Per migliorare le prestazioni delle query, si consiglia di attenersi alle linee guida relative alla parametrizzazione seguenti:To improve query performance, we recommend the following parameterization guidelines:

  • Parametrizzare tutti i valori letterali contenuti nella clausola ON <merge_search_condition> e nelle clausole WHEN dell'istruzione MERGE.Parameterize all literal values in the ON <merge_search_condition> clause and in the the WHEN clauses of the MERGE statement. È possibile ad esempio incorporare l'istruzione MERGE in una stored procedure sostituendo i valori letterali con parametri di input appropriati.For example, you can incorporate the MERGE statement into a stored procedure replacing the literal values with appropriate input parameters.
  • Se non è possibile parametrizzare l'istruzione, creare una guida di piano di tipo TEMPLATE e specificare l'hint per la query PARAMETERIZATION FORCED in tale guida.If you cannot parameterize the statement, create a plan guide of type TEMPLATE and specify the PARAMETERIZATION FORCED query hint in the plan guide.
  • Se le istruzioni MERGE vengono eseguite frequentemente nel database, impostare l'opzione PARAMETERIZATION relativa al database su FORCED.If MERGE statements are executed frequently on the database, consider setting the PARAMETERIZATION option on the database to FORCED. Si consiglia di prestare attenzione quando si imposta questa opzione,Use caution when setting this option. L'opzione PARAMETERIZATION è un'impostazione a livello di database e influisce sulle modalità di elaborazione delle query sul database.The PARAMETERIZATION option is a database-level setting and affects how all queries against the database are processed.

Procedure consigliate per la clausola TOPTOP Clause Best Practices

Nell'istruzione MERGE la clausola TOP specifica il numero o la percentuale di righe interessate dopo l'unione in join della tabella di origine e di quella di destinazione e dopo la rimozione delle righe non qualificate per un'azione di inserimento, aggiornamento o eliminazione.In the MERGE statement, the TOP clause specifies the number or percentage of rows that are affected after the source table and the target table are joined, and after rows that do not qualify for an insert, update, or delete action are removed. La clausola TOP riduce ulteriormente il numero di righe unite in join in base al valore specificato e l'azione di inserimento, aggiornamento o eliminazione viene applicata alle righe unite in join rimanenti in modo non ordinato.The TOP clause further reduces the number of joined rows to the specified value and the insert, update, or delete actions are applied to the remaining joined rows in an unordered fashion. Ciò significa che le righe vengono distribuite tra le azioni definite nelle clausole WHEN senza alcun ordine.That is, there is no order in which the rows are distributed among the actions defined in the WHEN clauses. La specifica della clausola TOP (10), ad esempio, influisce su 10 righe, 7 delle quali possono essere aggiornate e 3 inserite oppure 1 riga può essere eliminata, 5 aggiornate e 4 inserite e così via.For example, specifying TOP (10) affects 10 rows; of these rows, 7 may be updated and 3 inserted, or 1 may be deleted, 5 updated, and 4 inserted and so on.

In genere la clausola TOP viene utilizzata per eseguire operazioni DML (Data Manipulation Language) in batch in una tabella di grandi dimensioni.It is common to use the TOP clause to perform data manipulation language (DML) operations on a large table in batches. Quando la clausola TOP viene utilizzata nell'istruzione MERGE per questo scopo, è importante comprendere le implicazioni seguenti.When using the TOP clause in the MERGE statement for this purpose, it is important to understand the following implications.

  • Possibile impatto sulle prestazioni di I/O.I/O performance may be affected.

    L'istruzione MERGE esegue un'analisi completa di entrambe le tabelle di origine e di destinazione.The MERGE statement performs a full table scan of both the source and target tables. Se l'operazione viene divisa in batch, è possibile ridurre il numero di operazioni di scrittura eseguite per ogni batch, sebbene ciascun batch eseguirà un'analisi completa sia delle tabelle di origine che di quelle di destinazione.Dividing the operation into batches reduces the number of write operations performed per batch; however, each batch will perform a full table scan of the source and target tables. L'attività di lettura risultante può influire sulle prestazioni della query.The resulting read activity may affect the performance of the query.

  • Possibile restituzione di risultati non corretti.Incorrect results can occur.

    È importante assicurarsi che tutti i batch successivi vengano destinati a nuove righe per evitare un comportamento indesiderato, ad esempio l'inserimento non corretto di righe duplicate nella tabella di destinazione.It is important to ensure that all successive batches target new rows or undesired behavior such as incorrectly inserting duplicate rows into the target table can occur. Questa situazione può verificarsi quando nella tabella di origine è contenuta una riga non presente in un batch di destinazione, ma presente nella tabella di destinazione complessiva.This can happen when the source table includes a row that was not in a target batch but was in the overall target table.

  • Per garantire la restituzione di risultati corretti:To insure correct results:

    • Utilizzare la clausola ON per determinare le righe di origine che influiscono sulle righe di destinazione esistenti e le righe effettivamente nuove.Use the ON clause to determine which source rows affect existing target rows and which are genuinely new.
    • Utilizzare una condizione aggiuntiva nella clausola WHEN MATCHED per determinare se la riga di destinazione è già stata aggiornata da un batch precedente.Use an additional condition in the WHEN MATCHED clause to determine if the target row has already been updated by a previous batch.

Poiché la clausola TOP viene applicata solo dopo l'applicazione di queste clausole, a ogni esecuzione viene inserita solo una riga effettivamente non corrispondente o viene aggiornata una riga esistente.Because the TOP clause is only applied after these clauses are applied, each execution either inserts one genuinely unmatched row or updates one existing row.

Procedure consigliate per il caricamento bulkBulk Load Best Practices

L'istruzione MERGE può essere usata per eseguire in modo efficiente il caricamento bulk di dati da un file di dati di origine in una tabella di destinazione specificando la clausola OPENROWSET(BULK…) come origine della tabella.The MERGE statement can be used to efficiently bulk load data from a source data file into a target table by specifying the OPENROWSET(BULK…) clause as the table source. In questo modo, l'intero file viene elaborato in un unico batch.By doing so, the entire file is processed in a single batch.

Per migliorare le prestazioni del processo di merge di tipo bulk, si consiglia di attenersi alle linee guida seguenti:To improve the performance of the bulk merge process, we recommend the following guidelines:

  • Creare un indice cluster sulle colonne di join della tabella di destinazione.Create a clustered index on the join columns in the target table.

  • Usare gli hint ORDER e UNIQUE nella clausola OPENROWSET(BULK…) per specificare l'ordinamento del file di dati di origine.Use the ORDER and UNIQUE hints in the OPENROWSET(BULK…) clause to specify how the source data file is sorted.

    Per impostazione predefinita, per l'operazione bulk si presume che il file di dati non sia ordinato.By default, the bulk operation assumes the data file is unordered. Di conseguenza, è importante che i dati di origine siano ordinati in base all'indice cluster nella tabella di destinazione e che l'hint ORDER venga utilizzato per indicare l'ordine, in modo che Query Optimizer possa generare un piano di query più efficiente.Therefore, it is important that the source data is sorted according to the clustered index on the target table and that the ORDER hint is used to indicate the order so that the query optimizer can generate a more efficient query plan. Gli hint vengono convalidati in fase di esecuzione. Se il flusso di dati non è conforme agli hint specificati, viene generato un errore.Hints are validated at runtime; if the data stream does not conform to the specified hints, an error is raised.

Queste linee guida garantiscono che le chiavi di join siano univoche e che l'ordinamento dei dati nel file di origine corrisponda alla tabella di destinazione.These guidelines ensure that the join keys are unique and the sort order of the data in the source file matches the target table. Le prestazioni delle query risultano migliorate poiché non sono necessarie ulteriori operazioni di ordinamento né vengono richieste copie dei dati non necessarie.Query performance is improved because additional sort operations are not necessary and unnecessary data copies are not required.

Misurazione e diagnosi delle prestazioni delle istruzioni MERGEMeasuring and Diagnosing MERGE Performance

Per effettuare la misurazione e la diagnosi delle prestazioni delle istruzioni MERGE, sono disponibili le caratteristiche seguenti.The following features are available to assist you in measuring and diagnosing the performance of MERGE statements.

  • Contatore merge stmt nella DMV sys.dm_exec_query_optimizer_info, che consente di restituire il numero di ottimizzazioni di query per le istruzioni MERGE.Use the merge stmt counter in the sys.dm_exec_query_optimizer_info dynamic management view to return the number of query optimizations that are for MERGE statements.
  • Attributo merge_action_type nella DMV sys.dm_exec_plan_attributes, che consente di restituire il tipo del piano di esecuzione del trigger usato come risultato di un'istruzione MERGE.Use the merge_action_type attribute in the sys.dm_exec_plan_attributes dynamic management view to return the type of trigger execution plan used as the result of a MERGE statement.
  • Traccia SQL, che consente di raccogliere i dati relativi alla risoluzione dei problemi per l'istruzione MERGE in modo analogo alla raccolta dei dati per altre istruzioni DML (Data Manipulation Language).Use SQL Trace to gather troubleshooting data for the MERGE statement in the same way you would for other data manipulation language (DML) statements. Per altre informazioni, vedere SQL Trace.For more information, see SQL Trace.

EsempiExamples

R.A. Uso di MERGE per eseguire operazioni INSERT e UPDATE in una tabella in un'unica istruzioneUsing MERGE to do INSERT and UPDATE operations on a table in a single statement

Uno scenario comune è l'aggiornamento di una o più colonne in una tabella se esiste una riga corrispondenteA common scenario is updating one or more columns in a table if a matching row exists. oppure l'inserimento dei dati come nuova riga se non esiste una riga corrispondente.Or, inserting the data as a new row if a matching row doesn't exist. In genere si mettono in atto entrambi gli scenari passando i parametri a una stored procedure contenente le istruzioni UPDATE e INSERT appropriate.You usually do either scenario by passing parameters to a stored procedure that contains the appropriate UPDATE and INSERT statements. Con l'istruzione MERGE è possibile eseguire entrambe le attività in un'unica istruzione.With the MERGE statement, you can do both tasks in a single statement. Nell'esempio seguente viene illustrata una stored procedure nel database AdventureWorks2012AdventureWorks2012 che contiene un'istruzione INSERT e un'istruzione UPDATE.The following example shows a stored procedure in the AdventureWorks2012AdventureWorks2012database that contains both an INSERT statement and an UPDATE statement. La stored procedure viene quindi modificata per eseguire le operazioni equivalenti usando una singola istruzione MERGE.The procedure is then modified to run the equivalent operations by using a single MERGE statement.

CREATE PROCEDURE dbo.InsertUnitMeasure  
    @UnitMeasureCode nchar(3),  
    @Name nvarchar(25)  
AS
BEGIN  
    SET NOCOUNT ON;  
-- Update the row if it exists.
    UPDATE Production.UnitMeasure  
SET Name = @Name  
WHERE UnitMeasureCode = @UnitMeasureCode  
-- Insert the row if the UPDATE statement failed.  
IF (@@ROWCOUNT = 0 )  
BEGIN  
    INSERT INTO Production.UnitMeasure (UnitMeasureCode, Name)  
    VALUES (@UnitMeasureCode, @Name)  
END  
END;  
GO  
-- Test the procedure and return the results.  
EXEC InsertUnitMeasure @UnitMeasureCode = 'ABC', @Name = 'Test Value';  
SELECT UnitMeasureCode, Name FROM Production.UnitMeasure  
WHERE UnitMeasureCode = 'ABC';  
GO  
  
-- Rewrite the procedure to perform the same operations using the
-- MERGE statement.  
-- Create a temporary table to hold the updated or inserted values
-- from the OUTPUT clause.  
CREATE TABLE #MyTempTable  
    (ExistingCode nchar(3),  
     ExistingName nvarchar(50),  
     ExistingDate datetime,  
     ActionTaken nvarchar(10),  
     NewCode nchar(3),  
     NewName nvarchar(50),  
     NewDate datetime  
    );  
GO  
ALTER PROCEDURE dbo.InsertUnitMeasure  
    @UnitMeasureCode nchar(3),  
    @Name nvarchar(25)  
AS
BEGIN  
    SET NOCOUNT ON;  
  
    MERGE Production.UnitMeasure AS target  
    USING (SELECT @UnitMeasureCode, @Name) AS source (UnitMeasureCode, Name)  
    ON (target.UnitMeasureCode = source.UnitMeasureCode)  
    WHEN MATCHED THEN
        UPDATE SET Name = source.Name  
    WHEN NOT MATCHED THEN  
        INSERT (UnitMeasureCode, Name)  
        VALUES (source.UnitMeasureCode, source.Name)  
    OUTPUT deleted.*, $action, inserted.* INTO #MyTempTable;  
END;  
GO  
-- Test the procedure and return the results.  
EXEC InsertUnitMeasure @UnitMeasureCode = 'ABC', @Name = 'New Test Value';  
EXEC InsertUnitMeasure @UnitMeasureCode = 'XYZ', @Name = 'Test Value';  
EXEC InsertUnitMeasure @UnitMeasureCode = 'ABC', @Name = 'Another Test Value';  
  
SELECT * FROM #MyTempTable;  
-- Cleanup
DELETE FROM Production.UnitMeasure WHERE UnitMeasureCode IN ('ABC','XYZ');  
DROP TABLE #MyTempTable;  
GO  

B.B. Uso di MERGE per eseguire operazioni UPDATE e DELETE in una tabella in un'unica istruzioneUsing MERGE to do UPDATE and DELETE operations on a table in a single statement

L'esempio seguente usa MERGE per aggiornare la tabella ProductInventory nel database di esempio AdventureWorks2012AdventureWorks2012, su base giornaliera, in base agli ordini elaborati nella tabella SalesOrderDetail.The following example uses MERGE to update the ProductInventory table in the AdventureWorks2012AdventureWorks2012 sample database, daily, based on orders that are processed in the SalesOrderDetail table. La colonna Quantity della tabella ProductInventory viene aggiornata sottraendo il numero di ordini effettuati ogni giorno per ciascun prodotto nella tabella SalesOrderDetail.The Quantity column of the ProductInventory table is updated by subtracting the number of orders placed each day for each product in the SalesOrderDetail table. Se il numero di ordini per un prodotto riduce il livello delle scorte del prodotto a zero o a un valore inferiore, la riga relativa a tale prodotto viene eliminata dalla tabella ProductInventory.If the number of orders for a product drops the inventory level of a product to 0 or less, the row for that product is deleted from the ProductInventory table.

CREATE PROCEDURE Production.usp_UpdateInventory  
    @OrderDate datetime  
AS  
MERGE Production.ProductInventory AS target  
USING (SELECT ProductID, SUM(OrderQty) FROM Sales.SalesOrderDetail AS sod  
    JOIN Sales.SalesOrderHeader AS soh  
    ON sod.SalesOrderID = soh.SalesOrderID  
    AND soh.OrderDate = @OrderDate  
    GROUP BY ProductID) AS source (ProductID, OrderQty)  
ON (target.ProductID = source.ProductID)  
WHEN MATCHED AND target.Quantity - source.OrderQty <= 0  
    THEN DELETE  
WHEN MATCHED
    THEN UPDATE SET target.Quantity = target.Quantity - source.OrderQty,
                    target.ModifiedDate = GETDATE()  
OUTPUT $action, Inserted.ProductID, Inserted.Quantity,
    Inserted.ModifiedDate, Deleted.ProductID,  
    Deleted.Quantity, Deleted.ModifiedDate;  
GO  
  
EXECUTE Production.usp_UpdateInventory '20030501'  

C.C. Uso di MERGE per eseguire operazioni UPDATE e INSERT in una tabella di destinazione usando una tabella di origine derivataUsing MERGE to do UPDATE and INSERT operations on a target table by using a derived source table

Nell'esempio seguente viene utilizzata l'istruzione MERGE per modificare la tabella SalesReason nel database AdventureWorks2012AdventureWorks2012 eseguendo l'aggiornamento o l'inserimento di righe.The following example uses MERGE to modify the SalesReason table in the AdventureWorks2012AdventureWorks2012 database by either updating or inserting rows. Quando il valore di NewName nella tabella di origine corrisponde a un valore della colonna Name nella tabella di destinazione (SalesReason), la colonna ReasonType viene aggiornata nella tabella di destinazione.When the value of NewName in the source table matches a value in the Name column of the target table, (SalesReason), the ReasonType column is updated in the target table. Quando il valore di NewName non corrisponde, la riga di origine viene inserita nella tabella di destinazione.When the value of NewName doesn't match, the source row is inserted into the target table. La tabella di origine è una tabella derivata che utilizza il costruttore di valori di tabella Transact-SQLTransact-SQL per specificare più righe per la tabella di origine.The source table is a derived table that uses the Transact-SQLTransact-SQL table value constructor to specify multiple rows for the source table. Per altre informazioni sull'uso del costruttore di valori di tabella in una tabella derivata, vedere Costruttore di valori di tabella (Transact-SQL).For more information about using the table value constructor in a derived table, see Table Value Constructor (Transact-SQL). L'esempio illustra anche come archiviare i risultati della clausola OUTPUT in una variabile di tabella.The example also shows how to store the results of the OUTPUT clause in a table variable. Si riepilogano quindi i risultati dell'istruzione MERGE eseguendo una semplice operazione di selezione che restituisce il numero di righe inserite e aggiornate.And, then you summarize the results of the MERGE statement by running a simple select operation that returns the count of inserted and updated rows.

-- Create a temporary table variable to hold the output actions.  
DECLARE @SummaryOfChanges TABLE(Change VARCHAR(20));  
  
MERGE INTO Sales.SalesReason AS Target  
USING (VALUES ('Recommendation','Other'), ('Review', 'Marketing'),
              ('Internet', 'Promotion'))  
       AS Source (NewName, NewReasonType)  
ON Target.Name = Source.NewName  
WHEN MATCHED THEN  
UPDATE SET ReasonType = Source.NewReasonType  
WHEN NOT MATCHED BY TARGET THEN  
INSERT (Name, ReasonType) VALUES (NewName, NewReasonType)  
OUTPUT $action INTO @SummaryOfChanges;  
  
-- Query the results of the table variable.  
SELECT Change, COUNT(*) AS CountPerChange  
FROM @SummaryOfChanges  
GROUP BY Change;  

D.D. Inserimento dei risultati dell'istruzione MERGE in un'altra tabellaInserting the results of the MERGE statement into another table

Nell'esempio seguente vengono acquisiti i dati restituiti dalla clausola OUTPUT di un'istruzione MERGE e tali dati vengono inseriti in un'altra tabella.The following example captures data returned from the OUTPUT clause of a MERGE statement and inserts that data into another table. L'istruzione MERGE consente di aggiornare la colonna Quantity della tabella ProductInventory nel database AdventureWorks2012AdventureWorks2012, in base agli ordini elaborati nella tabella SalesOrderDetail.The MERGE statement updates the Quantity column of the ProductInventory table in the AdventureWorks2012AdventureWorks2012 database, based on orders that are processed in the SalesOrderDetail table. L'esempio acquisisce le righe aggiornate e le inserisce in un'altra tabella usata per tenere traccia delle modifiche apportate alle scorte.The example captures the updated rows and inserts them into another table that's used to track inventory changes.

CREATE TABLE Production.UpdatedInventory  
    (ProductID INT NOT NULL, LocationID int, NewQty int, PreviousQty int,  
     CONSTRAINT PK_Inventory PRIMARY KEY CLUSTERED (ProductID, LocationID));  
GO  
INSERT INTO Production.UpdatedInventory  
SELECT ProductID, LocationID, NewQty, PreviousQty
FROM  
(    MERGE Production.ProductInventory AS pi  
     USING (SELECT ProductID, SUM(OrderQty)
            FROM Sales.SalesOrderDetail AS sod  
            JOIN Sales.SalesOrderHeader AS soh  
            ON sod.SalesOrderID = soh.SalesOrderID  
            AND soh.OrderDate BETWEEN '20030701' AND '20030731'  
            GROUP BY ProductID) AS src (ProductID, OrderQty)  
     ON pi.ProductID = src.ProductID  
    WHEN MATCHED AND pi.Quantity - src.OrderQty >= 0
        THEN UPDATE SET pi.Quantity = pi.Quantity - src.OrderQty  
    WHEN MATCHED AND pi.Quantity - src.OrderQty <= 0
        THEN DELETE  
    OUTPUT $action, Inserted.ProductID, Inserted.LocationID,
        Inserted.Quantity AS NewQty, Deleted.Quantity AS PreviousQty)  
 AS Changes (Action, ProductID, LocationID, NewQty, PreviousQty)
 WHERE Action = 'UPDATE';  
GO  

E.E. Uso di MERGE per eseguire INSERT o UPDATE in una tabella bordi di destinazione in un database a grafoUsing MERGE to do INSERT or UPDATE on a target edge table in a graph database

In questo esempio si creano le tabelle nodi Person e City e la tabella bordi livesIn.In this example, you create node tables Person and City and an edge table livesIn. Si usa l'istruzione MERGE sul bordo livesIn e si inserisce una nuova riga se il bordo non esiste già tra Person e City.You use the MERGE statement on the livesIn edge and insert a new row if the edge doesn't already exist between a Person and City. Se il bordo esiste già, si aggiorna solo l'attributo StreetAddress sul bordo livesIn.If the edge already exists, then you just update the StreetAddress attribute on the livesIn edge.

-- CREATE node and edge tables
CREATE TABLE Person
    (
        ID INTEGER PRIMARY KEY,
        PersonName VARCHAR(100)
    )
AS NODE
GO

CREATE TABLE City
    (
        ID INTEGER PRIMARY KEY,
        CityName VARCHAR(100),
        StateName VARCHAR(100)
    )
AS NODE
GO

CREATE TABLE livesIn
    (
        StreetAddress VARCHAR(100)
    )
AS EDGE
GO

-- INSERT some test data into node and edge tables
INSERT INTO Person VALUES (1, 'Ron'), (2, 'David'), (3, 'Nancy')
GO

INSERT INTO City VALUES (1, 'Redmond', 'Washington'), (2, 'Seattle', 'Washington')
GO

INSERT livesIn SELECT P.$node_id, C.$node_id, c
FROM Person P, City C, (values (1,1, '123 Avenue'), (2,2,'Main Street')) v(a,b,c)
WHERE P.id = a AND C.id = b
GO

-- Use MERGE to update/insert edge data
CREATE OR ALTER PROCEDURE mergeEdge
    @PersonId integer,
    @CityId integer,
    @StreetAddress varchar(100)
AS
BEGIN
    MERGE livesIn
        USING ((SELECT @PersonId, @CityId, @StreetAddress) AS T (PersonId, CityId, StreetAddress)
                JOIN Person ON T.PersonId = Person.ID
                JOIN City ON T.CityId = City.ID)
        ON MATCH (Person-(livesIn)->City)
    WHEN MATCHED THEN
        UPDATE SET StreetAddress = @StreetAddress
    WHEN NOT MATCHED THEN
        INSERT ($from_id, $to_id, StreetAddress)
        VALUES (Person.$node_id, City.$node_id, @StreetAddress) ;
END
GO

-- Following will insert a new edge in the livesIn edge table
EXEC mergeEdge 3, 2, '4444th Avenue'
GO

-- Following will update the StreetAddress on the edge that connects Ron to Redmond
EXEC mergeEdge 1, 1, '321 Avenue'
GO

-- Verify that all the address were added/updated correctly
SELECT PersonName, CityName, StreetAddress
FROM Person , City , livesIn
WHERE MATCH(Person-(livesIn)->city)
GO

Vedere ancheSee Also