Microsoft SQL Server
ŁĄCZYĆ
Szukaj…
Wprowadzenie
Począwszy od SQL Server 2008 można wykonywać operacje wstawiania, aktualizacji lub usuwania w pojedynczej instrukcji za pomocą instrukcji MERGE.
Instrukcja MERGE pozwala dołączyć do źródła danych z docelową tabelą lub widokiem, a następnie wykonać wiele działań przeciwko celowi na podstawie wyników tego połączenia.
Składnia
- Zgodnie z MSDN - https://msdn.microsoft.com/en-us/library/bb510625.aspx [Z <wyrażenie_tabela_tabeli> [, ... n]] POŁĄCZ [TOP (wyrażenie) [PERCENT]] [INTO] < tabela_cel> TARGET] [AND <clause_search_condition>] THEN <merge_not_matched>] [GDY NIE DOPASOWANE PRZEZ ŹRÓDŁO [ORAZ <clause_search_condition>] THEN <merge_matched>] [... n] [<putput_clause>] [OPTION (<query_hint>]. ..n])]; <target_table> :: = {[nazwa_bazy_danych. nazwa_schematu. | nazwa_schematu. ] 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 <klucz open_ml> pochodna_tabela [AS] tabela_alias [(kolumna_alias [, ... n])] | <joined_table> | <pivoted_table> | <podprzedstawiona_tabela>} <merge_search_condition> :: = <search_condition> <merge_matched> :: = {UPDATE SET <set_clause> | DELETE} <klucz_zestawu> :: = SET {nazwa_kolumny = {wyrażenie | DOMYŚLNE | NULL} | {udt_column_name. {{property_name = wyrażenie | nazwa_pola = wyrażenie} | nazwa_metody (argument [, ... n])}} | nazwa_kolumny {.WRITE (wyrażenie, @Offset, @Length)} | @variable = wyrażenie | @variable = column = expression | nazwa_kolumny {+ = | - = | * = | / = | % = | & = | ^ = | | =} wyrażenie | @variable {+ = | - = | * = | / = | % = | & = | ^ = | | =} wyrażenie | @variable = kolumna {+ = | - = | * = | / = | % = | & = | ^ = | | =} wyrażenie} [, ... n] <merge_not_matched> :: = {INSERT [(lista_kolumn)] {WARTOŚCI (lista_wartości) | WARTOŚCI DOMYŚLNE}} <clause_search_condition> :: = <search_condition> :: = {[NOT] | (<warunek_wyszukiwania>)} [{AND | LUB} [NIE] {| (<warunek_wyszukiwania>)}] [, ... n] :: = {wyrażenie {= | <> | ! = |
| > = | ! > | <| <= | ! <} wyrażenie | wyrażenie_łańcuchowe [NIE] LIKE wyrażenie_łańcuchowe [ESCAPE 'escape_character'] | wyrażenie [NIE] MIĘDZY wyrażeniem I wyrażeniem | wyrażenie IS [NOT] NULL | ZAWIERA ({kolumna | *}, „<zawiera warunek_wyszukiwania>”) | FREETEXT ({kolumna | *}, „freetext_string”) | wyrażenie [NOT] IN (podzapytanie | wyrażenie [, ... n]) | wyrażenie {= | <> | ! = | | > = | ! > | <| <= | ! <} {WSZYSTKO | NIEKTÓRE | DOWOLNY} (podzapytanie) | ISTNIEJE (podzapytanie)} <klucz_wyjściowy> :: = {[WYJŚCIE <lista_wybranych_dml> INTO {@ zmienna_tabeli | tabela_wyjściowa} [(lista_kolumn)]] [WYJŚCIE <lista_wybranych_dml>]} <lista_wybranych_dml> :: = {<nazwa_kolumny> | scalar_expression} [[AS] identyfikator_kolumny kolumny] [, ... n] <nazwa_kolumny> :: = {USUNIĘTO | WSTAWIONE | from_table_name}. {* | nazwa_kolumny} | $ akcja
Uwagi
Wykonuje operacje wstawiania, aktualizacji lub usuwania tabeli docelowej na podstawie wyników łączenia z tabelą źródłową. Na przykład możesz zsynchronizować dwie tabele, wstawiając, aktualizując lub usuwając wiersze w jednej tabeli na podstawie różnic znalezionych w drugiej tabeli.
ŁĄCZ, aby wstawić / zaktualizować / usunąć
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
Opis:
-
MERGE INTO targetTable
do tabeliMERGE INTO targetTable
- tabela do modyfikacji -
USING sourceTable
- źródło danych (może to być tabela lub widok lub funkcja wyceniana w tabeli) -
ON ...
- warunek dołączenia międzytargetTable
isourceTable
. -
WHEN MATCHED
- działania, które należy podjąć po znalezieniu dopasowania -
AND (targetTable.PKID > 100)
- dodatkowe warunki, które muszą zostać spełnione, aby można było podjąć działanie
-
-
THEN DELETE
- usuń dopasowany rekord ztargetTable
-
THEN UPDATE
- zaktualizuj kolumny dopasowanego rekordu określonego przezSET ....
-
WHEN NOT MATCHED
- działania, które należy podjąć, gdy dopasowanie nie zostanie znalezione wtargetTable
-
WHEN NOT MATCHED BY SOURCE
- działania, które należy podjąć, gdy dopasowanie nie zostanie znalezione wsourceTable
Komentarze:
Jeśli określone działanie nie jest potrzebne, pomiń warunek, np. Usunięcie WHEN NOT MATCHED THEN INSERT
zapobiegnie wstawianiu rekordów
Instrukcja scalania wymaga średnika kończącego.
Ograniczenia:
-
WHEN MATCHED
nie zezwala naINSERT
-
UPDATE
może zaktualizować wiersz tylko raz. Oznacza to, że warunek łączenia musi dawać unikalne dopasowania.
Scal za pomocą źródła 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);
POŁĄCZ, używając pochodnej tabeli źródłowej
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);
Przykład scalania - Synchronizacja tabeli źródłowej i docelowej
Aby zilustrować instrukcję MERGE, rozważ następujące dwie tabele:
dbo.Produkt : Ta tabela zawiera informacje o produkcie, który firma obecnie sprzedaje
dbo.ProductNew : Ta tabela zawiera informacje o produkcie, który firma będzie sprzedawać w przyszłości.
Poniższy T-SQL utworzy i zapełni te dwie tabele
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)
Załóżmy teraz, że chcemy zsynchronizować tabelę docelową dbo.Product z tabelą dbo.ProductNew. Oto kryterium tego zadania:
Produkty istniejące zarówno w tabeli źródłowej dbo.ProductNew, jak i tabeli docelowej dbo.Product są aktualizowane w tabeli docelowej dbo.Product o nowe nowe produkty.
Każdy produkt w tabeli źródłowej dbo.ProductNew, który nie istnieje w tabeli docelowej dob.Product, jest wstawiany do tabeli docelowej dbo.Product.
Każdy produkt w tabeli docelowej dbo.Product, który nie istnieje w tabeli źródłowej dbo.ProductNew, musi zostać usunięty z tabeli docelowej dbo.Product. Oto instrukcja MERGE do wykonania tego zadania.
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.*;
Uwaga: średnik musi znajdować się na końcu instrukcji MERGE.
Scal za pomocą WYJĄTKU
Użyj WYJĄTKU, aby zapobiec aktualizacjom niezmienionych rekordów
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;