Wat is de MERGE-instructie?
Met behulp van de MERGE-instructie kunnen we gegevens in een doeltabel wijzigen op basis van gegevens in een brontabel. Hiermee kunnen we INSERT, UPDATE en DELETE uitvoeren op de doeltabellen binnen een enkel queryblok. Het verbindt beide tabellen met behulp van kolommen, gebruikelijk in beide tabellen, zoals de primaire sleutel. Op basis van hoe kolomgegevens overeenkomen, zijn wijzigingen van toepassing op gegevens van doeltabel. De volgende afbeelding illustreert hoe "MERGE" werkt:
Door MERGE te gebruiken, kunnen we prestatieverbetering krijgen omdat alle drie de bewerkingen (INSERT, UPDATE en DELETE ) worden in één keer uitgevoerd. We hoeven geen individuele verklaring te schrijven om wijzigingen in de doeltabel bij te werken.
De merge-instructie gebruikt SourceTable en Bestemmingstabel. Het wijzigt DestinationTable gebaseerd op de gegevens van SourceTable . Beide tabellen worden vergeleken met behulp van de voorwaarde die is gedefinieerd in de samenvoeginstructie. Deze voorwaarde bepaalt hoe SourceTable overeenkomt met de doeltabel. Het is net als voorwaarden voor samenvoegen die worden gebruikt om rijen te matchen.
Doorgaans moet matching worden gedaan door unieke identifiers zoals primaire sleutels te matchen. De brontabel is bijvoorbeeld Nieuw product en bestemming is Productmaster en de primaire sleutel is ProductID , dan zou de samenvoegvoorwaarde als volgt moeten zijn:
NewProduct.ProductID=ProductMaster.ProdID
Hieronder volgt het formaat van de MERGE-instructie:
DOEL SAMENVOEGEN met behulp van source son joinConditionWANNEER OVEREENGEKOMEN DAN updateQueryWANNEER NIET OVEREENGEKOMEN DOOR TARGETEN insertQueryWANNEER NIET OVEREENGEKOMEN DOOR SOURCETHEN deleteQuery
Om de gegevens in de doeltabel te wijzigen, ondersteunt MERGE de volgende T-SQL-clausules.
- WANNEER OVEREENGEKOMEN
- WANNEER NIET OVEREENGEKOMEN [DOOR DOEL]
- WANNEER NIET OVEREENGEKOMEN [VOOR BRON]
"WHEN MATCHED"-clausule
Deze clausule wordt gebruikt wanneer we de records in de bestemmingstabel willen bijwerken of verwijderen. Hier worden records als overeenkomend beschouwd als de gegevens in de samengevoegde kolommen hetzelfde zijn.
“WHEN NOT MATCHED [BY TARGET]”-clausule
Als het record aanwezig is in de brontabel maar niet in de doeltabel, wordt deze clausule gebruikt om een nieuw record in de doeltabel in te voegen.
“WHEN NOT MATCHED [BY SOURCE]”-clausule
Deze clausule wordt gebruikt wanneer we een record in een brontabel willen verwijderen of bijwerken die niet overeenkomt met een rij in de doeltabel.
Gebruik MERGE wanneer bron en doel op een aparte server staan
In dit artikel ga ik demonstreren hoe u een invoeg-, update- en verwijderbewerking uitvoert met MERGE, wanneer de bron- en doeltabellen zich op afzonderlijke servers bevinden. Een farmaceutisch bedrijf gebruikt bijvoorbeeld voorraadsoftware. Masterdatabases van software en transactionele databases van software bevinden zich op afzonderlijke databaseservers. Het volgende is een opstelling:
Het bedrijf heeft een aantal bestelde producten toegevoegd. Ik wil een paar opschoningsprocessen uitvoeren terwijl ik de voorraad producten bijwerk. Hieronder volgt de lijst met taken die moeten worden uitgevoerd.
- Als een product in voorraad is en hetzelfde product is besteld, update dan de voorraad.
- Als een product niet in de voorraad aanwezig is en product toevoegen is besteld, voeg dan het product op voorraad toe.
- Als het product in de voorraad aanwezig is, maar het is bovendien niet besteld, wordt de voorraad van het product niet langer dan een jaar bijgewerkt, dan wordt het product uit de voorraad verwijderd.
Om de bovengenoemde taak uit te voeren, zullen we de volgende stappen uitvoeren:
- Maak een globale tijdelijke tabel met de naam ##Source_Trn_Tabl e. Gegevens invullen uit "TrnOrder ” (Brontabel) met behulp van de OPENROWSET opdracht geven en gegevens opslaan in ##Source_Trn_Table .
- Voer de bewerking INSERT, UPDATE en DELETE uit op de MstStock tabel (doeltabel) met behulp van de MERGE trefwoord, op basis van de volgende voorwaarden:
- Als de waarde van de Product_ID kolom bestaat in ##Source_Trn_Table en de voorraad tabel en werk vervolgens de huidige voorraad bij in de MstStock tafel.
- Als de waarde van de Product_ID kolom bestaat in ##Source_Trn_Table maar bestaat niet in de MstStock tabel en voeg vervolgens een product toe aan de MstStock tafel.
- Als de waarde van de Product_ID kolom bestaat in MstStock maar bestaat niet in ##Source_Trn_Tabl e, bovendien de kolomwaarde van last_stock_update_date langer is dan een jaar, verwijder dan product_id uit de MstStock tafel.
Hieronder volgt het stroomschema:
Demonstratie
Maak eerst een doeltabel met de naam MstStock en MstProduct op de Product_Master database, gelegen op de TTI412-VM2 server. Voer de volgende vraag uit:
USE [Product_Master]GOCREATE TABLE [dbo].[MstProduct]( [ID] [int] IDENTITY(1,1) NOT NULL, [Product_ID] [varchar](15) NULL, [Product_Name] [varchar]( 500) NIET NULL,PRIMAIRE SLEUTEL GECLUSTERD ( [ID] ASC)MET (PAD_INDEX =UIT, STATISTICS_NORECOMPUTE =UIT, IGNORE_DUP_KEY =UIT, ALLOW_ROW_LOCKS =AAN, ALLOW_PAGE_LOCKS =AAN) AAN [PRIMARY],UNIEK NIET-GECLUSTERD]SC ([) (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY]GOCREATE TABLE [dbo].[MstStock]( [ID] [int] IDENTITY(1, 1) NOT NULL, [Product_ID] [varchar](5) NOT NULL, [Current_Stock] [int] NULL, [Last_Stock_Update_Date] [datetime] NULL, PRIMAIRE SLEUTEL CLUSTERED ( [ID] ASC) MET (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =UIT, IGNORE_DUP_KEY =UIT, ALLOW_ROW_LOCKS =AAN, ALLOW_PAGE_LOCKS =AAN) AAN [PRIMAIR], UNIEK NIET-GECLUSTERD ([Product_ID] ASC)MET (PAD_INDEX =UIT, STATISTICS_NORECOMPUTE =UIT, IGNORE_DUP_KEY =UIT, ALLOW_ AGE_LOCKS =AAN) OP [PRIMARY]) OP [PRIMARY]GO
Voeg nu wat gegevens toe aan beide tabellen.
Voer de volgende query uit om gegevens toe te voegen aan het MstProduct tafel:
SET IDENTITY_INSERT dbo.MstProduct ONGOINSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (28, 'MED141', 'Alfimaxin')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (29, 'MED142', 'Zylasonmuc')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (30, 'MED143', 'Rythmoxabid')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (31, 'MED144', 'Omedrozol') INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (32, 'MED145', 'Reducurzol')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (33, 'MED146', 'Losapuritriol')INSERT dbo.MstProduct (ID, Product_ID, Product_Name) VALUES (34, 'MED147', 'Pipepapreen')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (35, 'MED148', 'Miraperahex')INSERT dbo.MstProduct(ID, Product_ID , Product_Name) VALUES (36, 'MED149', 'Durachloridevant')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (37, 'MED151', 'Renachloridenide')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (38, 'MED152') ', 'Ecopurimuc')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (39, 'MED153', 'Aerocarpambid')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (40, 'MED154', 'Afsitec ')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (41, 'MED155', 'Aprozovant')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (42, 'MED156', 'Levopafen')INSERT dbo .MstProduct(ID, Product_ID, Product_Name) VALUES (43, 'MED157', 'Medrotraxel')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (44, 'MED158', 'Doxxaliq')INSERT dbo.MstProduct(ID , Product_ID, Product_Name) VALUES (45, 'MED159', 'Betatasine')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (46, 'MED161', 'Ciclopatex')INSERT dbo.MstProduct(ID, Product_ID, Product_Name ) VALUES (47, 'MED162', 'Acadipiphane')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (48, 'MED163', 'Septomapin')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (49 , 'MED164', 'Acioxenal')INSERT dbo.MstProduct(ID, Pr oduct_ID, Product_Name) VALUES (50, 'MED165', 'Natadrolol')GOSET IDENTITY_INSERT dbo.MstProduct OFFGO
Voer de volgende query uit om gegevens toe te voegen aan de MstStock tafel:
invoegen in MstStock-waarden (Product_ID,Current_Stock,Last_Stock_Update_Date) ('MED145',15,'2018-10-14'),('MED146',20,'2018-10-13'),('MED147' ,5,'2018-09-10'),('MED150',5,'2018-08-01'),('MED158',0,'2017-10-14'),('MED159',0 ,'14-10-2017')
Voer de volgende "Select"-query's uit om de uitvoer van tabellen te bekijken.
Vraag:
Gebruik Product_MasterGoSelect * van MstProduct
Uitvoer:
Vraag:
Gebruik Product_MasterGoSelect * van MstStock
Uitvoer:
Ten tweede, maak een brontabel met de naam TrnOrder op de Inventory_Details database, gelegen op de TTI412-VM1 server. Voer de volgende vraag uit:
USE [Inventory_Details]GOCREATE TABLE [dbo].[TrnOrder]( [ID] [int] IDENTITY(1,1) NOT NULL, [Product_ID] [varchar](15) NOT NULL, [Ordered_Qty] [int] NULL, [Ordered_Date] [datetime] NULL, [Last_Ordered_Date] [datetime] NULL,PRIMARY KEY CLUSTERED ( [ID] ASC)WITH (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON) ALLOW_LOCKS =ON) [PRIMARY],UNIEK NIET-GECLUSTERD ([Product_ID] ASC)MET (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY]GO
Voer de volgende query uit om gegevens toe te voegen aan de MstStock tafel:
invoegen in TrnOrder (Product_ID,Ordered_Qty,Ordered_Date,Last_Ordered_Date) waarden ('MED145',10,convert(date,getdate()),'2018-10-14'),('MED146',5,convert( date,getdate()),'2018-10-13'),('MED147',15,convert(date,getdate()),'2018-09-10'),('MED150',200,convert( date,getdate()),'2018-08-01') ,('MED169',50,convert(date,getdate()),'2018-10-14'),('MED170',100,convert( date,getdate()),'2018-10-14')
Voer de volgende "Select"-query uit om de uitvoer van de tabel te bekijken.
Vraag:
Gebruik Inventory_DetailsGoSelect * van TrnOrder
Uitvoer:
Verbinding maken met externe SQL Server-instantie om gegevens in te vullen
Zoals ik al zei, willen we de waarden bijwerken in "tabel die is gemaakt op een externe server. We hebben toegang tot gegevens van een externe databaseserver door de volgende methoden te gebruiken.
- SQL Server Gelinkte server :Gekoppelde server wordt gebruikt om een opdracht uit te voeren op de OLEDB-gegevensbron die is gekoppeld aan een externe SQL Server-instantie. Met behulp van een gekoppelde server kunt u ook de verschillende databaseproducten zoals Oracle opvragen. OLEDB-bronnen kunnen worden geconfigureerd om toegang te krijgen tot Microsoft Access en Excel als een gekoppelde server.
- SQL Server OPENROWSET-functie :Met behulp van de OPENROWSET-functie kunnen we een ad-hocquery uitvoeren op de externe OLEDB-gegevensbron.
In dit artikel gebruiken we de OPENROWSET methode om toegang te krijgen tot gegevens van de externe tabel. Om een externe server te bevragen met behulp van de OPENROWSET-functie, moeten we de Ad hoc gedistribueerde zoekopdrachten inschakelen configuratieparameter.
"Ad hoc gedistribueerde zoekopdrachten" is een geavanceerde optie, daarom moeten we eerst de Toon geavanceerde optie inschakelen configuratieparameter. Om dat te doen, voert u de volgende opdracht uit in het Query-venster van SQL Server Management Studio.
exec sp_configure 'toon geavanceerde opties',1reconfigure with overrideGo
Zodra de Toon geavanceerde optie parameter is ingeschakeld, voert u de volgende query uit om Ad hoc gedistribueerde zoekopdrachten in te schakelen :
sp_configure 'Ad hoc gedistribueerde zoekopdrachten', 1;HERCONFIGUREREN MET OVERRIDE;GO
We kunnen de functie "OPENROWSET" niet gebruiken om de MERGE-bewerking uit te voeren met behulp van gegevens van de externe server. Om dat te doen, moeten we eerst gegevens importeren van een externe server en deze opslaan in de globale tijdelijke tabel. Daarna kunnen we gegevens gebruiken die in de globale tijdelijke tabel zijn gelogen om de doeltabel bij te werken.
Zoals ik al zei, moeten we eerst gegevens importeren uit de externe tabel. Om dat te doen, maakt u een tijdelijke tabel aan en importeert u gegevens met de functie OPENROWSET.
De volgende query maakt een globale tijdelijke tabel aan.
gebruik Product_MastergoCREATE TABLE ##Source_Trn_Order( [ID] [int] IDENTITY(1,1) NOT NULL, [Product_ID] [varchar](15) NOT NULL, [Ordered_Qty] [int] NULL, [Ordered_Date] [datetime ] NULL, [Last_Ordered_Date] [datetime] NULL)
Nadat de tijdelijke tabel is gemaakt, gaan we gegevens laden uit een brontabel die zich op een externe server bevindt. Voer hiervoor de volgende query uit:
invoegen in ##Source_Trn_Order selecteer [Product_ID],[Ordered_Qty],[Ordered_Date],[Last_Ordered_Date] van OPENROWSET('SQLNCLI', 'Server=TTI609-VM1;Trusted_Connection=yes;,','SELECT Product__Date Ordered_Date,Last_Ordered_Date FROM Inventory_Details.dbo.TrnOrder') AS a;
Stap 1:Als een product bestaat in MstStock (doeltabel) en TrnOrder (brontabel), werk dan de huidige hoeveelheid bij in MstStock
Gebruik hiervoor de WHEN MATCHED clausule. De clausule voegt bron- en doeltabellen samen met de gemeenschappelijke kolommen van beide tabellen. De Product_ID kolom is gebruikelijk tussen MstStock en ##Source_Trn_Table, gebruik het daarom om beide tabellen samen te voegen.
Voer de volgende code uit:
MERGE MstStock target_StockUSING ##Source_Trn_Order Source_OrderON target_Stock.Product_Id =Source_Order.Product_Id WHEN MATCHED THEN UPDATE SET target_Stock.Current_Stock =Source_Order.Ordered_Qty + target_Stock.Current_date_Date_Date_Stockpredate_Date_De waarde van de kolom Current_Stock van 4 producten moet worden bijgewerkt. Voer de volgende query uit om de uitvoer te verifiëren:
select b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date from MstStock a inner join MstProduct b op a.Product_ID=b.Product_ID en a.Current_Stock>0Hieronder volgt de uitvoer:
Stap 2:Als een product niet bestaat in MstStock (Target Table), voeg het dan toe aan MstStock (Target Table)
Apotheek had een paar producten besteld. Die producten zijn toegevoegd aan de MstProduct-tabel, maar niet toegevoegd aan de MstStock-tabel. Om die producten toe te voegen aan de MstStock tabel, zal ik de WHEN NOT MATCHED [TARGET]-clausule gebruiken. De clausule voegt bron- en doeltabellen samen met behulp van gemeenschappelijke kolommen. Als er geen overeenkomende rijen worden gevonden in de doeltabel, worden rijen uit de brontabel ingevoegd.
Producten toevoegen aan MstStock met behulp van de MERGE tabel, voer de volgende code uit:
MERGE mststock target_Stockusing ##source_trn_order Source_OrderON target_Stock.product_id =source_order.product_idWHEN komt overeen DAN UPDATE SET target_Stock.current_stock =Source_Order.ordered_qty + target_Stock.current_stock, last_stock_update_date =Getdate() doel THE_ huidige INS komt niet overeen last_stock_update_date) WAARDEN (Source_Order.product_id, Source_Order.ordered_qty, Getdate());Twee product-ID's, MED169 en MED170, moet worden toegevoegd. Voer de volgende query uit om de uitvoer te bekijken:
select b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date from MstStock a inner join MstProduct b op a.Product_ID=b.Product_ID en a.Current_Stock>0Het volgende wordt uitgevoerd:
Stap 3:Verwijder artikel uit MstStock (doeltabel), als de huidige voorraad in MstStock (doeltabel) nul is en het product niet in ##Source_Trn_Order (brontabel) staat
In de inventaris zijn er weinig producten die moeten worden verwijderd omdat deze al een jaar niet zijn besteld. Daarom moeten we ze verwijderen uit de MstStock tafel en de MstProducts-tabel. Om die producten te verwijderen uit de MstStock tabel, kunnen we WHEN NOT MATCHED [SOURCE] . gebruiken .
De WHEN NOT MATCHED [BRON] clausule voegt bron- en doeltabellen samen met behulp van gemeenschappelijke kolommen. Als er geen overeenkomende rijen worden gevonden in de brontabel, worden de rijen uit de doeltabel verwijderd.
Producten verwijderen uit de MstStock tabel, voer de volgende code uit:
MERGE mststock target_Stockusing ##source_trn_order Source_OrderON target_Stock.product_id =source_order.product_idWHEN komt overeen DAN UPDATE SET target_Stock.current_stock =Source_Order.ordered_qty + target_Stock.current_stock, last_stock_update_date =Getdate() doel THE_ huidige INS komt niet overeen last_stock_update_date) WAARDEN (Source_Order.product_id, Source_Order.ordered_qty, Getdate()) WANNEER NIET overeenkomen met BRON DAN VERWIJDEREN;Twee product-ID's, MED158 en MED159 moet worden toegevoegd. Voer de volgende query uit om de uitvoer te bekijken:
select b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date van MstStock a inner join MstProduct b op a.Product_ID=b.Product_ID en a.Current_Stock>0Het volgende wordt uitgevoerd:
Samenvatting
In dit artikel heb ik het volgende behandeld:
- Wat is het MERGE-zoekwoord en hoe werkt het?
- Verschillende clausules gebruikt in MERGE om de bron- en doeltabel bij te werken.
- Hoe u gegevens kunt wijzigen met het MERGE-sleutelwoord wanneer databases zich op verschillende servers bevinden.
Handige hulpmiddelen:
dbForge Data Compare voor SQL Server – krachtige SQL-vergelijkingstool die met big data kan werken.