sql >> Databasteknik >  >> RDS >> Database

MERGE:Uppdatering av käll- och måltabeller som finns på separata servrar

Vad är MERGE-satsen?

Med hjälp av MERGE-satsen kan vi ändra data i en måltabell baserat på data i en källtabell. Genom att använda den kan vi köra INSERT, UPDATE och DELETE på måltabellerna inom ett enda frågeblock. Den förenar båda tabellerna med hjälp av kolumner, vanliga i båda tabellerna som primärnyckeln. Baserat på hur kolumndata matchar, gäller ändringar för data i måltabellen. Följande bild illustrerar hur "MERGE" fungerar:

Genom att använda MERGE kan vi få prestandaförbättringar eftersom alla tre operationerna (INSERT, UPDATE och DELETE ) utförs i ett pass. Vi behöver inte skriva ett individuellt uttalande för att uppdatera ändringar i måltabellen.

Merge-satsen använder SourceTable och destinationstabell. Den ändrar DestinationTable baserat på data från SourceTable . Båda tabellerna jämförs med villkoret, definierat i sammanfogningsutlåtandet. Det här villkoret avgör hur SourceTable matchar måltabellen. Det är som kopplingsvillkor som används för att matcha rader.

Vanligtvis bör matchning göras genom att matcha unika identifierare som primärnycklar. Till exempel är källtabellen Ny produkt och destinationen är Productmaster och den primära nyckeln är ProductID , då bör sammanslagningsvillkor vara följande:

NewProduct.ProductID=ProductMaster.ProdID

Följande är formatet för MERGE-satsen:

SAMMANSLUTNING AV mål genom att använda källa sON joinConditionWHEN MATCHEDTHEN updateQueryWHEN NOT MATCHED BY TARGETTHEN insertQueryWHEN NOT MATCHED BY SOURCETHEN deleteQuery

För att modifiera data i måltabellen stöder MERGE följande T-SQL-satser.

  1. NÄR MATCH
  2. NÄR INTE MATCHAT [PER MÅL]
  3. NÄR INTE MATCHAT [PER KÄLLA]

“NÄR MATCHED” klausul

Denna klausul kommer att användas när vi vill uppdatera eller ta bort posterna på destinationstabellen. Här anses poster som matchande när data i de sammanfogade kolumnerna är desamma.

“NÄR INTE MATCHED [BY MÅL]”-klausul

Om posten finns i källtabellen men inte i måltabellen kommer denna sats att användas för att infoga en ny post i måltabellen.

“NÄR INTE MATCHED [PER SOURCE]”-sats

Denna sats kommer att användas när vi vill ta bort eller uppdatera en post i en källtabell som inte matchar en rad i måltabellen.

Använd MERGE när källa och mål finns på en separat server

I den här artikeln kommer jag att demonstrera hur man utför infogning, uppdatering och radering med MERGE, när käll- och måltabellerna finns på separata servrar. Till exempel använder ett läkemedelsföretag inventeringsprogramvara. Masterdatabaser för en programvara och transaktionsdatabaser för programvara finns på separata databasservrar. Följande är en inställning:

Företaget har lagt till ett fåtal beställda produkter. Jag vill utföra några saneringsprocesser samtidigt som jag uppdaterar lagret av produkter. Följande är listan över uppgifter som måste utföras.

  1. Om en produkt finns i lager och samma produkt beställdes, uppdatera och uppdatera sedan lagret.
  2. Om en produkt inte finns i lagret och lägg till produkten är beställd, lägg till produkten i lager.
  3. Om produkten finns i lagret men den inte är beställd dessutom uppdateras inte produktens lager i mer än ett år än att ta bort produkten från lagret.

För att utföra den ovan nämnda uppgiften kommer vi att utföra följande steg:

  1. Skapa en global temporär tabell med namnet ##Source_Trn_Tabl e. Fyll i data från "TrnOrder ” (Källtabell) med OPENROWSET kommando och lagra data i ##Source_Trn_Table .
  2. Utför INSERT, UPDATE och DELETE operationen på Mstock tabell (Target Table) med MERGE nyckelord, baserat på följande villkor:
    • Om värdet på Product_ID kolumnen finns i ##Source_Trn_Table och aktien tabell och uppdatera sedan den aktuella aktien i MstStock tabell.
    • Om värdet på Product_ID kolumnen finns i ##Source_Trn_Table men finns inte i MstStock tabell och lägg sedan till en produkt i MstStock tabell.
    • Om värdet på Product_ID kolumnen finns i MstStock men finns inte i ##Source_Trn_Tabl e, dessutom kolumnvärdet last_stock_update_date är längre än ett år, radera sedan product_id från MstStock tabell.

Följande är flödesschemat:

Demonstration

Skapa först en måltabell med namnet MstStock och MstProduct Product_Master databas, som finns på TTI412-VM2 server. Kör följande fråga:

ANVÄND [Product_Master]GOCREATE TABLE [dbo].[MstProduct]( [ID] [int] IDENTITY(1,1) NOT NULL, [Product_ID] [varchar](15) NULL, [Product_Name] [varchar]( 500) INTE NULL, PRIMÄRNYCKEL KLUSTERAD ( [ID] ASC) MED (PAD_INDEX =AV, STATISTICS_NORECOMPUTE =AV, IGNORE_DUP_KEY =AV, ALLOW_ROW_LOCKS =PÅ, ALLOW_PAGE_LOCKS =INGEN PRIMARY)], PÅ [WITH QUENT] (PAD_INDEX =AV, STATISTICS_NORECOMPUTE =AV, IGNORE_DUP_KEY =AV, ALLOW_ROW_LOCKS =PÅ, ALLOW_PAGE_LOCKS =PÅ) PÅ [PRIMÄR]) PÅ [PRIMÄR]GOCREATE TABLE [dbo]].[ENTIDstStock1]. 1) NOT NULL, [Product_ID] [varchar](5) NOT NULL, [Current_Stock] [int] NULL, [Last_Stock_Update_Date] [datetime] NULL,PRIMÄRKEY CLUSTERED ( [ID] ASC)WITH (PAD_INDEX =OFF, STATISTICS_N) AV, IGNORE_DUP_KEY =AV, ALLOW_ROW_LOCKS =PÅ, ALLOW_PAGE_LOCKS =PÅ) PÅ [PRIMÄR], UNIK EJ KLUSTERAD ( [Product_ID] ASC) MED (PAD_INDEX =AV, STATISTICS_NORECOMPUTE =_ AV_, IALLT AV, PÅ, PÅ, AV AGE_LOCKS =PÅ) PÅ [PRIMARY]) PÅ [PRIMARY]GO

Lägg nu till lite data till båda tabellerna.

Kör följande fråga för att lägga till data till MstProduct tabell:

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) VÄRDEN (34, 'MED147', 'Pipepapren')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) ) VÄRDEN (47, 'MED162', 'Acadipiphane')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (48, 'MED163', 'Septomapin')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VÄRDEN (49) , 'MED164', 'Acioxenal')INSERT dbo.MstProduct(ID, Pr oduct_ID, Product_Name) VALUES (50, 'MED165', 'Natadrolol')GOSET IDENTITY_INSERT dbo.MstProduct OFFGO

Kör följande fråga för att lägga till data till MstStock tabell:

insert into MstStock (Product_ID,Current_Stock,Last_Stock_Update_Date) värden ('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 ,'2017-10-14')

Utför följande "Välj"-frågor för att granska utdata från tabeller.

Fråga:

Använd Product_MasterGoSelect * från MstProduct

Utdata:

Fråga:

Använd Product_MasterGoSelect * från MstStock

Utdata:

För det andra, skapa en källtabell med namnet TrnOrderInventory_Details databas, som finns på TTI412-VM1 server. Kör följande fråga:

ANVÄND [Inventory_Details]GOCREATE TABLE [dbo].[TrnOrder]( [ID] [int] IDENTITY(1,1) NOT NULL, [Product_ID] [varchar](15) NOT NULL, [Ordered_Quty] [int] NULL, [Ordered_Date] [datetime] NULL, [Last_Ordered_Date] [datetime] NULL, PRIMÄRNYCKEL CLUSTERED ( [ID] ASC)WITH (PAD_INDEX =AV, STATISTICS_NORECOMPUTE =AV, IGNORE_DUP_KEY LOCKLOCKLOCKS =OFF_W_ON, PÅ_) [PRIMÄR], UNIK EJ KLUSTERAD ( [Product_ID] ASC) MED (PAD_INDEX =AV, STATISTICS_NORECOMPUTE =AV, IGNORE_DUP_KEY =AV, ALLOW_ROW_LOCKS =PÅ, ALLOW_PAGE_LOCKS =PÅ)]) [PRIMÄRT]) [PRIMÄRT 

Kör följande fråga för att lägga till data till MstStock tabell:

insert into TrnOrder (Product_ID,Ordered_Quty,Ordered_Date,Last_Ordered_Date)values ​​('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')

Kör följande "Välj"-fråga för att granska tabellens utdata.

Fråga:

Använd Inventory_DetailsGoSelect * från TrnOrder

Utdata:

Anslut till Remote SQL Server-instans för att fylla i data

Som jag nämnde vill vi uppdatera värdena i "tabell som skapas på en fjärrserver. Vi kan komma åt data från en fjärrdatabasserver genom att använda följande metoder.

  1. SQL-serverlänkad server :Länkad server används för att utföra ett kommando på OLEDB-datakällan som är länkad till fjärransluten SQL Server-instans. Med hjälp av en länkad server kan du också fråga de olika databasprodukterna som Oracle. OLEDB-källor kan konfigureras för att få åtkomst till Microsoft Access och Excel som en länkad server.
  2. SQL Server OPENROWSET-funktion :Genom att använda OPENROWSET-funktionen kan vi köra en ad-hoc-fråga på den fjärranslutna OLEDB-datakällan.

I den här artikeln kommer vi att använda OPENROWSET metod för att komma åt data från fjärrtabellen. För att fråga en fjärrserver med OPENROWSET-funktionen måste vi aktivera Ad hoc-distribuerade frågor konfigurationsparameter.

"Ad hoc distribuerade frågor" är ett avancerat alternativ, därför måste vi först aktivera Visa avancerade alternativ konfigurationsparameter. För att göra det, kör följande kommando i frågefönstret i SQL Server Management Studio.

exec sp_configure 'visa avancerade alternativ',1omkonfigurera med overrideGo

När Visa avancerat alternativ parametern är aktiverad, kör följande fråga för att aktivera Distribuerade ad hoc-frågor :

sp_configure 'Ad Hoc Distributed Queries', 1;RECONFIGURE WITH OVERRIDE;GO

Vi kan inte använda "OPENROWSET"-funktionen för att utföra MERGE-operation med hjälp av data från fjärrservern. För att göra det först måste vi importera data från fjärrservern och lagra den i den globala temporära tabellen. Efter det kan vi använda data som ligger i den globala temporära tabellen för att uppdatera måltabellen.

Som jag nämnde måste vi först importera data från fjärrtabellen. För att göra det, skapa en temporär tabell och importera data med OPENROWSET-funktionen.
Följande fråga kommer att skapa en global temporär tabell.

använd Product_MastergoCREATE TABLE ##Source_Trn_Order( [ID] [int] IDENTITY(1,1) NOT NULL, [Product_ID] [varchar](15) NOT NULL, [Ordered_Quty] [int] NULL, [Ordered_Date] [datetime ] NULL, [Last_Ordered_Date] [datetime] NULL)

När den tillfälliga tabellen har skapats, låt oss ladda data från en källtabell som finns på en fjärrserver. För att göra det, kör följande fråga:

infoga i ##Source_Trn_Order välj [Product_ID],[Ordered_Quty],[Ordered_Date],[Last_Ordered_Date] från OPENROWSET('SQLNCLI', 'Server=TTI609-VM1;Trusted_Connection=yes;','Ordered_SELECT Product_ID Ordered_Date,Last_Ordered_Date FROM Inventory_Details.dbo.TrnOrder') AS a;

Steg 1:Om en produkt finns i MstStock (Target Table) och TrnOrder (Source Table) uppdaterar du den aktuella kvantiteten i MstStock

För att göra det, använd NÄR MATCHED klausul. Klausulen förenar käll- och måltabeller i de gemensamma kolumnerna i båda tabellerna. Product_ID kolumn är vanlig mellan MstStock och ##Source_Trn_Table, använd den därför för att slå samman båda tabellerna.

Kör följande kod:

 SAMMANFÖR MstStock target_StockUSING ##Source_Trn_Order Source_OrderON target_Stock.Product_Id =Source_Order.Product_Id NÄR MATCHED SEDAN UPPDATERAS SÄTTA target_Stock.Current_Stock =Source_Order.Ordered_Qty.Current_Stock_date=Last_Stock_Date_Current_Stock;Current_Stock_); 

Värdet på kolumnen Current_Stock med 4 produkter bör uppdateras. Kör följande fråga för att verifiera utdata:

välj b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date från MstStock a inre join MstProduct b på a.Product_ID=b.Product_ID och a.Current_Stock>0

Följande är resultatet:

Steg 2:Om en produkt inte finns i MstStock (Target Table), lägg till den i MstStock (Target Table)

Apotek hade beställt några produkter. Dessa produkter lades till i MstProduct-tabellen men lades inte till i MstStock-tabellen. För att lägga till dessa produkter i MstStock tabell, kommer jag att använda WHEN NOT MATCHED [MÅL]-satsen. Klausulen förenar käll- och måltabeller med vanliga kolumner. Om matchande rader inte hittas i måltabellen infogar den rader från källtabellen.

För att lägga till produkter till MstStock med SAMMANFATTNING tabell, kör följande kod:

SAMMANFÖR mststock target_Stockusing ##source_trn_order Source_OrderON target_Stock.product_id =source_order.product_idWHEN matched THEN UPDATE SET target_Stock.current_stock =Source_Order.ordered_qty + target_Stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock. last_stock_update_date) VALUES (Source_Order.product_id, Source_Order.ordered_qty, Getdate());

Två produkt-ID:n, MED169 och MED170, bör läggas till. Kör följande fråga för att granska utdata:

välj b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date från MstStock a inre join MstProduct b på a.Product_ID=b.Product_ID och a.Current_Stock>0

Följande är utdata:

Steg 3:Ta bort artikel från MstStock (Target Table), om nuvarande lager i MstStock (Target Table) är noll och produkten inte finns i ##Source_Trn_Order (källtabell)

I lager finns det få produkter som behöver raderas eftersom de inte har beställts sedan ett år. Därför måste vi ta bort dem från MstStock tabellen och tabellen MstProducts. För att ta bort dessa produkter från MstStock tabell kan vi använda NÄR INTE MATCHED [KÄLLA] .

NÄR INTE MATCHED [KÄLLA] sats förenar käll- och måltabeller med vanliga kolumner. Om matchande rader inte hittas i källtabellen tar den bort rader från måltabellen.

För att ta bort produkter från MstStock tabell, kör följande kod:

SAMMANFÖR mststock target_Stockusing ##source_trn_order Source_OrderON target_Stock.product_id =source_order.product_idWHEN matched THEN UPDATE SET target_Stock.current_stock =Source_Order.ordered_qty + target_Stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock.current_stock. last_stock_update_date) VÄRDEN (Source_Order.product_id, Source_Order.ordered_qty, Getdate()) NÄR INTE matchas AV KÄLLA, TA DETTA DELETE;

Två produkt-ID:n, MED158 och MED159 bör läggas till. Kör följande fråga för att granska utdata:

välj b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date från MstStock a inre join MstProduct b på a.Product_ID=b.Product_ID och a.Current_Stock>0

Följande är utdata:

Sammanfattning

I den här artikeln har jag täckt följande:

  1. Vad är MERGE-sökord och hur fungerar det?
  2. Olika satser som används i MERGE för att uppdatera käll- och måltabellen.
  3. Hur man ändrar data med hjälp av nyckelordet MERGE när databaser finns på olika servrar.

Användbara verktyg:

dbForge Data Compare för SQL Server – kraftfullt SQL-jämförelseverktyg som kan arbeta med big data.


  1. Är det bättre att använda flera databaser med ett schema vardera, eller en databas med flera scheman?

  2. Ställa in Oracle-språkparametrar för DG4ODBC

  3. Problem med att öppna MDF-fil eftersom det står SQL-fel 5171? - Ett gästinlägg av Andre Williams

  4. Kontrollera om en användardefinierad typ redan finns i PostgreSQL