MERGE: افزودن، بهروزرسانی و حذف در یک عملیات
در درس UPDATE، سناریویی دیدیم که یک جدول موقت (Staging) قیمتهای تازه داشت و باید در جدول اصلی بهروز میشدند. اما واقعیت این است که در دنیای واقعی، جدول Staging معمولاً هم محصولات جدید دارد (که باید INSERT شوند) هم محصولات موجود (که باید UPDATE شوند) — و نوشتن دو دستور جدا برای این دو حالت، هم تکراری است هم مستعد خطا. MERGE دقیقاً همین مشکل را حل میکند: افزودن، بهروزرسانی (و حتی حذف) را در یک دستور واحد ترکیب میکند.
ساختار MERGE در SQL Server
MERGE INTO Products AS target USING StagingProducts AS source ON target.Id = source.Id WHEN MATCHED THEN UPDATE SET target.Price = source.Price WHEN NOT MATCHED BY TARGET THEN INSERT (Id, Name, Price) VALUES (source.Id, source.Name, source.Price);
سه بخش اصلی اینجا:
- USING: منبع دادهی جدید (معمولاً یک جدول Staging یا یک زیرپرسوجو)
- ON: شرط تطبیق بین جدول هدف و منبع (شبیه شرط JOIN)
- WHEN MATCHED / WHEN NOT MATCHED BY TARGET: اگر تطبیق پیدا شد چه کاری انجام شود (معمولاً UPDATE)، و اگر پیدا نشد چه کاری (معمولاً INSERT)
میتوان یک شاخهی سوم هم اضافه کرد — WHEN NOT MATCHED BY SOURCE THEN DELETE — برای حذف ردیفهایی از جدول هدف که دیگر در منبع وجود ندارند.
MERGE کاملاً مخصوص SQL Server (و چند موتور دیگر مثل Oracle و PostgreSQL جدید) است. SQLite اصلاً چنین دستوری ندارد — اجرای مستقیم MERGE در این Playground با خطای نحوی متوقف میشود.معادل SQLite: INSERT ... ON CONFLICT DO UPDATE
SQLite برای همان سناریوی رایجترِ MERGE — «اگر بود بهروز کن، اگر نبود اضافه کن» (که به آن Upsert هم میگویند) — یک نحو سادهتر دارد:
INSERT INTO products (id, name, price) VALUES (1, N'کیبورد', 1450000) ON CONFLICT(id) DO UPDATE SET price = excluded.price;
یعنی: «سعی کن این ردیف را اضافه کنی؛ اگر به دلیل تکراریبودن id (که PRIMARY KEY است) با تعارض روبهرو شدی، بهجایش قیمتش را بهروز کن.» کلمهی excluded به مقداری اشاره میکند که قرار بود درج شود ولی بهخاطر تعارض، درج نشد. بیا این را روی دو حالت — یک محصول موجود و یک محصول تازه — امتحان کنیم:
INSERT را بازی کرد، هم نقش UPDATE را — دقیقاً همان ایدهی پشت MERGE.MERGE کِی واقعاً بهکار میآید؟
MERGE (یا معادل Upsert آن) بیشتر در این سناریوها ارزشش را نشان میدهد:
- همگامسازی داده (Data Sync): وارد کردن دورهای یک فایل یا جدول Staging به جدول اصلی، جایی که بعضی ردیفها جدیدند و بعضی باید بهروز شوند.
- پردازش دستهای (Batch Processing): وقتی چند صد یا چند هزار ردیف باید همزمان بررسی و همگام شوند — یک
MERGEبهجای صدهاINSERT/UPDATEجدا.
IF EXISTS ... UPDATE ELSE INSERT (یا همین ON CONFLICT در SQLite) خواناتر از یک MERGE کامل است. ارزش واقعی MERGE وقتی نمایان میشود که با حجم بالایی از ردیفها، از یک منبع دیگر، همزمان سروکار داری.جمعبندی این درس (و کل فصل ۶)
MERGEدر SQL Server،INSERT،UPDATEوDELETEرا بر اساس تطبیق با یک منبع دیگر، در یک دستور ترکیب میکند.- SQLite دستور
MERGEندارد؛ معادل رایجترین کاربردش (Upsert) باINSERT ... ON CONFLICT DO UPDATEپیاده میشود. MERGEبیشتر برای همگامسازی حجم بالا از داده مناسب است، نه یک بهروزرسانی سادهی تکردیفی.
با این درس، فصل ۶ (تغییر دادهها) کامل شد! تا اینجا یاد گرفتی چطور داده بخوانی، فیلتر کنی، تجمیع کنی، بین جدولها ارتباط برقرار کنی، و حالا چطور آن را تغییر بدهی. در فصل بعدی، یک قدم عقبتر میرویم و میبینیم چطور از اول، یک پایگاهدادهی خوب طراحی کنیم — نرمالسازی، مدلهای ER و روابط.