Co to jest instrukcja MERGE?
Za pomocą instrukcji MERGE możemy zmienić dane w tabeli docelowej na podstawie danych w tabeli źródłowej. Za jego pomocą możemy wykonać INSERT, UPDATE i DELETE na docelowych tabelach w ramach jednego bloku zapytania. Łączy obie tabele za pomocą kolumn, wspólnych dla obu tabel, takich jak klucz podstawowy. W zależności od dopasowania danych w kolumnie, zmiany dotyczą danych tabeli docelowej. Poniższy obraz ilustruje, jak działa „MERGE”:
Używając MERGE, możemy uzyskać poprawę wydajności, ponieważ wszystkie trzy operacje (INSERT, UPDATE i DELETE ) są wykonywane w jednym przejściu. Nie musimy pisać indywidualnego oświadczenia, aby zaktualizować zmiany w tabeli docelowej.
Oświadczenie scalające wykorzystuje SourceTable i Targettable. Modyfikuje Tabelę docelową na podstawie danych SourceTable . Obie tabele są porównywane przy użyciu warunku zdefiniowanego w instrukcji Merge. Ten warunek określa, w jaki sposób SourceTable pasuje do tabeli docelowej. Przypomina to warunki łączenia, które są używane do dopasowywania wierszy.
Zazwyczaj dopasowanie powinno odbywać się poprzez dopasowanie unikalnych identyfikatorów, takich jak klucze podstawowe. Na przykład tabela źródłowa to NowyProdukt a miejsce docelowe to Productmaster, a klucz podstawowy to ProductID , to warunek scalenia powinien wyglądać następująco:
NewProduct.ProductID=ProductMaster.ProdID
Poniżej znajduje się format instrukcji MERGE:
MERGE target tUsing source son joinConditionGDY DOPASOWANETHEN updateQueryGDY NIE DOPASOWANE PRZEZ CEL insertQueryGDY NIE DOPASOWANE PRZEZ ŹRÓDŁOTHEN deleteQuery
Aby zmodyfikować dane w tabeli docelowej, MERGE obsługuje następujące klauzule T-SQL.
- GDY DOPASOWANO
- GDY NIE DOPASOWANO [WG CELU]
- GDY NIE DOPASOWANO [WG ŹRÓDŁA]
Klauzula „GDY DOPASOWANE”
Ta klauzula będzie używana, gdy chcemy zaktualizować lub usunąć rekordy w tabeli docelowej. Tutaj rekordy są uważane za zgodne, gdy dane w połączonych kolumnach są takie same.
Klauzula „GDY NIE DOPASOWANO [WEDŁUG CELU]”
Jeśli rekord jest obecny w tabeli źródłowej, ale nie w tabeli docelowej, ta klauzula zostanie użyta do wstawienia nowego rekordu do tabeli docelowej.
Klauzula „GDY NIE DOPASOWANO [WEDŁUG ŹRÓDŁA]”
Ta klauzula będzie używana, gdy chcemy usunąć lub zaktualizować rekord w tabeli źródłowej, który nie pasuje do wiersza w tabeli docelowej.
Użyj MERGE, gdy źródło i cel znajdują się na osobnym serwerze
W tym artykule zademonstruję, jak wykonać operację wstawiania, aktualizowania i usuwania za pomocą MERGE, gdy tabele źródłowa i docelowa znajdują się na osobnych serwerach. Na przykład firma farmaceutyczna korzysta z oprogramowania do inwentaryzacji. Bazy danych master oprogramowania i transakcyjne bazy danych oprogramowania znajdują się na osobnych serwerach bazodanowych. Oto konfiguracja:
Firma dodała kilka zamówionych produktów. Chcę wykonać kilka procesów porządkowych podczas aktualizacji zapasów produktów. Poniżej znajduje się lista zadań, które należy wykonać.
- Jeśli produkt znajduje się w magazynie i ten sam produkt został zamówiony, zaktualizuj, a następnie zaktualizuj stan magazynowy.
- Jeśli produkt nie istnieje w ekwipunku i dodaj produkt jest zamówiony, dodaj produkt w magazynie.
- Jeśli produkt istnieje w ekwipunku, ale nie jest zamówiony, ponadto zapas produktu nie jest aktualizowany przez ponad rok, niż usuń produkt z zapasów.
Aby wykonać powyższe zadanie, wykonamy następujące kroki:
- Utwórz globalną tabelę tymczasową o nazwie ##Source_Trn_Tabl mi. Wypełnij dane z „TrnOrder ” (Tabela źródeł) przy użyciu OPENROWSET polecenie i przechowuj dane w ##Source_Trn_Table .
- Wykonaj operacje INSERT, UPDATE i DELETE na MstStock tabeli (Tabela docelowa) za pomocą MERGE słowo kluczowe, na podstawie następujących warunków:
- Jeśli wartość ID_produktu kolumna istnieje w ##Source_Trn_Table i akcje tabeli, a następnie zaktualizuj bieżące zapasy w MstStock stół.
- Jeśli wartość ID_produktu kolumna istnieje w ##Source_Trn_Table ale nie istnieje w MstStock tabeli, a następnie dodaj produkt do MstStock stół.
- Jeśli wartość ID_produktu kolumna istnieje w MstStock ale nie istnieje w ##Source_Trn_Tabl e, ponadto wartość kolumny last_stock_update_date jest dłuższy niż rok, a następnie usuń product_id z MstStock stół.
Poniżej znajduje się schemat blokowy:
Demonstracja
Najpierw utwórz tabelę docelową o nazwie MstStock i MstProduct na Product_Master baza danych, znajdująca się na TTI412-VM2 serwer. Wykonaj następujące zapytanie:
USE [Product_Master]GOCREATE TABLE [dbo].[MstProduct]( [ID] [int] IDENTITY(1,1) NOT NULL, [Product_ID] [varchar](15) NULL, [Product_Name] [varchar]( 500) NIE NULL, GŁÓWNY KLUCZ KLASTRA ( [ID] ASC) Z (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY], UNIQUE NONCLUSTERED] ([)ID_produktu (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].[Mstock]( [ID] [int] IDENTITY (1,1) 1) NIE NULL, [Product_ID] [varchar] (5) NIE NULL, [Current_Stock] [int] NULL, [Last_Stock_Update_Date] [data/godzina] NULL, KLUCZ PODSTAWOWY ([ID] ASC) Z (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =WYŁĄCZONE, IGNORE_DUP_KEY =WYŁĄCZONE, ALLOW_ROW_LOCKS =WŁĄCZONE, ALLOW_PAGE_LOCKS =WŁĄCZONE) WŁĄCZONE [PRIMARY],UNIKALNE NIECLUSTROWANE ([ID_produktu] ASC) Z (PAD_INDEX =WYŁĄCZONE, STATISTICS_NORECOMPUTE =WYŁĄCZONE, IGNORE_DUP_KEY =WYŁĄCZONE, ALLOW_, AGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY]GO
Teraz dodaj trochę danych do obu tabel.
Wykonaj następujące zapytanie, aby dodać dane do MstProduct tabela:
SET IDENTITY_INSERT dbo.MstProduct ONGOINSERT dbo.MstProduct(ID, ID_produktu, Nazwa_produktu) WARTOŚCI (28, 'MED141', 'Alfimaxin')WSTAW dbo.MstProduct(ID, ID_produktu, Nazwa_produktu) WARTOŚCI (29, 'MED142', 'Zylasonmuc')WSTAW dbo.MstProduct(ID, Product_ID, Product_Name) WARTOŚCI (30, 'MED143', 'Rythmoksabid')WSTAW dbo.MstProduct(ID, Product_ID, Product_Name) WARTOŚCI (31, 'MED144', 'Omedrozol') WSTAW dbo.MstProduct(ID, Product_ID, Product_Name) WARTOŚCI (32, 'MED145', 'Reducurzol')WSTAW dbo.MstProduct(ID, Product_ID, Product_Name) WARTOŚCI (33, 'MED146', 'Losapuritriol')WSTAW dbo.MstProduct (ID, ID_produktu, Nazwa_produktu) WARTOŚCI (34, 'MED147', 'Pipepapren')WSTAW dbo.MstProduct(ID, ID_produktu, Nazwa_produktu) WARTOŚCI (35, 'MED148', 'Miraperahex')WSTAW dbo.MstProduct(ID, ID_produktu) , Nazwa_produktu) WARTOŚCI (36, 'MED149', 'Durachloridevant')WSTAW dbo.MstProduct(ID, ID_produktu, Nazwa_produktu) WARTOŚCI (37, 'MED151', 'Renachloriden')WSTAW dbo.MstProduct(ID, ID_produktu, Nazwa_produktu) WARTOŚCI (38, „MED152” ', 'Ecopurimuc')WSTAW dbo.MstProduct(ID, ID_produktu, Nazwa_produktu) WARTOŚCI (39, 'MED153', 'Aerocarpambid')WSTAW dbo.MstProduct(ID, ID_produktu, Nazwa_produktu) WARTOŚCI (40, 'MED154', 'Afsitec ')WSTAW dbo.MstProduct(ID, Product_ID, Product_Name) WARTOŚCI (41, 'MED155', 'Aprozovant')WSTAW dbo.MstProduct(ID, Product_ID, Product_Name) WARTOŚCI (42, 'MED156', 'Levopafen')WSTAW dbo .MstProduct(ID, Product_ID, Product_Name) WARTOŚCI (43, 'MED157', 'Medrotraxel')WSTAW dbo.MstProduct(ID, Product_ID, Product_Name) WARTOŚCI (44, 'MED158', 'Doxxaliq')INSERT dbo.MstProduct(ID , Product_ID, Product_Name) WARTOŚCI (45, 'MED159', 'Betatasine') WSTAW dbo.MstProduct(ID, Product_ID, Product_Name) WARTOŚCI (46, 'MED161', 'Ciclopatex')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) ) WARTOŚCI (47, 'MED162', 'Acadipiphane')WSTAW dbo.MstProduct(ID, ID_produktu, Nazwa_produktu) WARTOŚCI (48, 'MED163', 'Septomapin')WSTAW dbo.MstProduct(ID, ID_produktu, Nazwa_produktu) WARTOŚCI (49 , 'MED164', 'Acioxenal')WSTAW dbo.MstProduct(ID, Pr oduct_ID, Product_Name) WARTOŚCI (50, 'MED165', 'Natadrolol')GOSET IDENTITY_INSERT dbo.MstProduct OFFGO
Wykonaj następujące zapytanie, aby dodać dane do MstStock tabela:
wstaw do wartości MstStock (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”)
Wykonaj następujące zapytania „Wybierz”, aby przejrzeć dane wyjściowe tabel.
Zapytanie:
Użyj Product_MasterGoSelect * z MstProduct
Wyjście:
Zapytanie:
Użyj Product_MasterGoSelect * z MstStock
Wyjście:
Po drugie, utwórz tabelę źródłową o nazwie TrnOrder na Szczegóły_inwentaryzacji baza danych, znajdująca się na TTI412-VM1 serwer. Wykonaj następujące zapytanie:
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)Z (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_LOCKROW_LOCKS ON_S) =ON, [PRIMARY],UNIKALNE NIECLUSTROWANE ([Product_ID] ASC)Z (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY]GO
Wykonaj następujące zapytanie, aby dodać dane do MstStock tabela:
wstaw do TrnOrder (Product_ID,Ordered_Qty,Ordered_Date,Last_Ordered_Date)wartości ('MED145',10,convert(data,getdate()),'2018-10-14'),('MED146',5,convert( data,getdate()),'2018-10-13'),('MED147',15,convert(data,getdate()),'2018-09-10'),('MED150',200,convert( data,getdate()),'2018-08-01') ,('MED169',50,convert(data,getdate()),'2018-10-14'),('MED170',100,convert( data,getdate()), '2018-10-14')
Wykonaj następujące zapytanie „Wybierz”, aby przejrzeć dane wyjściowe tabeli.
Zapytanie:
Użyj Inventory_DetailsGoSelect * z TrnOrder
Wyjście:
Połącz się z instancją Remote SQL Server, aby wypełnić dane
Jak wspomniałem, chcemy zaktualizować wartości w „tabeli, która jest tworzona na zdalnym serwerze. Możemy uzyskać dostęp do danych ze zdalnego serwera bazy danych, korzystając z następujących metod.
- Serwer połączony z serwerem SQL :Serwer połączony służy do wykonywania polecenia na źródle danych OLEDB, które jest połączone ze zdalną instancją SQL Server. Korzystając z serwera połączonego, możesz również wysyłać zapytania do różnych produktów bazodanowych, takich jak Oracle. Źródła OLEDB można skonfigurować tak, aby uzyskiwały dostęp do programów Microsoft Access i Excel jako połączonego serwera.
- Funkcja OPENROWSET serwera SQL :Używając funkcji OPENROWSET, możemy wykonać zapytanie Ad-Hoc w zdalnym źródle danych OLEDB.
W tym artykule użyjemy OPENROWSET metoda dostępu do danych tabeli zdalnej. Aby wysłać zapytanie do serwera zdalnego za pomocą funkcji OPENROWSET, musimy włączyć Kwerendy rozproszone ad hoc parametr konfiguracyjny.
„Kwerendy rozproszone ad hoc” to opcja zaawansowana, dlatego najpierw musimy włączyć opcję Pokaż opcję zaawansowaną parametr konfiguracyjny. Aby to zrobić, wykonaj następujące polecenie w oknie Zapytania w studiu zarządzania SQL Server.
exec sp_configure 'pokaż opcje zaawansowane',1zmień konfigurację za pomocą overrideGo
Po Pokaż opcję zaawansowaną parametr jest włączony, wykonaj następujące zapytanie, aby włączyć Kwerendy rozproszone ad hoc :
sp_configure 'Kwerendy rozproszone ad hoc', 1;PONOWNIE KONFIGURUJ Z ZASTĄPIENIEM;GO
Nie możemy użyć funkcji „OPENROWSET” do wykonania operacji MERGE przy użyciu danych zdalnego serwera. Aby to zrobić najpierw musimy zaimportować dane ze zdalnego serwera i przechowywać je w globalnej tabeli tymczasowej. Następnie możemy użyć danych zawartych w globalnej tabeli tymczasowej do aktualizacji tabeli docelowej.
Jak wspomniałem, najpierw musimy zaimportować dane ze zdalnej tabeli. Aby to zrobić, utwórz tabelę tymczasową i zaimportuj dane za pomocą funkcji OPENROWSET.
Następujące zapytanie utworzy globalną tabelę tymczasową.
użyj tabeli Product_MastergoCREATE ##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)
Po utworzeniu tabeli tymczasowej załadujmy dane z tabeli źródłowej, która znajduje się na zdalnym serwerze. Aby to zrobić, wykonaj następujące zapytanie:
wstaw do ##Source_Trn_Order select [Product_ID],[Ordered_Qty],[Ordered_Date],[Last_Ordered_Date] z OPENROWSET('SQLNCLI', 'Server=TTI609-VM1;Trusted_Connection=yes;','SELECT_Qty_ID, Ordered_Qty, Order Ordered_Date,Last_Ordered_Date Z Inventory_Details.dbo.TrnOrder') JAKO a;
Krok 1:Jeśli produkt istnieje w MstStock (tabela docelowa) i TrnOrder (tabela źródeł), zaktualizuj bieżącą ilość w MstStock
Aby to zrobić, użyj GDY DOPASOWANO klauzula. Klauzula łączy tabele źródłowe i docelowe we wspólnych kolumnach obu tabel. ID_produktu kolumna jest wspólna dla MstStock i ##Source_Trn_Table, dlatego użyj go, aby połączyć oba stoły.
Wykonaj następujący kod:
MERGE MstStock target_StockUSING ##Source_Trn_Order Source_OrderON target_Stock.Product_Id =Source_Order.Product_Id KIEDY DOPASOWANO, A NASTĘPNIE AKTUALIZOWAĆ ZESTAW target_Stock.Current_Stock =Source_Order.Ordered_Qty + target_Stock_Gock>,CurD (Należy zaktualizować wartość kolumny Current_Stock 4 produktów. Wykonaj następujące zapytanie, aby zweryfikować dane wyjściowe:
wybierz b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date z MstStock sprzężenia wewnętrznego MstProduct b na a.Product_ID=b.Product_ID i a.Current_Stock>0Poniżej znajduje się wynik:
Krok 2:Jeśli produkt nie istnieje w MstStock (Tabela docelowa), dodaj go w MstStock (Tabela docelowa)
Apteka zamówiła kilka produktów. Te produkty zostały dodane do tabeli MstProduct, ale nie zostały dodane do tabeli MstStock. Aby dodać te produkty w MstStock tabeli, użyję klauzuli WHEN NOT MATCHED [TARGET]. Klauzula łączy tabele źródłową i docelową przy użyciu wspólnych kolumn. Jeśli pasujące wiersze nie zostaną znalezione w tabeli docelowej, wstawia wiersze z tabeli źródłowej.
Aby dodać produkty do MstStock za pomocą MERGE tabeli, wykonaj następujący kod:
MERGE mststock target_Stockusing ##source_trn_order Source_OrderON target_Stock.product_id =source_order.product_idGDY dopasowane TO AKTUALIZUJ ZESTAW target_Stock.current_stock =Source_Order.ordered_qty + target_Stock.current_stock, last_stock_update_date =NIE DOPASOWANO_PRODUKTU, KTÓRY_CEL last_stock_update_date) WARTOŚCI (Source_Order.product_id, Source_Order.ordered_qty, Getdate());Dwa identyfikatory produktów, MED169 i MED170, należy dodać. Wykonaj następujące zapytanie, aby przejrzeć dane wyjściowe:
wybierz b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date z MstStock sprzężenia wewnętrznego MstProduct b na a.Product_ID=b.Product_ID i a.Current_Stock>0Następujące dane wyjściowe:
Krok 3:Usuń pozycję z MstStock (tabela docelowa), jeśli bieżące zapasy w MstStock (tabela docelowa) wynoszą zero, a produkt nie znajduje się w ##Source_Trn_Order (tabeli źródłowej)
W inwentarzu jest niewiele produktów, które należy skreślić, ponieważ nie były zamawiane od roku. Dlatego musimy je usunąć z MstStock tabeli i tabeli MstProducts. Aby usunąć te produkty z MstStock tabeli, możemy użyć GDY NIE DOPASOWANO [ŹRÓDŁO] .
GDY NIE DOPASOWANO [ŹRÓDŁO] Klauzula łączy tabele źródłową i docelową przy użyciu wspólnych kolumn. Jeśli pasujące wiersze nie zostaną znalezione w tabeli źródłowej, usuwa wiersze z tabeli docelowej.
Aby usunąć produkty z MstStock tabeli, wykonaj następujący kod:
MERGE mststock target_Stockusing ##source_trn_order Source_OrderON target_Stock.product_id =source_order.product_idGDY dopasowane TO AKTUALIZUJ ZESTAW target_Stock.current_stock =Source_Order.ordered_qty + target_Stock.current_stock, last_stock_update_date =NIE DOPASOWANO_PRODUKTU, KTÓRY_CEL last_stock_update_date) WARTOŚCI (Source_Order.product_id, Source_Order.ordered_qty, Getdate()) JEŚLI NIE są dopasowane WEDŁUG ŹRÓDŁA, NASTĘPNIE USUŃ;Dwa identyfikatory produktów, MED158 i MED159 należy dodać. Wykonaj następujące zapytanie, aby przejrzeć dane wyjściowe:
wybierz b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date z MstStock sprzężenia wewnętrznego MstProduct b na a.Product_ID=b.Product_ID i a.Current_Stock>0Następujące dane wyjściowe:
Podsumowanie
W tym artykule omówiłem następujące kwestie:
- Co to jest słowo kluczowe MERGE i jak ono działa?
- Różne klauzule używane w MERGE do aktualizacji tabeli źródłowej i docelowej.
- Jak modyfikować dane za pomocą słowa kluczowego MERGE, gdy bazy danych znajdują się na różnych serwerach.
Przydatne narzędzia:
dbForge Data Compare dla SQL Server – potężne narzędzie do porównywania SQL zdolne do pracy z dużymi danymi.