Suche…


Einführung

Beginnend mit SQL Server 2008 ist es möglich, Einfüge-, Aktualisierungs- oder Löschvorgänge in einer einzelnen Anweisung mithilfe der MERGE-Anweisung auszuführen.

Mit der MERGE-Anweisung können Sie eine Datenquelle mit einer Zieltabelle oder -sicht verknüpfen und dann basierend auf den Ergebnissen dieses Joins mehrere Aktionen für das Ziel ausführen.

Syntax

  • Gemäß MSDN - https://msdn.microsoft.com/en-us/library/bb510625.aspx [WITH <common_table_expression> [, ... n]] MERGE [TOP (Ausdruck) [PERCENT]] [INTO] < target_table> [WITH (<merge_hint>)] [[AS] table_alias] USING <table_source> ON <merge_search_condition> [WHEN MATCHED [AND <Klausel_search_condition>] THEN <merge_matched>] [... n] [WENN NICHT ÜBEREINSTIMMT [] TARGET] [AND <clause_search_condition>] THEN <merge_not_matched>] [WENN NICHT MIT QUELLE [UND <clause_search_condition>] DANN <merge_matched>] [... n] [<output_clause>] [OPTION (<query_hint>]). ..n])]; <target_table> :: = {[Datenbankname]. 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> | abgeleitete_Tabelle [AS] table_alias [(column_alias [, ... n])] | <join_table> | <pivoted_table> | <unpivoted_table>} <merge_search_condition> :: = <suchbedingung> <merge_matched> :: = {UPDATE SET <set_clause> | DELETE} <set_clause> :: = SET {Spaltenname = {Ausdruck | STANDARD | NULL} | {udt_column_name. {{property_name = Ausdruck | Feldname = Ausdruck} | Methodenname (Argument [, ... n])}} | Spaltenname {.WRITE (Ausdruck, @Offset, @Length)} | @variable = Ausdruck | @variable = Spalte = Ausdruck | Spaltenname {+ = | - = | * = | / = | % = | & = | ^ = | | =} Ausdruck | @variable {+ = | - = | * = | / = | % = | & = | ^ = | | =} Ausdruck | @variable = Spalte {+ = | - = | * = | / = | % = | & = | ^ = | | =} Ausdruck} [, ... n] <merge_not_matched> :: = {INSERT [(Spaltenliste)] {VALUES (Werte_Liste) | DEFAULT VALUES}} <clause_search_condition> :: = <search_condition> :: = {[NOT] | (<Suchbedingung>)} [{AND | ODER} [NICHT] {| (<Suchbedingung>)}] [, ... n] :: = {Ausdruck {= | <> | ! = |

    | > = | ! > | <| <= | ! <} Ausdruck | Zeichenfolgenausdruck [NOT] LIKE Zeichenfolgenausdruck [ESCAPE 'escape_character'] | Ausdruck [NICHT] ZWISCHEN Ausdruck UND Ausdruck | Ausdruck IST [NICHT] NULL | CONTAINS ({column | *}, '<contains_search_condition>') | FREETEXT ({column | *}, 'freetext_string') | Ausdruck [NOT] IN (Unterabfrage | Ausdruck [, ... n]) | Ausdruck {= | <> | ! = | | > = | ! > | <| <= | ! <} {ALL | EINIGE | ANY} (Unterabfrage) | EXISTS (Unterabfrage)} <output_clause> :: = {[OUTPUT <dml_select_list> INTO {@table_variable | output_table} [(column_list)]] [OUTPUT <dml_select_list>]} <dml_select_list> :: = {<spaltenname> | scalar_expression} [[AS] column_alias_identifier] [, ... n] <spaltenname> :: = {DELETED | INSERTED | from_table_name}. {* | Spaltenname} | $ action

Bemerkungen

Führt Einfüge-, Aktualisierungs- oder Löschvorgänge für eine Zieltabelle aus, basierend auf den Ergebnissen eines Joins mit einer Quelltabelle. Sie können beispielsweise zwei Tabellen synchronisieren, indem Sie Zeilen in einer Tabelle basierend auf den in der anderen Tabelle gefundenen Unterschieden einfügen, aktualisieren oder löschen.

MERGE zum Einfügen / Aktualisieren / Löschen

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

Beschreibung:

  • MERGE INTO targetTable - zu MERGE INTO targetTable Tabelle
  • USING sourceTable - Datenquelle (kann eine Tabelle oder eine Ansicht oder eine Funktion mit Tabellenwert sein)
  • ON ... - Join-Bedingung zwischen targetTable und sourceTable .
  • WHEN MATCHED - Aktionen, die ausgeführt werden sollen, wenn eine Übereinstimmung gefunden wird
    • AND (targetTable.PKID > 100) - zusätzliche Bedingung (en), die erfüllt sein müssen, damit die Aktion ausgeführt werden kann
  • THEN DELETE - Löscht den übereinstimmenden Datensatz aus der targetTable
  • THEN UPDATE - Aktualisieren Sie die Spalten des übereinstimmenden Datensatzes, der mit SET .... angegeben wurde SET ....
  • WHEN NOT MATCHED - Aktionen, die ausgeführt werden sollen, wenn in targetTable keine Übereinstimmung gefunden targetTable
  • WHEN NOT MATCHED BY SOURCE - Aktionen, die ausgeführt werden sollen, wenn keine sourceTable in sourceTable

Bemerkungen:

Wenn eine bestimmte Aktion nicht erforderlich ist, lassen Sie die Bedingung aus, z. B. das Entfernen von WHEN NOT MATCHED THEN INSERT verhindert, dass Datensätze eingefügt werden

Merge-Anweisung erfordert ein abschließendes Semikolon.

Beschränkungen:

  • WHEN MATCHED erlaubt keine INSERT Aktion
  • UPDATE Aktion UPDATE kann eine Zeile nur einmal aktualisieren. Dies bedeutet, dass die Join-Bedingung eindeutige Übereinstimmungen erzeugen muss.

Mit CTE-Quelle zusammenführen

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);

MERGE mithilfe der abgeleiteten Quelltabelle

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);

Zusammenführungsbeispiel - Quelle und Zieltabelle synchronisieren

Beachten Sie zur Veranschaulichung der MERGE-Anweisung die folgenden zwei Tabellen:

  1. dbo.Product : Diese Tabelle enthält Informationen zu dem Produkt, das das Unternehmen derzeit verkauft

  2. dbo.ProductNew : Diese Tabelle enthält Informationen über das Produkt, das das Unternehmen zukünftig verkaufen wird.

Das folgende T-SQL erstellt diese beiden Tabellen und füllt sie auf

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)

Nehmen wir an, wir wollen die Tabelle dbo.Product Target mit der Tabelle dbo.ProductNew synchronisieren. Hier ist das Kriterium für diese Aufgabe:

  1. Produkte, die sowohl in der Quelltabelle dbo.ProductNew als auch in der Zieltabelle dbo.Product vorhanden sind, werden in der Zieltabelle dbo.Product mit neuen neuen Produkten aktualisiert.

  2. Alle Produkte in der dbo.ProductNew-Quelltabelle, die nicht in der Zieltabelle dob.Product enthalten sind, werden in die Zieltabelle dbo.Product eingefügt.

  3. Jedes Produkt in der Zieltabelle dbo.Product, das nicht in der Quelltabelle dbo.ProductNew vorhanden ist, muss aus der Zieltabelle dbo.Product gelöscht werden. Hier ist die MERGE-Anweisung, um diese Aufgabe auszuführen.

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.*;

Hinweis: Das Semikolon muss am Ende der MERGE-Anweisung stehen. Geben Sie hier die Bildbeschreibung ein

Zusammenführen mit EXCEPT

Verwenden Sie EXCEPT, um Aktualisierungen an unveränderten Datensätzen zu verhindern

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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow