Microsoft SQL Server
SAMMANFOGA
Sök…
Introduktion
Från och med SQL Server 2008 är det möjligt att utföra infoga, uppdatera eller radera operationer i ett enda uttalande med MERGE-uttalandet.
Med MERGE-uttalandet kan du gå med i en datakälla med en måltabell eller vy och sedan utföra flera åtgärder mot målet baserat på resultaten från det sammanfogande.
Syntax
- Enligt MSDN - https://msdn.microsoft.com/en-us/library/bb510625.aspx [MED <common_table_expression> [, ... n]] MERGE [TOP (expression) [PERCENT]] [INTO] < target_table> [MED (<merge_hint>)] [[AS] table_alias] ANVÄNDER <table_source> ON <merge_search_condition> [WHEN MATCHED [AND <clause_search_condition>] THEN <merge_matched>] [... n] [WHEN NOT MATCHED [BY MÅL] [OCH <clause_search_condition>] DÄN <merge_not_matched]] [NÄR INTE KOMMERDE AV KÄLLA [OCH <clause_search_condition>] THEN <merge_matched>] [... n] [<output_clause>] [OPTION (<query_hint> [,. ..n])]; <target_table> :: = {[databasnamn. 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] [<tabellerample_clause>] [MED (table_hint [[,] ... n])] | rowset_function [[AS] table_alias] [(bulk_column_alias [, ... n])] | user_defined_function [[AS] table_alias] | OPENXML <openxml_clause> | deriv_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 | FUNKTION | NULL} | {udt_column_name. {{property_name = expression | field_name = expression} | metodnamn (argument [, ... n])}} | column_name {.WRITE (expression, @Offset, @Length)} | @variable = uttryck | @variable = kolumn = uttryck | column_name {+ = | - = | * = | / = | % = | & = | ^ = | | =} uttryck | @variable {+ = | - = | * = | / = | % = | & = | ^ = | | =} uttryck | @variable = kolumn {+ = | - = | * = | / = | % = | & = | ^ = | | =} uttryck} [, ... n] <merge_not_match> :: = {INSERT [(column_list)] {VALUES (Values_list) | DEFAULT VALUES}} <clause_search_condition> :: = <search_condition> :: = {[NOT] | (<sök_kondition>)} [{OCH | ELLER} [INTE] {| (<sök_kondition>)}] [, ... n] :: = {uttryck {= | <> | ! = |
| > = | ! > | <| <= | ! <} uttryck | string_expression [NOT] LIKE string_expression [ESCAPE 'escape_character'] | uttryck [INTE] MELLAN uttryck OCH uttryck | uttrycket är [INTE] NULL | INNEHÅLLER ({kolumn | *}, '<innehåller_sök_situation>') | FREETEXT ({kolumn | *}, 'freetext_string') | uttryck [INTE] IN (underskrift | uttryck [, ... n]) | uttryck {= | <> | ! = | | > = | ! > | <| <= | ! <} {ALLA | NOG | ANY} (undersökning) | EXISTER (subfråga)} <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 | INSTÄLLT | from_table_name}. {* | column_name} | $ åtgärd
Anmärkningar
Utför infoga, uppdatera eller radera operationer på en måltabell baserat på resultaten från en koppling med en källtabell. Till exempel kan du synkronisera två tabeller genom att infoga, uppdatera eller radera rader i en tabell baserat på skillnader i den andra tabellen.
FÖLJ till att infoga / uppdatera / radera
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
Beskrivning:
-
MERGE INTO targetTable
- tabell som ska modifieras -
USING sourceTable
-USING sourceTable
(kan vara en tabell eller visa eller tabellvärderad funktion) -
ON ...
-targetTable
tillstånd mellantargetTable
ochsourceTable
. -
WHEN MATCHED
- åtgärder som skaWHEN MATCHED
när en matchning hittas -
AND (targetTable.PKID > 100)
- ytterligare villkor som måste vara uppfyllda för att åtgärden ska kunna vidtas
-
-
THEN DELETE
- ta bort matchad post fråntargetTable
-
THEN UPDATE
- uppdatera kolumner med matchad post specificerad avSET ....
-
WHEN NOT MATCHED
- åtgärder som skaWHEN NOT MATCHED
när matchning inte finns itargetTable
-
WHEN NOT MATCHED BY SOURCE
- åtgärder som ska vidtas när matchning inte finns isourceTable
kommentarer:
Om en specifik åtgärd inte behövs, kan du undvika villkoret, t.ex. att ta bort WHEN NOT MATCHED THEN INSERT
förhindrar att poster införs
Sammanfattning uttalande kräver en avslutande semikolon.
restriktioner:
-
WHEN MATCHED
tillåterINSERT
åtgärder -
UPDATE
åtgärden kan bara uppdatera en rad en gång. Detta innebär att kopplingsvillkoret måste producera unika matchningar.
Slå samman med CTE-källa
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 med hjälp av Derived Source Table
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);
Sammanställningsexempel - Synkronisera käll- och måltabell
För att illustrera MERGE-uttalandet, överväg följande två tabeller -
dbo.Product : Denna tabell innehåller information om produkten som företaget för närvarande säljer
dbo.ProductNew : Denna tabell innehåller information om produkten som företaget kommer att sälja i framtiden.
Följande T-SQL skapar och fyller dessa två tabeller
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)
Anta nu att vi vill synkronisera dbo.Product-måltabellen med dbo.ProductNew-tabellen. Här är kriteriet för denna uppgift:
Produkt som finns i både dbo.ProductNew-källtabellen och dbo.Product-måltabellen uppdateras i dbo.Product-måltabellen med nya nya produkter.
Varje produkt i dbo.ProductNy källtabellen som inte finns i dob.Product-måltabellen införs i dbo.Product-måltabellen.
Alla produkter i tabellen dbo.Product-mål som inte finns i dbo.ProductNew-källtabellen måste tas bort från dbo.Product-måltabellen. Här är MERGE-uttalandet för att utföra denna uppgift.
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.*;
Obs: Semikolon måste vara närvarande i slutet av MERGE-uttalandet.
Slå ihop med undantag
Använd UNDANTAG för att förhindra uppdateringar av oförändrade poster
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;