Recherche…


Introduction

À partir de SQL Server 2008, il est possible d'effectuer des opérations d'insertion, de mise à jour ou de suppression dans une seule instruction à l'aide de l'instruction MERGE.

L'instruction MERGE vous permet de joindre une source de données avec une table ou une vue cible, puis d'effectuer plusieurs actions sur la cible en fonction des résultats de cette jointure.

Syntaxe

  • Selon MSDN - https://msdn.microsoft.com/en-us/library/bb510625.aspx [AVEC <common_table_expression> [, ... n]] MERGE [TOP (expression) [POURCENT]] [INTO] < target_table> [WITH (<merge_hint>)] [[AS] table_alias] UTILISATION <table_source> ON <merge_search_condition> [QUAND CORRIGÉ [ET <clause_search_condition>] THEN <merge_matched>] [... n] CIBLE] [ET <clause_search_condition>] THEN <merge_not_matched>] [QUAND N'EST PAS CORRESPONDANT PAR SOURCE [ET <clause_search_condition>] ALORS <merge_matched>] [... n] [<output_clause>] [OPTION (<query_hint> [,. ..n])]; <target_table> :: = {[nom_bdd. nom_schéma | nom_schéma ] target_table} <merge_hint> :: = {{[<table_hint_limited> [, ... n]] [[,] INDEX (index_val [, ... n])]}} <table_source> :: = {table_ou_nom_view [ [AS] table_alias] [<tableample_clause>] [WITH (table_hint [[,] ... n])] | rowset_function [[AS] table_alias] [(bulk_column_alias [, ... n])] | user_defined_function [[AS] table_alias] | OPENXML <openxml_clause> | dérivée_table [AS] alias_table [(alias_colonne [, ... n])] | <rejoindre_table> | <pivoted_table> | <tablepivoted_table>} <merge_search_condition> :: = <search_condition> <merge_matched> :: = {UPDATE SET <set_clause> | DELETE} <set_clause> :: = SET {nom_colonne = {expression | DÉFAUT | NULL} | {udt_column_name. {{property_name = expression | field_name = expression} | method_name (argument [, ... n])}} | nom_colonne {.WRITE (expression, @Offset, @Length)} | @variable = expression | @variable = colonne = expression | nom_colonne {+ = | - = | * = | / = | % = | & = | ^ = | | =} expression | @ variable {+ = | - = | * = | / = | % = | & = | ^ = | | =} expression | @variable = colonne {+ = | - = | * = | / = | % = | & = | ^ = | | =} expression} [, ... n] <merge_not_matched> :: = {INSERT [(column_list)] {VALUES (values_list) | VALEURS PAR DÉFAUT}} <clause_search_condition> :: = <search_condition> :: = {[NOT] | (<condition_recherche>)} [{ET | OU} [NOT] {| (<search_condition>)}] [, ... n] :: = {expression {= | <> | ! = |

    | > = | ! > | <| <= | ! <} expression | expression_chaîne [NOT] LIKE expression_chaîne [ESCAPE 'escape_character'] | expression [NOT] BETWEEN expression AND expression | expression IS [NOT] NULL | CONTAINS ({column | *}, '<contains_search_condition>') | FREETEXT ({colonne | *}, 'freetext_string') | expression [NOT] IN (sous-requête | expression [, ... n]) | expression {= | <> | ! = | | > = | ! > | <| <= | ! <} {TOUS | QUEL | ANY} (sous-requête) | EXISTS (sous-requête)} <output_clause> :: = {[OUTPUT <dml_select_list> INTO {@table_variable | output_table} [(column_list)]] [OUTPUT <dml_select_list>]} <dml_select_list> :: = {<nom_colonne> | expression_ scalaire} [[AS] identifiant_alias_colonne] [, ... n] <nom_colonne> :: = {SUPPRIMÉ | INSÉRÉ | from_table_name}. {* | nom_colonne} | $ action

Remarques

Effectue des opérations d'insertion, de mise à jour ou de suppression sur une table cible en fonction des résultats d'une jointure avec une table source. Par exemple, vous pouvez synchroniser deux tables en insérant, en mettant à jour ou en supprimant des lignes dans une table en fonction des différences trouvées dans l'autre table.

MERGE to Insert / Update / Delete

MERGE INTO targetTable

USING sourceTable 
ON (targetTable.PKID = sourceTable.PKID)

WHEN MATCHED AND (targetTable.PKID > 100) THEN
    DELETE

WHEN MATCHED AND (targetTable.PKID <= 100) THEN 
    UPDATE SET 
        targetTable.ColumnA = sourceTable.ColumnA, 
        targetTable.ColumnB = sourceTable.ColumnB

WHEN NOT MATCHED THEN
    INSERT (ColumnA, ColumnB) VALUES (sourceTable.ColumnA, sourceTable.ColumnB);

WHEN NOT MATCHED BY SOURCE THEN
    DELETE
; --< Required

La description:

  • MERGE INTO targetTable - table à modifier
  • USING sourceTable - source de données (peut être une table, une vue ou une fonction de table)
  • ON ... - joint la condition entre targetTable et sourceTable .
  • WHEN MATCHED - actions à entreprendre lorsqu'une correspondance est trouvée
    • AND (targetTable.PKID > 100) - condition (s) supplémentaire (s) à satisfaire pour que l'action soit effectuée
  • THEN DELETE - supprime l'enregistrement correspondant de la targetTable
  • THEN UPDATE - met à jour les colonnes de l'enregistrement correspondant spécifié par SET ....
  • WHEN NOT MATCHED - actions à entreprendre lorsque la correspondance est introuvable dans targetTable
  • WHEN NOT MATCHED BY SOURCE - actions à entreprendre lorsque la correspondance est introuvable dans sourceTable

Commentaires:

Si une action spécifique n'est pas nécessaire, omettez la condition, par exemple en supprimant WHEN NOT MATCHED THEN INSERT empêchera l'insertion des enregistrements.

L'instruction de fusion nécessite un point-virgule de terminaison.

Restrictions:

  • WHEN MATCHED n'autorise pas l'action INSERT
  • UPDATE action UPDATE ne peut mettre à jour une ligne qu'une seule fois. Cela implique que la condition de jointure doit produire des correspondances uniques.

Fusion à l'aide de la source CTE

WITH SourceTableCTE AS
(
    SELECT * FROM SourceTable
)
MERGE  
 TargetTable AS target
USING SourceTableCTE AS source  
ON (target.PKID = source.PKID)
WHEN MATCHED THEN     
    UPDATE SET target.ColumnA = source.ColumnA
WHEN NOT MATCHED THEN
    INSERT (ColumnA) VALUES (Source.ColumnA);

FUSIONNER en utilisant la table source dérivée

MERGE INTO TargetTable  AS Target  
USING (VALUES (1,'Value1'), (2, 'Value2'), (3,'Value3'))  
       AS Source (PKID, ColumnA)  
ON Target.PKID = Source.PKID 
WHEN MATCHED THEN 
    UPDATE SET target.ColumnA= source.ColumnA
WHEN NOT MATCHED THEN
    INSERT (PKID, ColumnA) VALUES (Source.PKID, Source.ColumnA);

Exemple de fusion - Synchroniser la table source et cible

Pour illustrer l'instruction MERGE, considérez les deux tableaux suivants:

  1. dbo.Product : Ce tableau contient des informations sur le produit vendu par cette société

  2. dbo.ProductNew : Ce tableau contient des informations sur le produit que la société vendra ultérieurement.

Le T-SQL suivant créera et remplira ces deux tables

IF OBJECT_id(N'dbo.Product',N'U') IS NOT NULL 
DROP TABLE dbo.Product
GO

CREATE TABLE dbo.Product (
ProductID INT PRIMARY KEY,
ProductName NVARCHAR(64),
PRICE MONEY
)

IF OBJECT_id(N'dbo.ProductNew',N'U') IS NOT NULL 
DROP TABLE dbo.ProductNew
GO

CREATE TABLE dbo.ProductNew (
ProductID INT PRIMARY KEY,
ProductName NVARCHAR(64),
PRICE MONEY
)

INSERT INTO dbo.Product VALUES(1,'IPod',300)
,(2,'IPhone',400)
,(3,'ChromeCast',100)
,(4,'raspberry pi',50)

INSERT INTO dbo.ProductNew VALUES(1,'Asus Notebook',300)
,(2,'Hp Notebook',400)
,(3,'Dell Notebook',100)
,(4,'raspberry pi',50)

Maintenant, supposons que nous voulions synchroniser la table cible dbo.Product avec la table dbo.ProductNew. Voici le critère pour cette tâche:

  1. Les produits existant dans la table source dbo.ProductNew et la table cible dbo.Product sont mis à jour dans la table cible dbo.Product avec les nouveaux nouveaux produits.

  2. Tout produit de la table source dbo.ProductNew qui n'existe pas dans la table cible dob.Product est inséré dans la table cible dbo.Product.

  3. Tout produit de la table cible dbo.Product qui n'existe pas dans la table source dbo.ProductNew doit être supprimé de la table cible dbo.Product. Voici l'instruction MERGE pour effectuer cette tâche.

MERGE dbo.Product AS SourceTbl 
USING dbo.ProductNew AS TargetTbl ON (SourceTbl.ProductID = TargetTbl.ProductID)
WHEN MATCHED 
            AND SourceTbl.ProductName <> TargetTbl.ProductName
            OR SourceTbl.Price <> TargetTbl.Price
    THEN UPDATE SET SourceTbl.ProductName = TargetTbl.ProductName,
                SourceTbl.Price = TargetTbl.Price
WHEN NOT MATCHED 
    THEN INSERT (ProductID, ProductName, Price)
         VALUES (TargetTbl.ProductID, TargetTbl.ProductName, TargetTbl.Price)
WHEN NOT MATCHED BY SOURCE 
    THEN DELETE
OUTPUT $action, INSERTED.*, DELETED.*;

Remarque: Le point-virgule doit être présent à la fin de l'instruction MERGE. entrer la description de l'image ici

Fusionner en utilisant sauf

Utilisez EXCEPT pour empêcher les mises à jour des enregistrements inchangés

MERGE TargetTable targ
USING SourceTable AS src
    ON src.id = targ.id
WHEN MATCHED
    AND EXISTS (
        SELECT src.field
        EXCEPT
        SELECT targ.field
        )
    THEN
        UPDATE
        SET field = src.field
WHEN NOT MATCHED BY TARGET
    THEN
        INSERT (
            id
            ,field
            )
        VALUES (
            src.id
            ,src.field
            )
WHEN NOT MATCHED BY SOURCE
    THEN
        DELETE;


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow