Database
 sql >> Datenbank >  >> RDS >> Database

MERGE:Aktualisieren von Quell- und Zieltabellen, die sich auf separaten Servern befinden

Was ist die MERGE-Anweisung?

Mit der MERGE-Anweisung können wir Daten in einer Zieltabelle basierend auf Daten in einer Quelltabelle ändern. Damit können wir INSERT, UPDATE und DELETE für die Zieltabellen innerhalb eines einzigen Abfrageblocks ausführen. Es verbindet beide Tabellen mit Spalten, die in beiden Tabellen wie der Primärschlüssel gemeinsam sind. Je nachdem, wie die Spaltendaten übereinstimmen, gelten Änderungen für die Daten der Zieltabelle. Das folgende Bild zeigt, wie „MERGE“ funktioniert:

Mit MERGE können wir die Leistung verbessern, da alle drei Operationen (INSERT, UPDATE und DELETE ) werden in einem Durchgang durchgeführt. Wir müssen keine individuelle Anweisung schreiben, um Änderungen in der Zieltabelle zu aktualisieren.

Die Merge-Anweisung verwendet SourceTable und Zieltabelle. Es modifiziert DestinationTable basierend auf den Daten von SourceTable . Beide Tabellen werden anhand der in der Merge-Anweisung definierten Bedingung verglichen. Diese Bedingung bestimmt, wie SourceTable mit der Zieltabelle übereinstimmt. Es ist wie Join-Bedingungen, die verwendet werden, um Zeilen abzugleichen.

Typischerweise sollte der Abgleich durch den Abgleich eindeutiger Bezeichner wie Primärschlüssel erfolgen. Die Quelltabelle ist beispielsweise NewProduct und Ziel ist Productmaster und der Primärschlüssel ist ProductID , dann sollte die Zusammenführungsbedingung wie folgt lauten:

NewProduct.ProductID=ProductMaster.ProdID

Es folgt das Format der MERGE-Anweisung:

MERGE target t
Using source s
ON joinCondition
WHEN MATCHED
THEN updateQuery
WHEN NOT MATCHED BY TARGET
THEN insertQuery
WHEN NOT MATCHED BY SOURCE
THEN deleteQuery

Um die Daten in der Zieltabelle zu ändern, unterstützt MERGE die folgenden T-SQL-Klauseln.

  1. WENN ÜBEREINGEKOMMEN
  2. WENN NICHT ÜBEREINGEKOMMEN [DURCH ZIEL]
  3. WENN NICHT ÜBEREINSTIMMT [NACH QUELLE]

"WHEN MATCHED"-Klausel

Diese Klausel wird verwendet, wenn wir die Datensätze in der Zieltabelle aktualisieren oder löschen möchten. Hier gelten Datensätze als übereinstimmend, wenn die Daten in den verbundenen Spalten gleich sind.

"WHEN NOT MATCHED [BY TARGET]"-Klausel

Wenn der Datensatz in der Quelltabelle, aber nicht in der Zieltabelle vorhanden ist, wird diese Klausel verwendet, um einen neuen Datensatz in die Zieltabelle einzufügen.

"WHEN NOT MATCHED [BY SOURCE]"-Klausel

Diese Klausel wird verwendet, wenn wir einen Datensatz in einer Quelltabelle löschen oder aktualisieren möchten, der nicht mit einer Zeile in der Zieltabelle übereinstimmt.

Verwenden Sie MERGE, wenn sich Quelle und Ziel auf einem separaten Server befinden

In diesem Artikel werde ich demonstrieren, wie Einfüge-, Aktualisierungs- und Löschoperationen mit MERGE durchgeführt werden, wenn sich die Quell- und Zieltabellen auf separaten Servern befinden. Beispielsweise verwendet ein Pharmaunternehmen eine Bestandssoftware. Masterdatenbanken einer Software und Transaktionsdatenbanken einer Software befinden sich auf separaten Datenbankservern. Das Folgende ist ein Setup:

Das Unternehmen hat ein paar bestellte Produkte hinzugefügt. Ich möchte einige Bereinigungsvorgänge durchführen, während ich den Produktbestand aktualisiere. Es folgt die Liste der Aufgaben, die durchgeführt werden müssen.

  1. Wenn ein Produkt im Bestand vorhanden ist und dasselbe Produkt bestellt wurde, aktualisieren Sie dann den Bestand.
  2. Wenn ein Produkt nicht im Inventar vorhanden ist und ein Produkt hinzugefügt wird, dann fügen Sie das Produkt auf Lager hinzu.
  3. Wenn das Produkt im Bestand vorhanden ist, aber nicht bestellt wird, wird der Bestand des Produkts länger als ein Jahr nicht aktualisiert, als das Produkt aus dem Bestand zu löschen.

Um die oben genannte Aufgabe auszuführen, führen wir die folgenden Schritte aus:

  1. Erstellen Sie eine globale temporäre Tabelle namens ##Source_Trn_Tabl e. Füllen Sie Daten aus „TrnOrder aus ” (Quelltabelle) mit dem OPENROWSET befehlen und Daten in ##Source_Trn_Table speichern .
  2. Führen Sie die Operationen INSERT, UPDATE und DELETE auf dem MstStock durch Tabelle (Target Table) mit MERGE Schlüsselwort, basierend auf den folgenden Bedingungen:
    • Wenn der Wert der Product_ID Spalte existiert in ##Source_Trn_Table und die Aktie Tabelle und aktualisieren Sie dann den aktuellen Lagerbestand in MstStock Tabelle.
    • Wenn der Wert der Product_ID Spalte existiert in ##Source_Trn_Table existiert aber nicht im MstStock Tabelle und fügen Sie dann ein Produkt zum MstStock hinzu Tabelle.
    • Wenn der Wert der Product_ID Spalte existiert in MstStock existiert aber nicht in ##Source_Trn_Tabl e, außerdem der Spaltenwert von last_stock_update_date länger als ein Jahr ist, dann löschen Sie product_id aus dem MstStock Tabelle.

Es folgt das Flussdiagramm:

Demonstration

Erstellen Sie zunächst eine Zieltabelle mit dem Namen MstStock und MstProduct auf dem Product_Master Datenbank, die sich auf dem TTI412-VM2 befindet Server. Führen Sie die folgende Abfrage aus:

USE [Product_Master]
GO
CREATE TABLE [dbo].[MstProduct](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[Product_ID] [varchar](15) NULL,
	[Product_Name] [varchar](500) NOT NULL,
PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
UNIQUE NONCLUSTERED 
(
	[Product_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE 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,
PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
UNIQUE NONCLUSTERED 
(
	[Product_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

Fügen Sie nun beiden Tabellen einige Daten hinzu.

Führen Sie die folgende Abfrage aus, um Daten zu MstProduct hinzuzufügen Tabelle:

SET IDENTITY_INSERT dbo.MstProduct ON
GO
INSERT 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', '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) 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, Product_ID, Product_Name) VALUES (50, 'MED165', 'Natadrolol')
GO
SET IDENTITY_INSERT dbo.MstProduct OFF
GO

Führen Sie die folgende Abfrage aus, um Daten zum MstStock hinzuzufügen Tabelle:

insert into MstStock (Product_ID,Current_Stock,Last_Stock_Update_Date) values ('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')

Führen Sie die folgenden „Select“-Abfragen aus, um die Ausgabe von Tabellen zu überprüfen.

Abfrage:

Use Product_Master
Go
Select * from MstProduct

Ausgabe:

Abfrage:

Use Product_Master
Go
Select * from MstStock

Ausgabe:

Zweitens erstellen Sie eine Quelltabelle mit dem Namen TrnOrder in den Inventar_Details Datenbank, die sich auf dem TTI412-VM1 befindet Server. Führen Sie die folgende Abfrage aus:

USE [Inventory_Details]
GO
CREATE 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_PAGE_LOCKS = ON) ON [PRIMARY],
UNIQUE NONCLUSTERED 
(
	[Product_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

Führen Sie die folgende Abfrage aus, um Daten zum MstStock hinzuzufügen Tabelle:

insert into TrnOrder (Product_ID,Ordered_Qty,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')

Führen Sie die folgende „Select“-Abfrage aus, um die Ausgabe der Tabelle zu überprüfen.

Abfrage:

Use Inventory_Details
Go
Select * from TrnOrder

Ausgabe:

Mit Remote SQL Server-Instanz verbinden, um Daten aufzufüllen

Wie ich bereits erwähnt habe, möchten wir die Werte in „Tabelle aktualisieren, die auf einem Remote-Server erstellt wird. Wir können mit den folgenden Methoden auf Daten von einem entfernten Datenbankserver zugreifen.

  1. SQL Server-Verbindungsserver :Der Verbindungsserver wird verwendet, um einen Befehl auf einer OLEDB-Datenquelle auszuführen, die mit einer entfernten SQL Server-Instanz verknüpft ist. Mit einem Verbindungsserver können Sie auch andere Datenbankprodukte wie Oracle abfragen. OLEDB-Quellen können so konfiguriert werden, dass sie als Verbindungsserver auf Microsoft Access und Excel zugreifen.
  2. SQL Server OPENROWSET-Funktion :Mit der OPENROWSET-Funktion können wir eine Ad-Hoc-Abfrage auf der entfernten OLEDB-Datenquelle ausführen.

In diesem Artikel verwenden wir das OPENROWSET Methode, um auf Daten der entfernten Tabelle zuzugreifen. Um einen Remote-Server mit der OPENROWSET-Funktion abzufragen, müssen wir die Ad hoc Distributed Queries aktivieren Konfigurationsparameter.

„Ad hoc Distributed Queries“ ist eine erweiterte Option, daher müssen wir zuerst die Erweiterte Option anzeigen aktivieren Konfigurationsparameter. Führen Sie dazu den folgenden Befehl im Abfragefenster von SQL Server Management Studio aus.

exec sp_configure 'show advanced options',1
reconfigure with override
Go

Einmal die Erweiterte Option anzeigen Parameter aktiviert ist, führen Sie die folgende Abfrage aus, um Verteilte Ad-hoc-Abfragen zu aktivieren :

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

Wir können die „OPENROWSET“-Funktion nicht verwenden, um MERGE-Operationen mit Daten des Remote-Servers durchzuführen. Dazu müssen wir zuerst Daten vom Remote-Server importieren und in der globalen temporären Tabelle speichern. Danach können wir Daten aus der globalen temporären Tabelle verwenden, um die Zieltabelle zu aktualisieren.

Wie ich bereits erwähnt habe, müssen wir zunächst Daten aus der Remote-Tabelle importieren. Erstellen Sie dazu eine temporäre Tabelle und importieren Sie Daten mit der Funktion OPENROWSET.
Die folgende Abfrage erstellt eine globale temporäre Tabelle.

use Product_Master
go
CREATE 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
)

Nachdem die temporäre Tabelle erstellt wurde, laden wir Daten aus einer Quelltabelle, die sich auf einem Remote-Server befindet. Führen Sie dazu die folgende Abfrage aus:

insert into ##Source_Trn_Order select [Product_ID],[Ordered_Qty],[Ordered_Date],[Last_Ordered_Date]  from 
OPENROWSET('SQLNCLI', 'Server=TTI609-VM1;Trusted_Connection=yes;',
'SELECT Product_ID, Ordered_Qty, Ordered_Date,Last_Ordered_Date FROM Inventory_Details.dbo.TrnOrder') AS a;

Schritt 1:Wenn ein Produkt in MstStock (Zieltabelle) und TrnOrder (Quelltabelle) vorhanden ist, aktualisieren Sie die aktuelle Menge in MstStock

Verwenden Sie dazu WHEN MATCHED Klausel. Die Klausel verbindet Quell- und Zieltabellen in den gemeinsamen Spalten beider Tabellen. Die Product_ID Spalte ist gemeinsam zwischen MstStock und ##Source_Trn_Table, Verwenden Sie es daher, um beide Tabellen zu verknüpfen.

Führen Sie den folgenden Code aus:

 MERGE MstStock target_Stock
USING ##Source_Trn_Order Source_Order
ON target_Stock.Product_Id = Source_Order.Product_Id 
WHEN MATCHED THEN
  UPDATE
  SET target_Stock.Current_Stock = Source_Order.Ordered_Qty + target_Stock.Current_Stock, 
Last_Stock_Update_Date=getdate();

Der Wert der Spalte Current_Stock von 4 Produkten sollte aktualisiert werden. Führen Sie die folgende Abfrage aus, um die Ausgabe zu überprüfen:

select b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date from MstStock a inner join MstProduct b on a.Product_ID=b.Product_ID and a.Current_Stock>0

Es folgt die Ausgabe:

Schritt 2:Wenn ein Produkt nicht in MstStock (Zieltabelle) existiert, fügen Sie es in MstStock (Zieltabelle) hinzu

Apotheke hatte ein paar Produkte bestellt. Diese Produkte wurden der MstProduct-Tabelle hinzugefügt, aber nicht der MstStock-Tabelle. Um diese Produkte zum MstStock hinzuzufügen Tabelle verwende ich die WHEN NOT MATCHED [TARGET]-Klausel. Die Klausel verknüpft Quell- und Zieltabellen mithilfe gemeinsamer Spalten. Wenn in der Zieltabelle keine übereinstimmenden Zeilen gefunden werden, werden Zeilen aus der Quelltabelle eingefügt.

Um Produkte zu MstStock hinzuzufügen Verwenden Sie die MISCHEN Tabelle, führen Sie den folgenden Code aus:

MERGE mststock target_Stock
using ##source_trn_order Source_Order
ON target_Stock.product_id = source_order.product_id
WHEN matched THEN
  UPDATE SET target_Stock.current_stock = Source_Order.ordered_qty
                                          + target_Stock.current_stock,
             last_stock_update_date = Getdate()
WHEN NOT matched BY target THEN
  INSERT (product_id,
          current_stock,
          last_stock_update_date)
  VALUES (Source_Order.product_id,
          Source_Order.ordered_qty,
          Getdate());

Zwei Produkt-IDs, MED169 und MED170, sollte hinzugefügt werden. Führen Sie die folgende Abfrage aus, um die Ausgabe zu überprüfen:

select b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date from MstStock a inner join MstProduct b on a.Product_ID=b.Product_ID and a.Current_Stock>0

Folgendes wird ausgegeben:

Schritt 3:Artikel aus MstStock (Zieltabelle) löschen, wenn der aktuelle Bestand in MstStock (Zieltabelle) Null ist und das Produkt nicht in ##Source_Trn_Order (Quelltabelle)

ist

Im Inventar gibt es einige Produkte, die gelöscht werden müssen, da diese seit einem Jahr nicht mehr bestellt wurden. Daher müssen wir sie aus dem MstStock löschen -Tabelle und die MstProducts-Tabelle. Um diese Produkte aus dem MstStock zu löschen Tabelle können wir WHEN NOT MATCHED [SOURCE] verwenden .

Die WENN NICHT ÜBEREINSTIMMT [QUELLE] -Klausel verknüpft Quell- und Zieltabellen mithilfe gemeinsamer Spalten. Wenn in der Quelltabelle keine übereinstimmenden Zeilen gefunden werden, werden Zeilen aus der Zieltabelle gelöscht.

Um Produkte aus dem MstStock zu entfernen Tabelle, führen Sie den folgenden Code aus:

MERGE mststock target_Stock
using ##source_trn_order Source_Order
ON target_Stock.product_id = source_order.product_id
WHEN matched THEN
  UPDATE SET target_Stock.current_stock = Source_Order.ordered_qty
                                          + target_Stock.current_stock,
             last_stock_update_date = Getdate()
WHEN NOT matched BY target THEN
  INSERT (product_id,
          current_stock,
          last_stock_update_date)
  VALUES (Source_Order.product_id,
          Source_Order.ordered_qty,
          Getdate())  
WHEN NOT matched BY SOURCE THEN
  DELETE;

Zwei Produkt-IDs, MED158 und MED159 sollte hinzugefügt werden. Führen Sie die folgende Abfrage aus, um die Ausgabe zu überprüfen:

select b.Product_ID,b.Product_Name,a.Current_Stock,a.Last_Stock_Update_Date from MstStock a inner join MstProduct b on a.Product_ID=b.Product_ID and a.Current_Stock>0

Folgendes wird ausgegeben:

Zusammenfassung

In diesem Artikel habe ich Folgendes behandelt:

  1. Was ist das Schlüsselwort MERGE und wie funktioniert es?
  2. Verschiedene Klauseln, die in MERGE verwendet werden, um die Quell- und Zieltabelle zu aktualisieren.
  3. Wie man Daten mit dem Schlüsselwort MERGE ändert, wenn sich Datenbanken auf verschiedenen Servern befinden.

Nützliche Tools:

dbForge Data Compare for SQL Server – leistungsstarkes SQL-Vergleichstool, das mit großen Datenmengen arbeiten kann.