sql >> Databáze >  >> RDS >> Database

SLOUČENÍ:Aktualizace zdrojových a cílových tabulek umístěných na samostatných serverech

Co je to příkaz MERGE?

Pomocí příkazu MERGE můžeme měnit data v cílové tabulce na základě dat ve zdrojové tabulce. Pomocí něj můžeme provádět INSERT, UPDATE a DELETE na cílových tabulkách v rámci jednoho bloku dotazu. Spojuje obě tabulky pomocí sloupců, společných v obou tabulkách jako primární klíč. Na základě toho, jak se data sloupce shodují, se změny vztahují na data cílové tabulky. Následující obrázek ukazuje, jak „SLOUČENÍ“ funguje:

Pomocí MERGE můžeme dosáhnout zlepšení výkonu, protože všechny tři operace (INSERT, UPDATE a DELETE ) se provádějí v jednom průchodu. K aktualizaci změn v cílové tabulce nepotřebujeme psát individuální příkaz.

Příkaz sloučení používáSourceTable a Destinationtable. Upravuje DestinationTable na základě dat SourceTable . Obě tabulky jsou porovnány pomocí podmínky definované v příkazu Merge. Tato podmínka určuje, jak se SourceTable shoduje s cílovou tabulkou. Je to jako podmínky spojení, které se používají ke spárování řádků.

Typicky by se shoda měla provádět pomocí shody jedinečných identifikátorů, jako jsou primární klíče. Například zdrojová tabulka je Nový produkt a cíl je Productmaster a primární klíč je ProductID , pak by podmínka sloučení měla být následující:

NewProduct.ProductID=ProductMaster.ProdID

Níže je uveden formát příkazu MERGE:

SLOUČIT cíl pomocí zdroje SON joinConditionWHEN MATCHEDTHEN updateQueryWHEN NOT MATCHED BY TARGETTHEN insertQueryWHEN NEPŘIPOJENÉHO BY SOURCETHEN deleteQuery

Chcete-li upravit data v cílové tabulce, MERGE podporuje následující klauzule T-SQL.

  1. PŘI SHODU
  2. KDYŽ NENÍ SHODA [PODLE CÍLE]
  3. KDYŽ NENÍ SHODA [PODLE ZDROJA]

Klauzule „WHEN MATCHED“

Tato klauzule se použije, když chceme aktualizovat nebo smazat záznamy v cílové tabulce. Zde jsou záznamy považovány za odpovídající, když jsou data ve spojených sloupcích stejná.

Klauzule „KDYŽ NENÍ SHODA [PODLE CÍLE]“

Pokud je záznam přítomen ve zdrojové tabulce, ale ne v cílové tabulce, bude tato klauzule použita k vložení nového záznamu do cílové tabulky.

Klauzule „KDYŽ NENÍ SHODA [PODLE ZDROJA]“

Tato klauzule se použije, když chceme smazat nebo aktualizovat záznam ve zdrojové tabulce, který neodpovídá řádku v cílové tabulce.

Použijte MERGE, když jsou zdroj a cíl na samostatném serveru

V tomto článku ukážu, jak provést operaci vložení, aktualizace a odstranění pomocí MERGE, když jsou zdrojové a cílové tabulky na samostatných serverech. Například farmaceutická společnost používá inventarizační software. Hlavní databáze softwaru a transakční databáze softwaru jsou na samostatných databázových serverech. Následuje nastavení:

Společnost přidala několik objednaných produktů. Chci provést několik procesů čištění a zároveň aktualizovat zásoby produktů. Následuje seznam úkolů, které je třeba provést.

  1. Pokud produkt existuje na skladě a stejný produkt byl objednán, aktualizujte a poté aktualizujte zásoby.
  2. Pokud produkt v inventáři neexistuje a je objednáno přidat produkt, přidejte produkt na skladě.
  3. Pokud produkt existuje na skladě, ale není objednán, zásoby produktu se neaktualizují déle než rok, než je odstranit produkt ze skladu.

K provedení výše uvedeného úkolu provedeme následující kroky:

  1. Vytvořte globální dočasnou tabulku s názvem ##Source_Trn_Tabl E. Vyplňte data z „TrnOrder ” (tabulka zdrojů) pomocí OPENROWSET příkazy a ukládejte data do ##Source_Trn_Table .
  2. Proveďte operace INSERT, UPDATE a DELETE na MstStock tabulky (cílová tabulka) pomocí SLOUČENÍ klíčové slovo, na základě následujících podmínek:
    • Pokud je hodnota ID_produktu sloupec existuje v ##Source_Trn_Table a zásoby a poté aktualizujte aktuální zásoby v MstStock stůl.
    • Pokud je hodnota ID_produktu sloupec existuje v ##Source_Trn_Table ale neexistuje v MstStock tabulky a poté přidejte produkt do MstStock stůl.
    • Pokud je hodnota ID_produktu v MstStock existuje sloupec ale neexistuje v ##Source_Trn_Tabl e, navíc hodnota sloupce last_stock_update_date je delší než rok, pak odstraňte product_id z MstStock stůl.

Následuje vývojový diagram:

Ukázka

Nejprve vytvořte cílovou tabulku s názvem MstStock a MstProduct na Product_Master databázi umístěnou na TTI412-VM2 server. Proveďte následující dotaz:

POUŽÍVEJTE [Product_Master]GOCREATE TABLE [dbo].[MstProduct]( [ID] [int] IDENTITY(1,1) NOT NULL, [ID_produktu] [varchar](15) NULL, [Název_produktu] [varchar]( 500) NENÍ NULL, PRIMÁRNÍ KLÍČ SE CLUSTERED ( [ID] ASC) S (PAD_INDEX =VYPNUTO, STATISTICS_NORECOMPUTE =VYPNUTO, IGNORE_DUP_KEY =VYPNUTO, ALLOW_ROW_LOCKS =ZAPNUTO, ALLOW_PAGE_LOCKS =ZAPNUTO) WIQUE PRODUKT UNTHIDEDRIMA ZAPNUTO (PAD_INDEX =VYPNUTO, STATISTICS_NORECOMPUTE =VYPNUTO, IGNORE_DUP_KEY =VYPNUTO, ALLOW_ROW_LOCKS =ZAPNUTO, ALLOW_PAGE_LOCKS =ZAPNUTO) ZAPNUTO [PRIMARY]) NA [PRIMARY]GOCREATE TABLE [dbo], [MstStock] [MstStock](1)(MstStock) 1) NOT NULL, [ID_produktu] [varchar](5) NOT NULL, [Current_Stock] [int] NULL, [Last_Stock_Update_Date] [datetime] NULL,PRIMARY KEY CLUSTERED ([ID] ASC)WITH (PAD_INDEX =VYPNUTO, STATISTIKA STATISTIKY) VYPNUTO, IGNORE_DUP_KEY =VYPNUTO, ALLOW_ROW_LOCKS =ZAPNUTO, ALLOW_PAGE_LOCKS =ZAPNUTO) ZAPNUTO [PRIMARY], UNIKÁTNÍ NEZAHRNUTÉ ( [Product_ID] ASC) S (WLOCK_INDEX =VYPNUTO, ON STATISTICS_NORECOMPUTE =WROUP_OFF,_KEY =VYPNUTO, WALGNORE =VYPNUTO AGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY]GO

Nyní přidejte některá data do obou tabulek.

Provedením následujícího dotazu přidejte data do MstProduct tabulka:

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, 24'MED19 'Zylasonmuc')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (30, 'MED143', 'Rythmoxabid')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (31, 'MED'Omedro') INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (32, 'MED145', 'Reducurzol')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (33, 'MED146', 'Losapuritriductdbo.IN) (ID, Product_ID, Product_Name) VALUES (34, 'MED147', 'Pipepapren')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (35, 'MED148', 'Miraperahex')INSERT dbo.MstProduct , Product_Name) VALUES (36, 'MED149', 'Durachloridevant') INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (37, 'MED151', 'Renachloridenide')INSERT dbo.MstProduct (ID, 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) VALUES (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', 'INSERTdbo') .MstProduct(ID, Product_ID, Product_Name) VALUES (43, 'MED157', 'Medrotraxel')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (44, 'MED158', 'Doxxaliq')MStProduct dbo , Product_ID, Product_Name) VALUES (45, 'MED159', 'Betatasine')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (46, 'MED161', 'Ciclopatex')INSERT dbo.MstProduct, Product_ID, Product_ID ) VALUES (47, 'MED162', 'Acadipiphane')INSERT dbo.MstProduct(ID, Product_ID, Product_Name) VALUES (48, 'MED163', 'Septomapin')INSERT dbo.MstProduct (ID, Product_ID, Product_ID, Product_9 , 'MED164', 'Acioxenal') INSERT dbo.MstProduct(ID, Pr oduct_ID, Product_Name) VALUES (50, 'MED165', 'Natadrolol')GOSET IDENTITY_INSERT dbo.MstProduct OFFGO

Provedením následujícího dotazu přidejte data do MstStock tabulka:

vložte do MstStock (Product_ID,Current_Stock,Last_Stock_Update_Date) hodnoty ('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')

Chcete-li zkontrolovat výstup tabulek, proveďte následující dotazy „Vybrat“.

Dotaz:

Použijte Product_MasterGoSelect * z MstProduct

Výstup:

Dotaz:

Použijte Product_MasterGoSelect * z MstStock

Výstup:

Zadruhé vytvořte zdrojovou tabulku s názvem TrnOrder na stránce Inventory_Details databázi umístěnou na TTI412-VM1 server. Proveďte následující dotaz:

POUŽÍVEJTE [Inventory_Details]GOCREATE TABLE [dbo].[TrnOrder]( [ID] [int] IDENTITY(1,1) NOT NULL, [ID_produktu] [varchar](15) NOT NULL, [Ordered_Qty] [int] NULL, [Ordered_Date] [datetime] NULL, [Last_Ordered_Date] [datetime] NULL,PRIMÁRNÍ KLÍČ SE SLUSTROVANÝ ([ID] ASC)WITH (PAD_INDEX =VYPNUTO, STATISTICS_NORECOMPUTE =VYPNUTO, IGNORE =_DUP_KEYAL_WLOW OFF_,_ALLO_KEYW =VYPNUTO) [PRIMARY], UNIKÁTNÍ NEZAHRNUTÉ ( [Product_ID] ASC) S (PAD_INDEX =VYPNUTO, STATISTICS_NORECOMPUTE =VYPNUTO, IGNORE_DUP_KEY =VYPNUTO, ALLOW_ROW_LOCKS =ZAPNUTO, ALLOW_PAGE_LOCKS =ZAPNUTO) ZAPNUTO [PRIMÁRNÍ] 

Provedením následujícího dotazu přidejte data do MstStock tabulka:

vložte do TrnOrder (ID_produktu,Objednané_množství,Ordered_Date,Last_Ordered_Date)hodnoty ('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')

Provedením následujícího dotazu „Select“ zkontrolujte výstup tabulky.

Dotaz:

Použijte Inventory_DetailsGoSelect * z TrnOrder

Výstup:

Připojte se ke vzdálené instanci SQL Serveru k naplnění dat

Jak jsem již zmínil, chceme aktualizovat hodnoty v „tabulce, která je vytvořena na vzdáleném serveru. K datům ze vzdáleného databázového serveru můžeme přistupovat pomocí následujících metod.

  1. Propojený server SQL Server :Propojený server se používá ke spuštění příkazu na zdroji dat OLEDB, který je propojen se vzdálenou instancí SQL Server. Pomocí propojeného serveru můžete také dotazovat různé databázové produkty, jako je Oracle. Zdroje OLEDB lze nakonfigurovat pro přístup k aplikacím Microsoft Access a Excel jako propojený server.
  2. Funkce SQL Server OPENROWSET :Pomocí funkce OPENROWSET můžeme provést dotaz Ad-Hoc na vzdálený zdroj dat OLEDB.

V tomto článku budeme používat OPENROWSET způsob přístupu k datům vzdálené tabulky. Abychom mohli dotazovat vzdálený server pomocí funkce OPENROWSET, musíme povolit Ad hoc distribuované dotazy konfigurační parametr.

„Ad hoc Distributed Queries“ je pokročilá možnost, proto musíme nejprve povolit Zobrazit rozšířenou možnost konfigurační parametr. Chcete-li to provést, spusťte následující příkaz v okně Query SQL Server management studio.

exec sp_configure 'zobrazit pokročilé možnosti',1reconfigure with overrideGo

Jakmile se zobrazí Zobrazit pokročilou možnost Pokud je parametr povolen, proveďte následující dotaz pro povolení Ad hoc distribuovaných dotazů :

sp_configure 'Ad Hoc Distribuované dotazy', 1;ZNOVU NAKONFIGURUJTE S PŘEPISEM;PŘEJÍT

Nemůžeme použít funkci „OPENROWSET“ k provedení operace MERGE pomocí dat vzdáleného serveru. K tomu musíme nejprve importovat data ze vzdáleného serveru a uložit je do globální dočasné tabulky. Poté můžeme použít data uložená v globální dočasné tabulce k aktualizaci cílové tabulky.

Jak jsem již zmínil, nejprve musíme importovat data ze vzdálené tabulky. Chcete-li to provést, vytvořte dočasnou tabulku a importujte data pomocí funkce OPENROWSET.
Následující dotaz vytvoří globální dočasnou tabulku.

použijte Product_MastergoCREATE TABLE ##Source_Trn_Order( [ID] [int] IDENTITY(1,1) NOT NULL, [ID_produktu] [varchar](15) NOT NULL, [Ordered_Qty] [int] NULL, [Ordered_Date] [datum a čas ] NULL, [Last_Ordered_Date] [datetime] NULL)

Jakmile je vytvořena dočasná tabulka, načtěte data ze zdrojové tabulky, která je umístěna na vzdáleném serveru. Chcete-li to provést, proveďte následující dotaz:

vložte do ##Source_Trn_Order vyberte [ID_produktu],[Objednané_množství],[Datum objednávky],[Poslední_objednané_Datum] z OPENROWSET('SQLNCLI', 'Server=TTI609-VM1;Trusted_Connection,'SELECTedQty_yes,'ty Ordered_Date,Last_Ordered_Date FROM Inventory_Details.dbo.TrnOrder') AS a;

Krok 1:Pokud produkt existuje v MstStock (cílová tabulka) a TrnOrder (tabulka zdrojů), aktualizujte aktuální množství v MstStock

Chcete-li to provést, použijte KDYŽ SE SHODA doložka. Klauzule spojuje zdrojové a cílové tabulky ve společných sloupcích obou tabulek. ID_produktu sloupec je společný pro MstStock a ##Source_Trn_Table, proto jej použijte ke spojení obou tabulek.

Spusťte následující kód:

 SLOUČIT MstStock target_StockUSING ##Source_Trn_Order Source_OrderON target_Stock.Product_Id =Source_Order.Product_Id KDYŽ SE SEŘÁDÁ POTOM AKTUALIZUJTE SET target_Stock.Current_Stock =Source_Order_Stock.Current_Stock =Source_Order.Update>Date Source_Order.Ordered_tockS; 

Hodnota sloupce Current_Stock 4 produktů by měla být aktualizována. Provedením následujícího dotazu ověřte výstup:

vyberte b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date z MstStock a vnitřní spojení MstProduct b na a.Product_ID=b.Product_ID a a.Current_Stock>0

Následuje výstup:

Krok 2:Pokud produkt neexistuje v MstStock (cílová tabulka), přidejte jej do MstStock (cílová tabulka)

Lékárna objednala několik produktů. Tyto produkty byly přidány do tabulky MstProduct, ale nebyly přidány do tabulky MstStock. Chcete-li tyto produkty přidat do MstStock tabulky, použiji klauzuli WHEN NOT MATCHED [TARGET]. Klauzule spojuje zdrojové a cílové tabulky pomocí společných sloupců. Pokud v cílové tabulce nejsou nalezeny odpovídající řádky, vloží řádky ze zdrojové tabulky.

Chcete-li přidat produkty do MstStock pomocíSLOUČENÍ tabulky, spusťte následující kód:

SLOUČIT mststock target_Stockusing ##source_trn_order Source_OrderON target_Stock.product_id =source_order.product_idWHEN spárováno POTOM AKTUALIZOVAT SET target_Stock.current_stock =Source_Order.ordered_qty,N target_Stock.current_stock_date Get_Stock.current_stock_stock, last_stock_CZ last_stock_update_date) VALUES (Source_Order.product_id, Source_Order.ordered_qty, Getdate());

Dvě ID produktů, MED169 a MED170, by mělo být přidáno. Chcete-li zkontrolovat výstup, spusťte následující dotaz:

vyberte b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date z MstStock a vnitřní spojení MstProduct b na a.Product_ID=b.Product_ID a a.Current_Stock>0

Následuje výstup:

Krok 3:Odstraňte položku z MstStock (cílová tabulka), pokud jsou aktuální zásoby v MstStock (cílová tabulka) nulové a produkt není v ##Source_Trn_Order (zdrojová tabulka)

V inventáři je málo produktů, které je třeba smazat, protože nebyly objednány již rok. Proto je musíme odstranit z MstStock tabulky a tabulky MstProducts. Chcete-li tyto produkty odstranit z MstStock tabulky, můžeme použít WHEN NOT MATCHED [SOURCE] .

KDYŽ SE NEPŘIDÍ [ZDROJ] klauzule spojuje zdrojové a cílové tabulky pomocí společných sloupců. Pokud ve zdrojové tabulce nejsou nalezeny odpovídající řádky, odstraní řádky z cílové tabulky.

Odebrání produktů z MstStock tabulky, spusťte následující kód:

SLOUČIT mststock target_Stockusing ##source_trn_order Source_OrderON target_Stock.product_id =source_order.product_idWHEN spárováno POTOM AKTUALIZOVAT SET target_Stock.current_stock =Source_Order.ordered_qty,N target_Stock.current_stock_date Get_Stock.current_stock_stock, last_stock_CZ last_stock_update_date) HODNOTY (Source_Order.product_id, Source_Order.ordered_qty, Getdate()), KDYŽ SE NEPŘIZDÁVÁ ZDROJ, PAK DELETE;

Dvě ID produktů, MED158 a MED159 by mělo být přidáno. Chcete-li zkontrolovat výstup, spusťte následující dotaz:

vyberte b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date z MstStock a vnitřní spojení MstProduct b na a.Product_ID=b.Product_ID a a.Current_Stock>0

Následuje výstup:

Shrnutí

V tomto článku jsem se zabýval následovně:

  1. Co je klíčové slovo MERGE a jak funguje?
  2. Různé klauzule používané v MERGE k aktualizaci zdrojové a cílové tabulky.
  3. Jak upravit data pomocí klíčového slova MERGE, když jsou databáze na různých serverech.

Užitečné nástroje:

dbForge Data Compare for SQL Server – výkonný nástroj pro porovnání SQL schopný pracovat s velkými daty.


  1. Rozdíl mezi literály N'String' a U'String' v Oracle

  2. Proč se SQL*Plus zavazuje při ukončení?

  3. Přesměrování vložení založené na spouštěči Postgres bez přerušení RETURNING

  4. STRING_SPLIT() v SQL Server 2016:Následná akce #1