آپدیت داده در SQL Server: راهنما جامع UPDATE، FROM، JOIN و MERGE برای عملکرد بهینه
دستور UPDATE
در SQL Server برای اصلاح رکوردهای موجود در یک جدول استفاده میشود. این دستور به شما امکان میدهد تا مقادیر یک یا چند ستون را برای یک زیرمجموعه خاص از ردیفها یا برای تمام ردیفهای یک جدول تغییر دهید. درک نحوه استفاده مؤثر از UPDATE
با عباراتی مانند FROM
، JOIN
و MERGE
برای مدیریت کارآمد دادهها حیاتی است.
روش استاندارد برای به روز رسانی یک جدول شامل تعیین دستور UPDATE
و سپس نام جدول هدف است. این نام جدول را میتوان به صورت زیر در نظر گرفت:
table_name
پس از آن، عبارت SET
که شامل ستونها و مقادیری است که باید به روز شوند، و یک عبارت WHERE
برای فیلتر کردن ردیفها میآید. ساختار اصلی این دستور به شرح زیر است:
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
این ساختار به شما امکان میدهد تا مقادیر را به صورت مستقیم در یک جدول هدف بر اساس شرایط مشخص شده به روز کنید. برای مثال، فرض کنید میخواهیم اطلاعات یک شخص را در جدول Person.Person
در پایگاه داده AdventureWorks2019
به روز رسانی کنیم:
USE AdventureWorks2019;
GO
UPDATE Person.Person
SET FirstName = 'Roberto', LastName = 'Tamburello'
WHERE BusinessEntityID = 1;
این کوئری ستونهای FirstName
و LastName
را برای ردیفی که BusinessEntityID
آن برابر با 1 است، به روز میکند. اگر عبارت WHERE
حذف شود، تمام ردیفهای جدول تحت تأثیر قرار میگیرند.
در برخی موارد، نیاز به به روز رسانی یک جدول بر اساس دادههای موجود در جداول دیگر است. عبارت FROM
در دستور UPDATE
، که ساختار آن به صورت زیر است:
FROM table_source
روشی قدرتمند برای انجام این کار فراهم میکند. این عبارت به شما امکان میدهد تا دادهها را از چندین منبع بازیابی کرده و برای به روز رسانی جدول هدف استفاده کنید.
UPDATE T1
SET T1.column = T2.column
FROM table1 T1 JOIN table2 T2 ON T1.id = T2.id
WHERE condition;
این نمونه نحوه ارجاع به جداول T1
و T2
را در عبارت FROM
نشان میدهد و سپس مقادیر را از T2
به T1
منتقل میکند. برای نشان دادن این قابلیت، میتوانیم از جدول Sales.Store
و Sales.Customer
در AdventureWorks2019
استفاده کنیم.
ابتدا، دو جدول موقت ایجاد میکنیم تا دادههای نمونه برای نمایش داشته باشیم:
DROP TABLE IF EXISTS #SalesStore;
CREATE TABLE #SalesStore (
BusinessEntityID INT,
Name NVARCHAR(50),
SalesPersonID INT
);
INSERT INTO #SalesStore (BusinessEntityID, Name, SalesPersonID)
SELECT BusinessEntityID, Name, SalesPersonID
FROM Sales.Store
WHERE BusinessEntityID IN (292, 294, 296, 298, 300);
DROP TABLE IF EXISTS #SalesCustomer;
CREATE TABLE #SalesCustomer (
CustomerID INT,
PersonID INT,
StoreID INT,
TerritoryID INT,
AccountNumber NVARCHAR(10)
);
INSERT INTO #SalesCustomer (CustomerID, PersonID, StoreID, TerritoryID, AccountNumber)
SELECT CustomerID, PersonID, StoreID, TerritoryID, AccountNumber
FROM Sales.Customer
WHERE StoreID IN (292, 294, 296, 298, 300);
حال، فرض کنید میخواهیم ستون StoreID
در جدول #SalesCustomer
را بر اساس BusinessEntityID
متناظر در #SalesStore
به روز کنیم. در اینجا BusinessEntityID
در #SalesStore
با StoreID
در #SalesCustomer
مطابقت دارد:
UPDATE SC
SET SC.StoreID = SS.BusinessEntityID
FROM #SalesCustomer AS SC
INNER JOIN #SalesStore AS SS
ON SC.StoreID = SS.BusinessEntityID
WHERE SC.CustomerID = 11185;
این کوئری، StoreID
مشتری با CustomerID
11185 را با BusinessEntityID
مربوطه از #SalesStore
به روز میکند. این یک راه حل ساده و رایج برای به روز رسانی دادهها از یک جدول منبع است.
برای به روز رسانیهای شرطی که نیاز به ارزیابی پیچیدهتری دارند، میتوان از عبارت FROM
با یک JOIN
داخلی (INNER JOIN
) استفاده کرد. این امکان به روز رسانی ردیفها را فقط در صورتی که شرط JOIN
برآورده شود، فراهم میکند. این رویکرد به ویژه زمانی مفید است که شما میخواهید فقط رکوردهای خاصی را بر اساس معیارهای منطبق از یک جدول دیگر تغییر دهید.
UPDATE SC
SET SC.StoreID = 302
FROM #SalesCustomer AS SC
INNER JOIN #SalesStore AS SS
ON SC.StoreID = SS.BusinessEntityID
WHERE SC.BusinessEntityID = 292;
مثال بالا کمی متفاوت است؛ اگر BusinessEntityID
از #SalesCustomer
(که قبلاً ایجاد نشده است) استفاده کند، کار نمیکند. یک مثال بهتر میتواند این باشد که StoreID
را در #SalesCustomer
برای مشتریانی که StoreID
آنها در #SalesStore
وجود دارد، به روز کنیم. اگر میخواهیم StoreID
را برای رکوردهای خاصی بر اساس تطابق در #SalesStore
به یک مقدار ثابت (مثلاً 302) تغییر دهیم:
UPDATE SC
SET SC.StoreID = 302
FROM #SalesCustomer AS SC
INNER JOIN #SalesStore AS SS
ON SC.StoreID = SS.BusinessEntityID
WHERE SC.StoreID = 292; -- Assuming StoreID in #SalesCustomer matches BusinessEntityID in #SalesStore
در SQL Server، عبارت UPDATE
همراه با عبارت JOIN
یک سینتکس قدرتمند برای به روز رسانی یک جدول بر اساس دادههای جداول دیگر است. ساختار کلی JOIN
به این صورت است:
JOIN | APPLY
این روش معمولاً در سناریوهایی به کار میرود که دادههای به روز رسانی شده از یک یا چند جدول مرتبط میآیند. دستور UPDATE
با JOIN
یک سینتکس قدرتمند برای انجام به روز رسانیهای پیچیده فراهم میکند.
UPDATE SC
SET SC.AccountNumber = 'AW' + CONVERT(NVARCHAR(10), SC.CustomerID)
FROM #SalesCustomer AS SC
INNER JOIN #SalesStore AS SS
ON SC.StoreID = SS.BusinessEntityID
WHERE SS.BusinessEntityID = 292;
این کوئری AccountNumber
را برای مشتریانی که StoreID
آنها با BusinessEntityID
292 در #SalesStore
مطابقت دارد، به روز میکند و یک شماره حساب جدید با فرمت ‘AW’ + CustomerID
ایجاد میکند.
استفاده از LEFT JOIN
در UPDATE
SQL Server به شما امکان میدهد تا رکوردهایی را در جدول هدف به روز کنید، حتی اگر مطابقت متناظری در جدول منبع وجود نداشته باشد. این قابلیت در سناریوهایی که میخواهید ردیفها را در جدول هدف بر اساس دادههای موجود در جدول منبع به روز کنید، اما همچنان ردیفهایی را که مطابقت ندارند حفظ و احتمالاً مقادیر خاصی را برای آنها تنظیم کنید، بسیار مفید است.
UPDATE SC
SET SC.TerritoryID = 5
FROM #SalesCustomer AS SC
LEFT JOIN #SalesStore AS SS
ON SC.StoreID = SS.BusinessEntityID
WHERE SS.BusinessEntityID IS NULL AND SC.TerritoryID = 4;
این دستور تمام مشتریان در #SalesCustomer
را که StoreID
آنها در #SalesStore
مطابقت ندارد و TerritoryID
آنها 4 است، یافته و TerritoryID
آنها را به 5 به روز میکند. این یک مثال برای به روز رسانی رکوردهای ناموجود در جدول JOIN
شده است.
هنگامی که نیاز به ادغام دادهها از چندین جدول برای به روز رسانی، درج (INSERT
) یا حذف (DELETE
) ردیفها به صورت همزمان دارید، دستور MERGE
راه حلی جامع ارائه میدهد. این دستور به ویژه برای عملیات همگامسازی یا مدیریت تغییرات دادهها بین جداول منبع و هدف مفید است. MERGE
به شما امکان میدهد تا یک جدول هدف را بر اساس نتیجه JOIN
با یک جدول منبع دستکاری کنید. بخشهای اصلی دستور MERGE
عبارتند از:
WHEN MATCHED THEN UPDATE, WHEN NOT MATCHED THEN INSERT, WHEN NOT MATCHED BY SOURCE THEN DELETE
که به شما امکان میدهد عملیات مختلف را بر اساس اینکه ردیفها در جدول منبع و هدف مطابقت دارند یا نه، تعریف کنید.
USE AdventureWorks2019;
GO
DROP TABLE IF EXISTS #TargetProducts;
CREATE TABLE #TargetProducts (
ProductID INT PRIMARY KEY,
ProductName NVARCHAR(50),
Price MONEY,
LastUpdated DATETIME DEFAULT GETDATE()
);
INSERT INTO #TargetProducts (ProductID, ProductName, Price) VALUES
(707, 'Sport-100 Helmet', 34.99),
(708, 'Road-650 Helmet', 49.99),
(709, 'Mountain-500 Helmet', 79.99);
DROP TABLE IF EXISTS #SourceProducts;
CREATE TABLE #SourceProducts (
ProductID INT PRIMARY KEY,
ProductName NVARCHAR(50),
Price MONEY
);
INSERT INTO #SourceProducts (ProductID, ProductName, Price) VALUES
(707, 'Sport-100 Helmet', 36.99), -- Update price
(710, 'Bike Wash', 8.99), -- New product (insert)
(708, 'Road-650 Helmet', 49.99); -- No change
اکنون از MERGE
برای همگامسازی #TargetProducts
با #SourceProducts
استفاده میکنیم. این عملیات شامل به روز رسانی رکوردهای موجود، درج رکوردهای جدید و حذف رکوردهایی است که در منبع وجود ندارند:
MERGE #TargetProducts AS Target
USING #SourceProducts AS Source
ON (Target.ProductID = Source.ProductID)
WHEN MATCHED AND Target.Price <> Source.Price THEN
UPDATE SET Target.Price = Source.Price,
Target.LastUpdated = GETDATE()
WHEN NOT MATCHED BY Target THEN
INSERT (ProductID, ProductName, Price)
VALUES (Source.ProductID, Source.ProductName, Source.Price)
WHEN NOT MATCHED BY Source THEN
DELETE;
دستور MERGE
فوق، جدول #TargetProducts
را بر اساس #SourceProducts
به روز میکند. اگر ProductID
مطابقت داشته باشد و Price
متفاوت باشد، ردیف Target
به روز میشود. اگر ProductID
در Target
وجود نداشته باشد اما در Source
باشد، یک ردیف جدید در Target
درج میشود. اگر ProductID
در Target
باشد اما در Source
نباشد، ردیف از Target
حذف میشود.
انتخاب روش صحیح برای به روز رسانی دادهها در SQL Server به الزامات خاص و پیچیدگی عملیات شما بستگی دارد. دستور UPDATE
با FROM
یا JOIN
برای به روز رسانیهای ساده تا متوسط که شامل دادهها از یک یا چند جدول مرتبط هستند، بسیار کارآمد است. این روشها به دلیل خوانایی و عملکرد خوب در سناریوهای معمول، به طور گستردهای مورد استفاده قرار میگیرند.
در مقابل، دستور MERGE
برای سناریوهای همگامسازی پیچیدهتر که نیاز به انجام چندین نوع عملیات (UPDATE
، INSERT
و DELETE
) در یک تراکنش واحد دارند، ایدهآل است. اگرچه MERGE
قدرتمند است، اما میتواند پیچیدگی بیشتری داشته باشد و در برخی موارد ممکن است نیاز به بررسی دقیقتری از عملکرد داشته باشد.
هنگام انتخاب بین این روشها، عوامل زیر را در نظر بگیرید:
- **سادگی عملیات:** برای به روز رسانیهای مستقیم،
UPDATE
باFROM
یاJOIN
اغلب سادهتر و خواناتر است. - **نیاز به درج/حذف:** اگر علاوه بر به روز رسانی، نیاز به درج یا حذف ردیفها نیز دارید،
MERGE
بهترین گزینه است. - **عملکرد:** برای حجم زیادی از دادهها، هر دو روش میتوانند عملکرد خوبی داشته باشند، اما
MERGE
ممکن است در برخی موارد به دلیل پیچیدگی داخلی، سربار بیشتری داشته باشد. همیشه عملکرد را با دادههای واقعی آزمایش کنید.
با درک نقاط قوت و ضعف هر یک از این روشها، میتوانید کارآمدترین و بهینهترین راه حل را برای نیازهای مدیریت داده در SQL Server خود انتخاب کنید. استفاده صحیح از UPDATE FROM
، UPDATE JOIN
و MERGE
میتواند به طور قابل توجهی کارایی و دقت عملیات داده شما را بهبود بخشد.