همگامسازی دادهها در SQL Server: راهنمای جامع MERGE برای INSERT، UPDATE و DELETE همزمان
دستور MERGE در SQL Server ابزاری قدرتمند برای همگامسازی آسان دادهها بین دو جدول است. این دستور پیچیدگیهای معمول در عملیات INSERT، UPDATE و DELETE همزمان را کاهش میدهد. پیش از معرفی MERGE، توسعهدهندگان SQL Server برای انجام عملیات همگامسازی، نیاز به نوشتن چندین دستور جداگانه INSERT، UPDATE و DELETE داشتند که این فرآیند را پیچیده و مستعد خطا میکرد. MERGE با امکان ترکیب این عملیات در یک دستور واحد، بهینهسازی و سادگی را برای مدیریت دادهها به ارمغان میآورد. این دستور برای سناریوهایی مانند بارگذاری انبوه دادهها یا همگامسازی تغییرات از یک منبع به یک جدول هدف بسیار مفید است.
دستور MERGE، شرایط مختلفی را برای مقایسه ردیفها بین جداول منبع و هدف فراهم میکند. این شرایط شامل WHEN MATCHED برای ردیفهای منطبق، WHEN NOT MATCHED BY TARGET (یا به اختصار WHEN NOT MATCHED) برای ردیفهایی که فقط در منبع وجود دارند، و WHEN NOT MATCHED BY SOURCE برای ردیفهایی که فقط در هدف وجود دارند، میشود. این انعطافپذیری به شما اجازه میدهد تا سناریوهای پیچیده همگامسازی دادهها را با یک دستور واحد و کارآمد پیادهسازی کنید.
در ادامه، نحوه عملکرد و کاربرد عملی دستور MERGE در SQL Server را با مثالهای کاربردی بررسی میکنیم تا به شما در تسلط بر این ابزار قدرتمند کمک کند. این رویکرد یکپارچه، کارایی مدیریت پایگاه داده را به طور چشمگیری بهبود میبخشد.
سینتکس عمومی دستور MERGE به شرح زیر است:
MERGE INTO AS TARGET
USING AS SOURCE
ON ()
WHEN MATCHED THEN
WHEN NOT MATCHED THEN
WHEN NOT MATCHED BY SOURCE THEN ;
برای درک بهتر، ابتدا دو جدول آزمایشی با نامهای ProductTarget و ProductSource ایجاد میکنیم. جدول ProductTarget به عنوان جدول اصلی یا هدف و ProductSource به عنوان منبع دادههای جدید یا بهروزرسانی شده استفاده خواهد شد.
CREATE TABLE ProductTarget
(
ProductID INT PRIMARY KEY,
ProductName VARCHAR(50),
Price DECIMAL(10, 2)
);
CREATE TABLE ProductSource
(
ProductID INT PRIMARY KEY,
ProductName VARCHAR(50),
Price DECIMAL(10, 2)
);
INSERT INTO ProductTarget (ProductID, ProductName, Price)
VALUES
(1, 'Laptop', 1200.00),
(2, 'Mouse', 25.00),
(3, 'Keyboard', 75.00),
(4, 'Monitor', 300.00);
INSERT INTO ProductSource (ProductID, ProductName, Price)
VALUES
(1, 'Laptop', 1250.00), -- Updated price for Laptop
(3, 'Gaming Keyboard', 80.00), -- Updated name and price for Keyboard
(5, 'Webcam', 50.00), -- New product
(6, 'Headphones', 100.00); -- New product
در این مثال، جدول ProductTarget شامل چهار محصول موجود است، در حالی که ProductSource شامل دو محصول موجود (با تغییرات) و دو محصول کاملاً جدید است. اکنون میتوانیم از دستور MERGE برای همگامسازی این دو جدول استفاده کنیم. دستور MERGE با استفاده از JOIN بر روی ProductID، عملیات بهروزرسانی (برای محصولات موجود با تغییر قیمت)، درج (برای محصولات جدید) و حذف (برای محصولاتی که در منبع نیستند) را انجام میدهد. این عملیات شامل بهروزرسانی قیمتها و نامها برای محصولات منطبق، و درج محصولات کاملاً جدید از منبع به هدف میشود.
MERGE ProductTarget AS TARGET
USING ProductSource AS SOURCE
ON (TARGET.ProductID = SOURCE.ProductID)
WHEN MATCHED THEN
UPDATE SET TARGET.ProductName = SOURCE.ProductName, TARGET.Price = SOURCE.Price
WHEN NOT MATCHED BY TARGET THEN
INSERT (ProductID, ProductName, Price) VALUES (SOURCE.ProductID, SOURCE.ProductName, SOURCE.Price)
OUTPUT $action, INSERTED.ProductID, INSERTED.ProductName, INSERTED.Price, DELETED.ProductID, DELETED.ProductName, DELETED.Price;
دستور MERGE میتواند شامل سه شرط اصلی باشد که هر یک عملیات خاصی را بر اساس وضعیت ردیفها بین جداول منبع و هدف انجام میدهند. این شرایط، انعطافپذیری زیادی را در مدیریت دادههای SQL Server فراهم میکنند.
* **TARGET و SOURCE**: این بخشها به ترتیب جدول هدف (که تغییرات روی آن اعمال میشود) و جدول منبع (که دادههای جدید یا بهروزرسانی شده از آن میآیند) را مشخص میکنند. در مثال ما، ProductTarget جدول هدف و ProductSource جدول منبع است.
* **ON (TARGET.ProductID = SOURCE.ProductID)**: این بند نحوه مقایسه ردیفها بین دو جدول را تعریف میکند. این یک شرط JOIN است که بر اساس آن، دستور MERGE تصمیم میگیرد که آیا یک ردیف در هر دو جدول وجود دارد، فقط در جدول منبع، یا فقط در جدول هدف.
* **WHEN MATCHED THEN UPDATE SET TARGET.ProductName = SOURCE.ProductName, TARGET.Price = SOURCE.Price**: این شرط زمانی فعال میشود که یک ردیف در هر دو جدول TARGET و SOURCE بر اساس شرط ON مطابقت داشته باشد. در این حالت، ردیف در جدول هدف با مقادیر از جدول منبع بهروزرسانی میشود. میتوانید به جای UPDATE، از DELETE نیز استفاده کنید تا ردیفهای منطبق را حذف کنید.
* **WHEN NOT MATCHED BY TARGET THEN INSERT (ProductID, ProductName, Price) VALUES (SOURCE.ProductID, SOURCE.ProductName, SOURCE.Price)**: این شرط زمانی اجرا میشود که یک ردیف در جدول SOURCE وجود داشته باشد اما هیچ ردیف منطبقی در جدول TARGET پیدا نشود. در این حالت، ردیف جدید از جدول منبع به جدول هدف درج میشود. این بند معادل WHEN NOT MATCHED است.
* **WHEN NOT MATCHED BY SOURCE THEN DELETE**: این شرط برای مدیریت ردیفهایی است که فقط در جدول TARGET وجود دارند و هیچ ردیف منطبقی در جدول SOURCE ندارند. در این حالت، ردیفهای اضافی از جدول هدف حذف میشوند. این بند به شما امکان میدهد تا جدول هدف را تمیز و همگام نگه دارید.
* **OUTPUT $action, INSERTED.ProductID, INSERTED.ProductName, INSERTED.Price, DELETED.ProductID, DELETED.ProductName, DELETED.Price**: بند OUTPUT به شما امکان میدهد اطلاعات مربوط به ردیفهایی که تحت تأثیر عملیات MERGE قرار گرفتهاند را بازیابی کنید. $action نوع عملیات انجام شده (INSERT، UPDATE، DELETE) را نشان میدهد. INSERTED ردیفهای جدید یا بهروزرسانی شده را نشان میدهد و DELETED ردیفهای حذف شده یا مقادیر اصلی ردیفهای بهروزرسانی شده را نمایش میدهد. این بند برای گزارشگیری و ثبت تغییرات در SQL Server بسیار مفید است.
برای نمایش قابلیت WHEN NOT MATCHED BY SOURCE، جدول ProductSource را تغییر میدهیم تا یکی از محصولات موجود در ProductTarget (مثلاً ‘Monitor’) در آن وجود نداشته باشد. سپس دستور MERGE را مجدداً اجرا میکنیم.
-- Clear and re-populate ProductSource to demonstrate WHEN NOT MATCHED BY SOURCE
TRUNCATE TABLE ProductSource;
INSERT INTO ProductSource (ProductID, ProductName, Price)
VALUES
(1, 'Laptop', 1260.00), -- Updated price again
(3, 'Wireless Keyboard', 85.00), -- Updated name and price
(5, 'Webcam Pro', 55.00); -- Updated name and price for existing new product
MERGE ProductTarget AS TARGET
USING ProductSource AS SOURCE
ON (TARGET.ProductID = SOURCE.ProductID)
WHEN MATCHED THEN
UPDATE SET TARGET.ProductName = SOURCE.ProductName, TARGET.Price = SOURCE.Price
WHEN NOT MATCHED BY TARGET THEN
INSERT (ProductID, ProductName, Price) VALUES (SOURCE.ProductID, SOURCE.ProductName, SOURCE.Price)
WHEN NOT MATCHED BY SOURCE THEN
DELETE
OUTPUT $action, INSERTED.ProductID, INSERTED.ProductName, INSERTED.Price, DELETED.ProductID, DELETED.ProductName, DELETED.Price;
در این اجرای دوم MERGE، محصول ‘Monitor’ (ProductID 4) که در ProductTarget بود اما در ProductSource جدید وجود ندارد، از جدول ProductTarget حذف خواهد شد. این نمونه قدرت MERGE را در همگامسازی کامل دادهها نشان میدهد.
**نکات مهم در استفاده از دستور MERGE:**
* **سمیکولن پایانی (;)**: همیشه دستور MERGE را با یک سمیکولن (`;`) به پایان برسانید. عدم استفاده از آن ممکن است منجر به خطای سینتکسی در نسخههای جدیدتر SQL Server شود.
* **عملکرد اتمیک**: دستور MERGE به عنوان یک عمل اتمیک (Atomic Operation) عمل میکند، به این معنی که کل عملیات یا به طور کامل با موفقیت انجام میشود یا به طور کامل بازگردانده میشود (Rollback). این ویژگی برای حفظ یکپارچگی دادهها در پایگاههای داده حیاتی است.
* **استفاده از OUTPUT**: بند OUTPUT برای بازبینی تغییرات اعمال شده توسط MERGE بسیار مفید است. این میتواند برای اهداف ممیزی یا گزارشگیری از عملیات SQL Server استفاده شود.
* **عملکرد TRIGGER**: دستور MERGE میتواند TRIGGERهای INSERT، UPDATE یا DELETE را بر روی جدول هدف فعال کند. این نکته مهمی است که باید هنگام طراحی راهحلهای همگامسازی داده در نظر گرفته شود.
استفاده از دستور MERGE فرآیند همگامسازی دادهها در SQL Server را سادهتر، کارآمدتر و قابل نگهداریتر میکند. این ابزار قدرتمند به متخصصان T-SQL و توسعهدهندگان پایگاه داده کمک میکند تا چالشهای مدیریت داده را با اطمینان بیشتری مدیریت کنند.
“`