Microsoft SQL Server
FUSIONNER
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 entretargetTable
etsourceTable
. -
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 latargetTable
-
THEN UPDATE
- met à jour les colonnes de l'enregistrement correspondant spécifié parSET ....
-
WHEN NOT MATCHED
- actions à entreprendre lorsque la correspondance est introuvable danstargetTable
-
WHEN NOT MATCHED BY SOURCE
- actions à entreprendre lorsque la correspondance est introuvable danssourceTable
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'actionINSERT
-
UPDATE
actionUPDATE
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:
dbo.Product : Ce tableau contient des informations sur le produit vendu par cette société
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:
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.
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.
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.
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;