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

ESTE TEMA SE APLICA A:síSQL Server (a partir de 2008)síAzure SQL DatabasenoAzure SQL Data Warehouse noAlmacenamiento de datos paralelos THIS TOPIC APPLIES TO:yesSQL Server (starting with 2008)yesAzure SQL DatabasenoAzure SQL Data Warehouse noParallel Data Warehouse

Realiza operaciones de inserción, actualización o eliminación en una tabla de destino según los resultados de una combinación con una tabla de origen.Performs insert, update, or delete operations on a target table based on the results of a join with a source table. Por ejemplo, puede sincronizar dos tablas insertando, actualizando o eliminando las filas de una tabla según las diferencias que se encuentren en la otra.For example, you can synchronize two tables by inserting, updating, or deleting rows in one table based on differences found in the other table.

Consejo de rendimiento: el comportamiento condicional descrito para la instrucción MERGE funciona mejor cuando las dos tablas tienen una mezcla compleja de características de búsqueda de coincidencias.Performance Tip: The conditional behavior described for the MERGE statement works best when the two tables have a complex mixture of matching characteristics. Por ejemplo, insertar una fila si no la hay, o actualizar la fila si esta coincide.For example, inserting a row if it does not exist, or updating the row if it does match. Cuando simplemente se actualiza una tabla basada en las filas de otra tabla, se puede lograr un mejor rendimiento y escalabilidad con las instrucciones básicas INSERT, UPDATE y DELETE.When simply updating one table based on the rows of another table, improved performance and scalability can be achieved with basic INSERT, UPDATE, and DELETE statements. Por ejemplo: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);  

Icono de vínculo de tema Convenciones de sintaxis de Transact-SQLTopic link icon Transact-SQL Syntax Conventions

SintaxisSyntax

[ WITH <common_table_expression> [,...n] ]  
MERGE   
    [ TOP ( expression ) [ PERCENT ] ]   
    [ INTO ] <target_table> [ WITH ( <merge_hint> ) ] [ [ AS ] table_alias ]  
    USING <table_source>   
    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 ] ) ] }  
}  

<table_source> ::=   
{  
    table_or_view_name [ [ AS ] table_alias ] [ <tablesample_clause> ]   
        [ WITH ( table_hint [ [ , ]...n ] ) ]   
  | rowset_function [ [ AS ] table_alias ]   
        [ ( bulk_column_alias [ ,...n ] ) ]   
  | user_defined_function [ [ AS ] table_alias ]  
  | OPENXML <openxml_clause>   
  | derived_table [ AS ] table_alias [ ( column_alias [ ,...n ] ) ]   
  | <joined_table>   
  | <pivoted_table>   
  | <unpivoted_table>   
}  

<merge_search_condition> ::=  
    <search_condition>  

<merge_matched>::=  
    { UPDATE SET <set_clause> | DELETE }  

<set_clause>::=  
SET  
  { column_name = { expression | DEFAULT | NULL }  
  | { udt_column_name.{ { property_name = expression  
                        | field_name = expression }  
                        | method_name ( argument [ ,...n ] ) }  
    }  
  | column_name { .WRITE ( expression , @Offset , @Length ) }  
  | @variable = expression  
  | @variable = column = expression  
  | column_name { += | -= | *= | /= | %= | &= | ^= | |= } expression  
  | @variable { += | -= | *= | /= | %= | &= | ^= | |= } expression  
  | @variable = column { += | -= | *= | /= | %= | &= | ^= | |= } expression  
  } [ ,...n ]   

<merge_not_matched>::=  
{  
    INSERT [ ( column_list ) ]   
        { VALUES ( values_list )  
        | DEFAULT VALUES }  
}  

<clause_search_condition> ::=  
    <search_condition>  

<search condition> ::=  
    { [ NOT ] <predicate> | ( <search_condition> ) }   
    [ { AND | OR } [ NOT ] { <predicate> | ( <search_condition> ) } ]   
[ ,...n ]   

<predicate> ::=   
    { expression { = | < > | ! = | > | > = | ! > | < | < = | ! < } expression   
    | string_expression [ NOT ] LIKE string_expression   
  [ ESCAPE 'escape_character' ]   
    | expression [ NOT ] BETWEEN expression AND expression   
    | expression IS [ NOT ] NULL   
    | CONTAINS   
  ( { column | * } , '< contains_search_condition >' )   
    | FREETEXT ( { column | * } , 'freetext_string' )   
    | expression [ NOT ] IN ( subquery | expression [ ,...n ] )   
    | expression { = | < > | ! = | > | > = | ! > | < | < = | ! < }   
  { ALL | SOME | ANY} ( subquery )   
    | EXISTS ( subquery ) }   

<output_clause>::=  
{  
    [ OUTPUT <dml_select_list> INTO { @table_variable | output_table }  
        [ (column_list) ] ]  
    [ OUTPUT <dml_select_list> ]  
}  

<dml_select_list>::=  
    { <column_name> | scalar_expression }   
        [ [AS] column_alias_identifier ] [ ,...n ]  

<column_name> ::=  
    { DELETED | INSERTED | from_table_name } . { * | column_name }  
    | $action  

ArgumentosArguments

CON <common_table_expression >WITH <common_table_expression>
Especifica la vista o el conjunto de resultados temporal indicado, que también se conoce como expresión de tabla común, definido en el ámbito de la instrucción MERGE.Specifies the temporary named result set or view, also known as common table expression, defined within the scope of the MERGE statement. El conjunto de resultados se deriva de una consulta simple. La instrucción MERGE hace referencia al conjunto de resultados.The result set is derived from a simple query and is referenced by the MERGE statement. Para obtener más información, consulte con common_table_expression ( Transact-SQL ) .For more information, see WITH common_table_expression (Transact-SQL).

Parte superior ( expresión ) [%]TOP ( expression ) [ PERCENT ]
Especifica el número o porcentaje de filas afectadas.Specifies the number or percentage of rows that are affected. expresión puede ser un número o un porcentaje de las filas.expression can be either a number or a percentage of the rows. Las filas a las que se hace referencia en la expresión TOP no están organizadas en ningún orden.The rows referenced in the TOP expression are not arranged in any order. Para obtener más información, vea TOP ( Transact-SQL ) .For more information, see TOP (Transact-SQL).

La cláusula TOP se aplica después de que se combinen toda la tabla de origen y toda la tabla de destino, y se quiten las filas combinadas que no reúnan las condiciones para las acciones de inserción, actualización o eliminación.The TOP clause is applied after the entire source table and the entire target table are joined and the joined rows that do not qualify for an insert, update, or delete action are removed. La cláusula TOP reduce aún más el número de filas combinadas al valor especificado y se aplican las acciones de inserción, actualización o eliminación a las filas combinadas restantes de una manera desordenada.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. Es decir, no hay ningún orden en el que las filas se distribuyan entre las acciones definidas en las cláusulas WHEN.That is, there is no order in which the rows are distributed among the actions defined in the WHEN clauses. Por ejemplo, cuando se especifica TOP (10) afecta a 10 filas; de estas filas, 7 se pueden actualizar y 3 insertar, o se pueden eliminar 1, actualizar 5 e insertar 4, etc.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.

Dado que la instrucción MERGE realiza exámenes de tabla completos de ambas tablas, de destino y de origen, el rendimiento de E/S puede verse afectado al utilizar la cláusula TOP para modificar una tabla grande mediante la creación de varios lotes.Because the MERGE statement performs a full table scan of both the source and target tables, I/O performance can be affected when using the TOP clause to modify a large table by creating multiple batches. En este escenario, es importante asegurarse de que todos los lotes sucesivos tengan como destino nuevas filas.In this scenario, it is important to ensure that all successive batches target new rows.

database_namedatabase_name
Es el nombre de la base de datos en el que target_table se encuentra.Is the name of the database in which target_table is located.

schema_nameschema_name
Es el nombre del esquema al que target_table pertenece.Is the name of the schema to which target_table belongs.

target_tabletarget_table
Es la tabla o vista en la que los datos de filas de <table_source > se comparan en función de <clause_search_condition >.Is the table or view against which the data rows from <table_source> are matched based on <clause_search_condition>. target_table es el destino de cualquier operaciones de inserción, actualización o eliminación especificadas por las cláusulas WHEN de la instrucción MERGE.target_table is the target of any insert, update, or delete operations specified by the WHEN clauses of the MERGE statement.

Si target_table es una vista, cualquier acción con ella debe satisfacer las condiciones para actualizar las vistas.If target_table is a view, any actions against it must satisfy the conditions for updating views. Para obtener más información, consulte modificar datos mediante una vista.For more information, see Modify Data Through a View.

target_table no puede ser una tabla remota.target_table cannot be a remote table. target_table no puede tener ninguna regla definida en él.target_table cannot have any rules defined on it.

[COMO] aliasTabla[ AS ] table_alias
Es un nombre alternativo que se utiliza para hacer referencia a una tabla.Is an alternative name used to reference a table.

USAR <table_source >USING <table_source>
Especifica el origen de datos que coincide con las filas de datos de target_table basado en <merge_search condition >.Specifies the data source that is matched with the data rows in target_table based on <merge_search condition>. El resultado de esta coincidencia dicta las acciones que tomarán las cláusulas WHEN de la instrucción MERGE.The result of this match dictates the actions to take by the WHEN clauses of the MERGE statement. <table_source > puede ser una tabla remota o una tabla derivada que tiene acceso a tablas remotas.<table_source> can be a remote table or a derived table that accesses remote tables.

<table_source > puede ser una tabla derivada que utiliza la Transact-SQLTransact-SQL constructor con valores de tabla para construir una tabla especificando varias filas.<table_source> can be a derived table that uses the Transact-SQLTransact-SQL table value constructor to construct a table by specifying multiple rows.

Para obtener más información sobre la sintaxis y los argumentos de esta cláusula, vea 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>
Especifica las condiciones en la que <table_source > se une con target_table para determinar dónde coinciden.Specifies the conditions on which <table_source> is joined with target_table to determine where they match.

Precaución

Es importante especificar solamente las columnas de la tabla de destino que se utilizan para los propósitos de la coincidencia.It is important to specify only the columns from the target table that are used for matching purposes. Es decir, especifique las columnas de la tabla de destino que se comparan con la correspondiente columna de la tabla de origen.That is, specify columns from the target table that are compared to the corresponding column of the source table. No intente mejorar el rendimiento de las consultas filtrando las filas de la tabla de destino en la cláusula ON, según se especifica con AND NOT target_table.column_x = value.Do not attempt to improve query performance by filtering out rows in the target table in the ON clause, such as by specifying AND NOT target_table.column_x = value. Si se hace esto, se pueden devolver resultados inesperados e incorrectos.Doing so may return unexpected and incorrect results.

Cuando MATCHED THEN <merge_matched >WHEN MATCHED THEN <merge_matched>
Especifica que todas las filas de target_table que coincidan con las filas devueltas por <table_source > ON <merge_search_condition > y satisfacen alguna condición de búsqueda adicional, se actualizan o eliminan según el <merge_matched > cláusula.Specifies that all rows of target_table that 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.

La instrucción MERGE puede tener a lo sumo dos cláusulas WHEN MATCHED.The MERGE statement can have at most two WHEN MATCHED clauses. Si se especifican dos cláusulas, la primera cláusula debe ir acompañada de una operación AND <search_condition > cláusula.If two clauses are specified, then the first clause must be accompanied by an AND <search_condition> clause. Para una fila determinada, la segunda cláusula WHEN MATCHED se aplica solamente si no se aplica la primera.For any given row, the second WHEN MATCHED clause is only applied if the first is not. Si hay dos cláusulas WHEN MATCHED, una debe especificar una acción UPDATE y la otra una acción DELETE.If there are two WHEN MATCHED clauses, then one must specify an UPDATE action and one must specify a DELETE action. Si se especifica UPDATE en el <merge_matched > cláusula y más de una fila de <table_source > coincide con una fila de target_table basado en <merge_search_condition >, SQL ServerSQL Serverdevuelve un error.If 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. La instrucción MERGE no puede actualizar la misma fila más de una vez, ni actualizar o eliminar la misma fila.The MERGE statement cannot update the same row more than once, or update and delete the same row.

Cuando no MATCHED [BY TARGET] THEN <merge_not_matched >WHEN NOT MATCHED [ BY TARGET ] THEN <merge_not_matched>
Especifica que se inserta una fila en target_table para cada fila devuelta por <table_source > ON <merge_search_condition > que no coincide con una fila de target_table, pero satisface una condición de búsqueda adicional, si está presente.Specifies that a row is inserted into target_table for every row returned by <table_source> ON <merge_search_condition> that does not match a row in target_table, but does satisfy an additional search condition, if present. Especifica los valores para insertar el <merge_not_matched > cláusula.The values to insert are specified by the <merge_not_matched> clause. La instrucción MERGE puede tener solamente una cláusula WHEN NOT MATCHED.The MERGE statement can have only one WHEN NOT MATCHED clause.

WHEN NOT MATCHED BY SOURCE, a continuación, <merge_matched >WHEN NOT MATCHED BY SOURCE THEN <merge_matched>
Especifica que todas las filas de target_table que no coincidan con las filas devueltas por <table_source > ON <merge_search_condition >, y que satisfacen alguna condición de búsqueda adicional, se actualizan cualquiera o eliminan según la <merge_matched > cláusula.Specifies that all rows of target_table that do not match the rows returned by <table_source> ON <merge_search_condition>, and that satisfy any additional search condition, are either updated or deleted according to the <merge_matched> clause.

La instrucción MERGE puede tener a lo sumo dos cláusulas WHEN NOT MATCHED BY SOURCE.The MERGE statement can have at most two WHEN NOT MATCHED BY SOURCE clauses. Si se especifican dos cláusulas, la primera cláusula debe ir acompañada de una operación AND <clause_search_condition > cláusula.If two clauses are specified, then the first clause must be accompanied by an AND <clause_search_condition> clause. Para una fila determinada, la segunda cláusula WHEN NOT MATCHED BY SOURCE se aplica solamente si no se aplica la primera.For any given row, the second WHEN NOT MATCHED BY SOURCE clause is only applied if the first is not. Si hay dos cláusulas WHEN NOT MATCHED BY SOURCE, una debe especificar una acción UPDATE y la otra una acción 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. Solo las columnas de la tabla de destino pueden hacer referencia en <clause_search_condition >.Only columns from the target table can be referenced in <clause_search_condition>.

Cuando se devuelve ninguna fila por <table_source >, no se pueden tener acceso a las columnas de la tabla de origen.When no rows are returned by <table_source>, columns in the source table cannot be accessed. Si la acción update o delete especificada en el <merge_matched > cláusula hace referencia a columnas de la tabla de origen, se devuelve el error 207 (nombre de columna no válido).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 cláusula WHEN NOT MATCHED BY SOURCE THEN UPDATE SET TargetTable.Col1 = SourceTable.Col1 puede hacer que la instrucción genere un error porque Col1 en la tabla de origen es inaccesible.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.

Y <clause_search_condition >AND <clause_search_condition>
Especifica cualquier condición de búsqueda válida.Specifies any valid search condition. Para obtener más información, vea condición de búsqueda ( Transact-SQL ) .For more information, see Search Condition (Transact-SQL).

<sugTablaLimit ><table_hint_limited>
Especifica una o más sugerencias de tabla que se aplican en la tabla de destino para cada una de las acciones de inserción, actualización o eliminación que realiza la instrucción MERGE.Specifies one or more table hints that are applied on the target table for each of the insert, update, or delete actions that are performed by the MERGE statement. La palabra clave WITH y los paréntesis son obligatorios.The WITH keyword and the parentheses are required.

No se permiten NOLOCK ni READUNCOMMITTED.NOLOCK and READUNCOMMITTED are not allowed. Para obtener más información acerca de las sugerencias de tabla, vea sugerencias de tabla ( Transact-SQL ) .For more information about table hints, see Table Hints (Transact-SQL).

Especificar la sugerencia TABLOCK en una tabla que es el destino de una instrucción INSERT tiene el mismo efecto que especificar la sugerencia TABLOCKX.Specifying the TABLOCK hint on a table that is the target of an INSERT statement has the same effect as specifying the TABLOCKX hint. Se realiza un bloqueo exclusivo en la tabla.An exclusive lock is taken on the table. Cuando se especifica FORCESEEK, se aplica a la instancia implícita de la tabla de destino combinada con la tabla de origen.When FORCESEEK is specified, it is applied to the implicit instance of the target table joined with the source table.

Precaución

Si se especifica READPAST con WHEN NOT MATCHED [ BY TARGET ] THEN INSERT, pueden producirse operaciones INSERT que infrinjan las restricciones 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 ] )
Especifica el nombre o identificador de uno o más índices de la tabla de destino para realizar una combinación implícita con la tabla de origen.Specifies the name or ID of one or more indexes on the target table for performing an implicit join with the source table. Para obtener más información, vea Sugerencias de tabla (Transact-SQL).For more information, see Table Hints (Transact-SQL).

<output_clause ><output_clause>
Devuelve una fila para cada fila de target_table que se actualiza, inserta o elimina, sin ningún orden determinado.Returns a row for every row in target_table that is updated, inserted, or deleted, in no particular order. $action se puede especificar en la cláusula output.$action can be specified in the output clause. $action es una columna de tipo nvarchar (10) que devuelve uno de estos tres valores para cada fila: 'INSERT', 'UPDATE' o 'DELETE', según la acción que se realizó en esa fila.$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 that was performed on that row. Para obtener más información acerca de los argumentos de esta cláusula, vea cláusula OUTPUT ( Transact-SQL ) .For more information about the arguments of this clause, see OUTPUT Clause (Transact-SQL).

OPCIÓN ( <query_hint > [,.. .n])OPTION ( <query_hint> [ ,...n ] )
Especifica que se utilizan las sugerencias del optimizador para personalizar el modo en que el motor de base de datos procesa la instrucción.Specifies that optimizer hints are used to customize the way the Database Engine processes the statement. Para obtener más información, vea Sugerencias de consulta (Transact-SQL).For more information, see Query Hints (Transact-SQL).

<merge_matched ><merge_matched>
Especifica la actualización o eliminación de la acción que se aplica a todas las filas de target_table que no coincidan con las filas devueltas por <table_source > ON <merge_search_condition >, y que cumplen alguna condición de búsqueda adicional.Specifies the update or delete action that is applied to all rows of target_table that do not match the rows returned by <table_source> ON <merge_search_condition>, and that satisfy any additional search condition.

UPDATE configurado <set_clause >UPDATE SET <set_clause>
Especifica la lista de nombres de columna o de variable que se van a actualizar en la tabla de destino y los valores con los que se actualizan.Specifies the list of column or variable names to be updated in the target table and the values with which to update them.

Para obtener más información acerca de los argumentos de esta cláusula, vea actualización ( Transact-SQL ) .For more information about the arguments of this clause, see UPDATE (Transact-SQL). No se puede establecer una variable con el mismo valor que una columna.Setting a variable to the same value as a column is not permitted.

DELETEDELETE
Especifica que las filas que coinciden con filas de target_table se eliminan.Specifies that the rows matching rows in target_table are deleted.

<merge_not_matched ><merge_not_matched>
Especifica los valores que insertar en la tabla de destino.Specifies the values to insert into the target table.

(column_list)(column_list)
Es una lista de una o varias columnas de la tabla de destino en la que insertar los datos.Is a list of one or more columns of the target table in which to insert data. Las columnas se deben especificar como un nombre de una sola parte o, de lo contrario, se producirá un error en la instrucción MERGE.Columns must be specified as a single-part name or else the MERGE statement will fail. column_list debe incluir entre paréntesis y delimitarse mediante comas.column_list must be enclosed in parentheses and delimited by commas.

VALORES ( listaValores)VALUES ( values_list)
Es una lista separada por comas de constantes, variables o expresiones que devuelve los valores que se insertarán en la tabla de destino.Is a comma-separated list of constants, variables, or expressions that return values to insert into the target table. Las expresiones no pueden contener una instrucción EXECUTE.Expressions cannot contain an EXECUTE statement.

DEFAULT VALUESDEFAULT VALUES
Hace que la fila insertada contenga los valores predeterminados definidos para cada columna.Forces the inserted row to contain the default values defined for each column.

Para obtener más información acerca de esta cláusula, vea INSERT ( Transact-SQL ) .For more information about this clause, see INSERT (Transact-SQL).

<condición de búsqueda ><search condition>
Especifica las condiciones de búsqueda que se utiliza para especificar <merge_search_condition > o <clause_search_condition >.Specifies the search conditions used to specify <merge_search_condition> or <clause_search_condition>. Para obtener más información acerca de los argumentos para esta cláusula, vea condición de búsqueda ( Transact-SQL ) .For more information about the arguments for this clause, see Search Condition (Transact-SQL).

ComentariosRemarks

Al menos se debe especificar una de las tres cláusulas MATCHED, pero se pueden especificar en cualquier orden.At least one of the three MATCHED clauses must be specified, but they can be specified in any order. Una variable no puede actualizarse más de una vez en la misma cláusula MATCHED.A variable cannot be updated more than once in the same MATCHED clause.

Cualquier acción de inserción, actualización o eliminación especificada en la tabla de destino por la instrucción MERGE está limitada por las restricciones definidas en ella, incluidas las restricciones de integridad referencial en cascada.Any insert, update, or delete actions specified on the target table by the MERGE statement are limited by any constraints defined on it, including any cascading referential integrity constraints. Si IGNORE_DUP_KEY se establece en ON para algún índice único de la tabla de destino, MERGE omite este valor.If IGNORE_DUP_KEY is set to ON for any unique indexes on the target table, MERGE ignores this setting.

La instrucción MERGE requiere un punto y coma (;) como terminador.The MERGE statement requires a semicolon (;) as a statement terminator. Se genera el error 10713 cuando una instrucción MERGE se ejecuta sin el terminador.Error 10713 is raised when a MERGE statement is run without the terminator.

Cuando se utiliza después de la mezcla, @@ROWCOUNT ( Transact-SQL ) devuelve el número total de filas insertadas, actualizadas y eliminadas al cliente.When used after MERGE, @@ROWCOUNT (Transact-SQL) returns the total number of rows inserted, updated, and deleted to the client.

MERGE es una palabra clave totalmente reservada cuando el nivel de compatibilidad de la base de datos se establece en 100 o superior.MERGE is a fully reserved keyword when the database compatibility level is set to 100 or higher. La instrucción MERGE también está disponible en los niveles de compatibilidad 90 y 100 de la base de datos; sin embargo, la palabra clave no se reserva completamente cuando el nivel de compatibilidad se establece en 90.The MERGE statement is available under both 90 and 100 database compatibility levels; however the keyword is not fully reserved when the database compatibility level is set to 90.

El mezcla instrucción no debe usarse al utilizar la replicación de actualización en cola.The MERGE statement should not be used when using queued updating replication. El mezcla y desencadenador de actualización en cola no son compatibles.The MERGE and queued updating trigger are not compatible. Reemplace el mezcla instrucción con una instrucción insert o una instrucción update.Replace the MERGE statement with an insert or an update statement.

Implementación de desencadenadoresTrigger Implementation

Para cada acción de inserción, actualización o eliminación especificada en la instrucción MERGE, SQL ServerSQL Server activa los desencadenadores AFTER correspondientes definidos en la tabla de destino, pero no garantiza qué acción activará los desencadenadores primero o último.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 does not guarantee on which action to fire triggers first or last. Los desencadenadores definidos para la misma acción cumplen el orden que especifique.Triggers defined for the same action honor the order you specify. Para obtener más información acerca de cómo establecer el orden de activación de los desencadenadores, vea especificar primero y último desencadenadores.For more information about setting trigger firing order, see Specify First and Last Triggers.

Si la tabla de destino tiene habilitado un desencadenador INSTEAD OF definido en ella para una acción de inserción, actualización o eliminación realizada por una instrucción MERGE, debe tener habilitado un desencadenador INSTEAD OF para todas las acciones especificadas en la instrucción MERGE.If the target table has an enabled INSTEAD OF trigger defined on it for an insert, update, or delete action performed by a MERGE statement, then it must have an enabled INSTEAD OF trigger for all of the actions specified in the MERGE statement.

Si hay INSTEAD OF UPDATE o definir desencadenadores INSTEAD OF DELETE en target_table, no se realizan las operaciones update o delete.If there are any INSTEAD OF UPDATE or INSTEAD OF DELETE triggers defined on target_table, the update or delete operations are not performed. En su lugar, se activan los desencadenadores y la insertar y eliminado tablas se rellenan en consecuencia.Instead, the triggers fire and the inserted and deleted tables are populated accordingly.

Si hay alguna en lugar de desencadenadores de INSERCIÓN definidos en target_table, no se realiza la operación de inserción.If there are any INSTEAD OF INSERT triggers defined on target_table, the insert operation is not performed. En su lugar, se activan los desencadenadores y la insertar tabla se rellena en consecuencia.Instead, the triggers fire and the inserted table is populated accordingly.

PermissionsPermissions

Requiere el permiso SELECT en la tabla de origen y los permisos INSERT, UPDATE o DELETE en la tabla de destino.Requires SELECT permission on the source table and INSERT, UPDATE, or DELETE permissions on the target table. Para obtener más información, vea la sección de permisos en el seleccione, insertar, actualización, y eliminar temas.For additional information, see the Permissions section in the SELECT, INSERT, UPDATE, and DELETE topics.

EjemplosExamples

A.A. Usar MERGE para realizar operaciones INSERT y UPDATE en una tabla en una sola instrucciónUsing MERGE to perform INSERT and UPDATE operations on a table in a single statement

Un escenario común es la actualización de una o varias columnas de una tabla si una fila coincidente existe, o la inserción de datos como una fila nueva si no existe ninguna fila coincidente.A common scenario is updating one or more columns in a table if a matching row exists, or inserting the data as a new row if a matching row does not exist. Normalmente, para hacer esto se pasan los parámetros a un procedimiento almacenado que contiene las instrucciones INSERT y UPDATE adecuadas.This is usually done by passing parameters to a stored procedure that contains the appropriate UPDATE and INSERT statements. Con la instrucción MERGE puede realizar ambas tareas en una sola instrucción.With the MERGE statement, you can perform both tasks in a single statement. En el ejemplo siguiente se muestra un procedimiento almacenado de la base de datos AdventureWorks2012AdventureWorks2012 que contiene una instrucción INSERT y una instrucción UPDATE.The following example shows a stored procedure in the AdventureWorks2012AdventureWorks2012database that contains both an INSERT statement and an UPDATE statement. A continuación, el procedimiento se modifica para realizar las operaciones equivalentes utilizando una sola instrucción MERGE.The procedure is then modified to perform 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. Usar MERGE para realizar operaciones UPDATE y DELETE en una tabla en una sola instrucciónUsing MERGE to perform UPDATE and DELETE operations on a table in a single statement

En el siguiente ejemplo se usa MERGE para actualizar diariamente la tabla ProductInventory de la base de datos de ejemplo AdventureWorks2012AdventureWorks2012, en función de los pedidos procesados en la tabla SalesOrderDetail.The following example uses MERGE to update the ProductInventory table in the AdventureWorks2012AdventureWorks2012 sample database on a daily basis, based on orders that are processed in the SalesOrderDetail table. La columna Quantity de la tabla ProductInventory se actualiza restando el número de pedidos realizados cada día para cada producto de la tabla 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. Si el número de pedidos de un producto baja el nivel de inventario del mismo hasta 0 o un valor menor, la fila correspondiente a ese producto se elimina de la tabla 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. Usar MERGE para realizar operaciones INSERT y UPDATE en una tabla de destino mediante una tabla de origen derivadaUsing MERGE to perform UPDATE and INSERT operations on a target table by using a derived source table

En el ejemplo siguiente se usa MERGE para modificar la tabla SalesReason de la base de datos AdventureWorks2012AdventureWorks2012, actualizando o insertando las filas.The following example uses MERGE to modify the SalesReason table in the AdventureWorks2012AdventureWorks2012 database by either updating or inserting rows. Cuando el valor de NewName de la tabla de origen coincide con un valor de la columna Name de la tabla de destino, (SalesReason), la columna ReasonType se actualiza en la tabla de destino.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. Cuando el valor de NewName no coincide, la fila del origen se inserta en la tabla de destino.When the value of NewName does not match, the source row is inserted into the target table. La tabla de origen es una tabla derivada que usa la característica de constructor con valores de tabla de Transact-SQLTransact-SQL para especificar varias filas en la tabla de origen.The source table is a derived table that uses the Transact-SQLTransact-SQL table value constructor to specify multiple rows for the source table. Para obtener más información acerca de cómo utilizar el constructor con valores de tabla en una tabla derivada, vea Constructor con valores de tabla ( Transact-SQL ) .For more information about using the table value constructor in a derived table, see Table Value Constructor (Transact-SQL). El ejemplo también muestra cómo almacenar los resultados de la cláusula OUTPUT en una variable de tabla y, a continuación, resumir los resultados de la instrucción MERGE realizando una sencilla operación SELECT que devuelve el recuento de las filas insertadas y actualizadas.The example also shows how to store the results of the OUTPUT clause in a table variable and then summarize the results of the MERGE statment by performing 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. Insertar los resultados de la instrucción MERGE en otra tablaInserting the results of the MERGE statement into another table

En el ejemplo siguiente se capturan los datos devueltos por la cláusula OUTPUT de una instrucción MERGE y se insertan en otra tabla.The following example captures data returned from the OUTPUT clause of a MERGE statement and inserts that data into another table. La instrucción MERGE actualiza diariamente la columna Quantity de la tabla ProductInventory de la base de datos AdventureWorks2012AdventureWorks2012, en función de los pedidos procesados en la tabla 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. En el ejemplo se capturan las filas actualizadas y se insertan en otra tabla que se usa para realizar el seguimiento de los cambios del inventario.The example captures the rows that are updated and inserts them into another table that is 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  

Vea tambiénSee Also

SELECT (Transact-SQL) SELECT (Transact-SQL)
INSERT (Transact-SQL) INSERT (Transact-SQL)
UPDATE (Transact-SQL) UPDATE (Transact-SQL)
DELETE (Transact-SQL) DELETE (Transact-SQL)
Cláusula OUTPUT ( Transact-SQL ) OUTPUT Clause (Transact-SQL)
MERGE en paquetes Integration Services MERGE in Integration Services Packages
FROM (Transact-SQL) FROM (Transact-SQL)
Constructor con valores de tabla ( Transact-SQL )Table Value Constructor (Transact-SQL)