Какво е операторът MERGE?
Използвайки оператора MERGE, можем да променим данни в целева таблица въз основа на данни в таблица източник. Използвайки го, можем да изпълним INSERT, UPDATE и DELETE върху целевите таблици в рамките на един блок на заявка. Той свързва двете таблици с помощта на колони, общи и в двете таблици като първичния ключ. Въз основа на това как съвпадат данните в колоните, промените се прилагат към данните на целевата таблица. Следното изображение илюстрира как работи „MERGE“:
Използвайки MERGE, можем да подобрим производителността, тъй като и трите операции (INSERT, UPDATE и DELETE ) се изпълняват с едно преминаване. Не е необходимо да пишем отделно изявление, за да актуализираме промените в целевата таблица.
Инструкцията за сливане използва SourceTable и Таблица на дестинацията. Той променя DestinationTable въз основа на данните от SourceTable . И двете таблици се сравняват с помощта на условието, дефинирано в Инструкцията за сливане. Това условие определя как SourceTable съвпада с таблицата на местоназначението. Това е като условия за присъединяване, които се използват за съпоставяне на редове.
Обикновено съпоставянето трябва да се извършва чрез съпоставяне на уникални идентификатори като първични ключове. Например таблицата с източник е Нов продукт и местоназначението е Productmaster, а първичният ключ е ProductID , тогава условието за сливане трябва да бъде както следва:
NewProduct.ProductID=ProductMaster.ProdID
Следва форматът на оператора MERGE:
ОБЕДИНЯВАНЕ на целта с използване на източник sON joinConditionWHEN MATCHEDTHEN updateQuery КОГАТО НЕ СЪВЪВТАПВА ОТ TARGETTHEN insertQueryКОГА НЕ СЪВЪВПАДА ОТ SOURCETHEN deleteQuery
За да промени данните в целевата таблица, MERGE поддържа следните T-SQL клаузи.
- КОГАТО СЕ СЪВПАДА
- КОГАТО НЕ СЕ СЪВПАДА [ПО ЦЕЛ]
- КОГАТО НЕ СЕ СЪВПАДА [ПО ИЗТОЧНИК]
Клауза „WHEN MATCHED“
Тази клауза ще се използва, когато искаме да актуализираме или изтрием записите в целевата таблица. Тук записите се считат за съвпадащи, когато данните в обединените колони са еднакви.
Клауза „КОГАТО НЕ СЕ СЪВПАДА [ПО ЦЕЛ]“
Ако записът присъства в таблицата източник, но не и в целевата таблица, тогава тази клауза ще се използва за вмъкване на нов запис в целевата таблица.
Клауза „КОГАТО НЕ СЕ СЪВПАДА [ПО ИЗТОЧНИК]“
Тази клауза ще се използва, когато искаме да изтрием или актуализираме запис в таблица източник, който не съвпада с ред в целевата таблица.
Използвайте MERGE, когато източникът и целта са на отделен сървър
В тази статия ще демонстрирам как да извършвате операции за вмъкване, актуализиране и изтриване с помощта на MERGE, когато изходната и целевата таблица са в отделни сървъри. Например, фармацевтична компания използва софтуер за инвентаризация. Основните бази данни на софтуер и транзакционни бази данни на софтуер са на отделни сървъри за бази данни. Следното е настройка:
Компанията е добавила няколко поръчани продукта. Искам да извърша няколко процеса на почистване, докато актуализирам запаса от продукти. Следва списък на задачите, които трябва да бъдат изпълнени.
- Ако продукт съществува в инвентара и е поръчан същият продукт, след това актуализирайте и след това актуализирайте наличността.
- Ако продукт не съществува в инвентара и е поръчан добавен продукт, добавете продукта на склад.
- Ако продуктът съществува в инвентара, но не е поръчан, освен това наличността на продукта не се актуализира повече от една година, изтрийте продукта от инвентара.
За да изпълним гореспоменатата задача, ще изпълним следните стъпки:
- Създайте глобална временна таблица с име ##Source_Trn_Tabl д. Попълване на данни от „TrnOrder ” (Изходна таблица) с помощта на OPENROWSET командвайте и съхранявайте данни в ##Source_Trn_Table .
- Извършване на операции INSERT, UPDATE и DELETE на MstStock таблица (Целева таблица) с помощта на СЛИВАНЕ ключова дума въз основа на следните условия:
- Ако стойността на Product_ID колоната съществува в ##Source_Trn_Table и запасата таблица, след което актуализирайте текущата наличност в MstStock маса.
- Ако стойността на Product_ID колоната съществува в ##Source_Trn_Table но не съществува в MstStock таблица, след което добавете продукт към MstStock маса.
- Ако стойността на Product_ID колоната съществува в MstStock но не съществува в ##Source_Trn_Tabl д, освен това стойността на колоната на last_stock_update_date е повече от една година, след което изтрийте product_id от MstStock маса.
Следва диаграмата:
Демонстрация
Първо създайте целева таблица с име MstStock и MstProduct на Product_Master база данни, намираща се на TTI412-VM2 сървър. Изпълнете следната заявка:
ИЗПОЛЗВАЙТЕ [Product_Master]GOCREATE TABLE [dbo].[MstProduct]( [ID] [int] IDENTITY(1,1) НЕ NULL, [Product_ID] [varchar](15) NULL, [Product_Name] [varchar]( 500) НЕ НУЛЕВО, ПЪРВИЧЕН КЛУШЕР КЛУСТРИРАН ( [ID] ASC) С (PAD_INDEX =ИЗКЛЮЧЕНО, STATISTICS_NORECOMPUTE =ИЗКЛЮЧЕНО, IGNORE_DUP_KEY =ИЗКЛЮЧЕНО, ALLOW_ROW_LOCKS =ВКЛ, ALLOW_PAGE_LOCKSPRIMARY] (PAD_INDEX =ИЗКЛ.) (PAD_INDEX =ИЗКЛЮЧЕНО, STATISTICS_NORECOMPUTE =ИЗКЛЮЧЕНО, IGNORE_DUP_KEY =ИЗКЛЮЧЕНО, ALLOW_ROW_LOCKS =ВКЛ, ALLOW_PAGE_LOCKS =ВКЛ) ВКЛЮЧЕНО [ПРАВИЛНО]) ВКЛЮЧЕНО [PRIMARY]GOCREATE TABLE [dbo].[MstIDStock][MstIDStock]([MstIDStock](1) 1) NOT NULL, [Product_ID] [varchar](5) NOT NULL, [Current_Stock] [int] NULL, [Last_Stock_Update_Date] [datetime] NULL,PRIMARY KEY CLUSTERED ( [ID] ASC)WITH (PAD_INDEXPUSTICS =OFF,PAD STATITECS_OFF, ИЗКЛЮЧЕНО, IGNORE_DUP_KEY =ИЗКЛЮЧЕНО, ALLOW_ROW_LOCKS =ВКЛ, ALLOW_PAGE_LOCKS =ВКЛ.) ВКЛЮЧЕНО [ОСНОВНО], УНИКАЛНО НЕКЛУСТРИРАНО ( [Product_ID] ASC) С (PAD_INDEX =ИЗКЛ., STATISTICS_NOREW_KEGNOREALL =ИЗКЛ. AGE_LOCKS =ВКЛ.) НА [ОСНОВНО]) НА [ОСНОВНО]GO
Сега добавете малко данни към двете таблици.
Изпълнете следната заявка, за да добавите данни към MstProduct таблица:
ЗАДАДЕТЕ IDENTITY_INSERT dbo.MstProduct ONGOINSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (28, 'MED141', 'Alfimaxin')INSERT dbo.MstProduct(ID, Product_ID, Product_Name)'MES (D14,D14) 'Zylasonmuc')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (30, 'MED143', 'Rythmoxabid')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (31, 'MED144'medrozol' INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (32, 'MED145', 'Reducurzol')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) STOJIS (33, 'MED146', 'Losapuritriol')INstProduct (ID, Product_ID, Product_Name) VALUES (34, 'MED147', 'Pipepapren')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (35, 'MED148', 'Miraperahex')INSERT dbo.Mst_ID( , Product_Name) VALUES (36, 'MED149', 'Durachloridevant')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (37, 'MED151', 'Renachloridenide')INSERT dbo.MstProduct(ID_Na Product_ID) (38, 'MED152 ', 'Ecopurimuc')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (39, 'MED153', 'Aerocarpambid')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) STOJIS (40, 'MED'Afsite) ')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 .MstProduct(ID, Product_ID, Product_Name) VALUES (43, 'MED157', 'Medrotraxel')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (44, 'MED158', 'Doxxaliq')INSERTProduct(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_Name) ) СТОЙНОСТИ (47, 'MED162', 'Acadipiphane')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (48, 'MED163', 'Septomapin')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) , 'MED164', 'Acioxenal')INSERT dbo.MstProduct(ID, Pr oduct_ID, Product_Name) VALUES (50, 'MED165', 'Natadrolol')GOSET IDENTITY_INSERT dbo.MstProduct OFFGO
Изпълнете следната заявка, за да добавите данни към MstStock таблица:
вмъкнете в MstStock (Product_ID,Current_Stock,Last_Stock_Update_Date) стойности ('MED145',15,'2018-10-14'),('MED146',20,'2018-10-13'),'MED14 ,5,'2018-09-10'),('MED150',5,'2018-08-01'),('MED158',0,'2017-10-14'),('MED159',0 ,'2017-10-14')
Изпълнете следните „Select“ заявки, за да прегледате изхода от таблици.
Запитване:
Използвайте Product_MasterGoSelect * от MstProduct
Изход:
Запитване:
Използвайте Product_MasterGoSelect * от MstStock
Изход:
Второ, създайте изходна таблица с име TrnOrder в Подробности за инвентара база данни, намираща се на TTI412-VM1 сървър. Изпълнете следната заявка:
ИЗПОЛЗВАЙТЕ [Inventory_Details]GOCREATE TABLE [dbo].[TrnOrder]( [ID] [int] IDENTITY(1,1) НЕ NULL, [Product_ID] [varchar](15) НЕ NULL, [Ordered_Qty] [int] NULL, [Поредена_Дата] [дата и час] NULL, [Последна_Поредена_Дата] [дата и час] NULL, ПЪРВЕН КЛУСТЕР ( [ID] ASC) С (PAD_INDEX =ИЗКЛЮЧЕНО, STATISTICS_NORECOMPUTE =ИЗКЛЮЧЕНО, IGNORE_DUP_KEALLY =ИЗКЛ. [ОСНОВЕН],УНИКАЛЕН НЕКЛУСТРИРАН ([Product_ID] ASC)С (PAD_INDEX =ИЗКЛЮЧЕНО, STATISTICS_NORECOMPUTE =ИЗКЛЮЧЕНО, IGNORE_DUP_KEY =ИЗКЛЮЧЕНО, ALLOW_ROW_LOCKS =ВКЛ., ALLOW_PAGE_LOCKS =ON) [PRIMA>)] ВКЛ.Изпълнете следната заявка, за да добавите данни към MstStock таблица:
вмъкнете в TrnOrder (Product_ID,Ordered_Qty,Ordered_Date,Last_Ordered_Date)стойности ('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')Изпълнете следната заявка „Select“, за да прегледате изхода на таблицата.
Запитване:
Използвайте Inventory_DetailsGoSelect * от TrnOrderИзход:
Свържете се с отдалечен екземпляр на SQL Server, за да попълните данни
Както споменах, искаме да актуализираме стойностите в „таблица, която е създадена на отдалечен сървър. Имаме достъп до данни от отдалечен сървър на база данни, като използваме следните методи.
- Свързан сървър към SQL сървър :Свързаният сървър се използва за изпълнение на команда върху източник на данни OLEDB, който е свързан с отдалечен екземпляр на SQL Server. Използвайки свързан сървър, можете също да направите заявка за различни продукти за база данни като Oracle. OLEDB източниците могат да бъдат конфигурирани за достъп до Microsoft Access и Excel като свързан сървър.
- Функция OPENROWSET на SQL сървър :Използвайки функцията OPENROWSET, можем да изпълним Ad-Hoc заявка към отдалечения източник на данни OLEDB.
В тази статия ще използваме OPENROWSET метод за достъп до данните на отдалечената таблица. За да отправим заявка към отдалечен сървър с помощта на функцията OPENROWSET, трябва да активираме Ad hoc разпределени заявки конфигурационен параметър.
„Ad hoc разпределени заявки“ е разширена опция, следователно първо трябва да активираме Показване на разширените опции конфигурационен параметър. За да направите това, изпълнете следната команда в прозореца на заявката на студиото за управление на SQL Server.
exec sp_configure 'показване на разширени опции',1преконфигуриране с overrideGoСлед като Показване на разширената опция параметърът е активиран, изпълнете следната заявка, за да активирате Ad hoc разпределени заявки :
sp_configure 'Ad Hoc разпределени заявки', 1;ПРЕКОНФИГУРИРАЙТЕ С OVERRIDE;GOНе можем да използваме функцията “OPENROWSET” за извършване на операция MERGE, използвайки данни от отдалечен сървър. За да направим това първо трябва да импортираме данни от отдалечен сървър и да ги съхраняваме в глобалната временна таблица. След това можем да използваме данни, съдържащи се в глобалната временна таблица, за да актуализираме целевата таблица.
Както споменах, първо трябва да импортираме данни от отдалечената таблица. За да направите това, създайте временна таблица и импортирайте данни с помощта на функцията OPENROWSET.
Следната заявка ще създаде глобална временна таблица.използвайте 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] [date ] NULL, [Last_Ordered_Date] [datetime] NULL)След като временната таблица е създадена, нека заредим данни от таблица източник, която се намира на отдалечен сървър. За да направите това, изпълнете следната заявка:
вмъкнете в ##Source_Trn_Order изберете [Product_ID], [Ordered_Qty], [Ordered_Date], [Last_Ordered_Date] от OPENROWSET('SQLNCLI', 'Server=TTI609-VM1;Trusted_ID;,Quested_Connection;,Quested_Connection', Order_SELECT Ordered_Date,Last_Ordered_Date FROM Inventory_Details.dbo.TrnOrder') КАТО;Стъпка 1:Ако продукт съществува в MstStock (Целева таблица) и TrnOrder (Източна таблица), тогава актуализирайте текущото количество в MstStock
За да направите това, използвайте КОГАТО СЕ СЪВПАДА клауза. Клаузата обединява таблици Source и Target в общите колони на двете таблици. Product_ID колоната е често срещана между MstStock и ##Source_Trn_Table, следователно го използвайте, за да свържете двете таблици.
Изпълнете следния код:
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 =Last_Order_tock.Стойността на колоната Current_Stock от 4 продукта трябва да бъде актуализирана. Изпълнете следната заявка, за да проверите изхода:
изберете b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date от MstStock a вътрешно присъединяване MstProduct b на a.Product_ID=b.Product_ID и a.Current_Stock>0Следва изходът:
Стъпка 2:Ако продукт не съществува в MstStock (Целева таблица), тогава го добавете в MstStock (Целева таблица)
Аптечният магазин беше поръчал няколко продукта. Тези продукти бяха добавени в таблицата MstProduct, но не и към таблицата MstStock. За да добавите тези продукти в MstStock таблица, ще използвам клаузата WHEN NOT MATCHED [TARGET]. Клаузата обединява изходни и целеви таблици, използвайки общи колони. Ако съвпадащи редове не са открити в целевата таблица, той вмъква редове от таблицата източник.
За да добавите продукти към MstStock с помощта наСЛИВАНЕ таблица, изпълнете следния код:
ОБЛИВАЙТЕ mststock target_Stockusing ##source_trn_order Source_OrderON target_Stock.product_id =source_order.product_idWHEN съвпадение THEN UPDATE SET target_Stock.current_stock =Source_Order.ordered_qty =Вземете Current_Order.ordered_qty + target_Stock.ordered_qty + target_Stock.current_tock_da_tock_tock_tock THE_da_tock IN_STOCK last_stock_update_date) VALUES (Source_Order.product_id, Source_Order.ordered_qty, Getdate());Два идентификатора на продукта, MED169 и MED170, трябва да се добави. Изпълнете следната заявка, за да прегледате изхода:
изберете b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date от MstStock a вътрешно присъединяване MstProduct b на a.Product_ID=b.Product_ID и a.Current_Stock>0Извежда се следното:
Стъпка 3:Изтрийте артикул от MstStock (Целева таблица), ако текущата наличност в MstStock (Целева таблица) е нула и продуктът не е в ##Source_Trn_Order (изходна таблица)
В инвентара има малко продукти, които трябва да бъдат изтрити, защото не са поръчвани от една година. Следователно трябва да ги изтрием от MstStock таблица и таблицата MstProducts. За да изтриете тези продукти от MstStock таблица, можем да използваме КОГАТО НЕ СЪВПАДА [ИЗТОЧНИК] .
КОГАТО НЕ СЪВПАДА [ИЗТОЧНИК] клауза свързва изходни и целеви таблици, използвайки общи колони. Ако съвпадащи редове не бъдат намерени в таблицата източник, той изтрива редове от целевата таблица.
За да премахнете продукти от MstStock таблица, изпълнете следния код:
ОБЛИВАЙТЕ mststock target_Stockusing ##source_trn_order Source_OrderON target_Stock.product_id =source_order.product_idWHEN съвпадение THEN UPDATE SET target_Stock.current_stock =Source_Order.ordered_qty =Вземете Current_Order.ordered_qty + target_Stock.ordered_qty + target_Stock.current_tock_da_tock_tock_tock THE_da_tock IN_STOCK last_stock_update_date) СТОЙНОСТИ (Source_Order.product_id, Source_Order.ordered_qty, Getdate()) КОГАТО НЕ съвпадат ОТ SOURCE THEN DELETE;Два идентификатора на продукта, MED158 и MED159 трябва да се добави. Изпълнете следната заявка, за да прегледате изхода:
изберете b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date от MstStock a вътрешно присъединяване MstProduct b на a.Product_ID=b.Product_ID и a.Current_Stock>0Извежда се следното:
Резюме
В тази статия разгледах следното:
- Какво е ключова дума MERGE и как работи?
- Различни клаузи, използвани в MERGE за актуализиране на изходната и целевата таблица.
- Как да променям данни с помощта на ключова дума MERGE, когато базите данни са на различни сървъри.
Полезни инструменти:
dbForge Data Compare за SQL Server – мощен инструмент за сравнение на SQL, способен да работи с големи данни.