UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)
نفّذ عمليات إدراج متكررة آمنة باستخدام ON CONFLICT DO UPDATE، واستخدم EXCLUDED، واختر هدف التعارض المناسب.
UPSERT: ON CONFLICT DO UPDATE (PostgreSQL) درس مجاني في SQL Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في SQL Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة SQL Academy 4 دروس في المجموع.
ما المقصود بـ UPSERT؟
UPSERT = تنفيذ INSERT إذا لم يكن الصف موجودًا، وتنفيذ UPDATE إذا كان موجودًا. وتكتب PostgreSQL هذه العملية بصيغة INSERT ... ON CONFLICT.
ON CONFLICT DO NOTHING
أدرج الصف إذا لم يكن موجودًا، وتجاوَز التكرار بصمت إذا كان موجودًا:
INSERT INTO users (email, full_name)
VALUES ('alice@example.com', 'Alice')
ON CONFLICT (email) DO NOTHING;ON CONFLICT DO UPDATE
أدرج الصف إذا لم يكن موجودًا، وإلا فحدّث أعمدة محددة:
INSERT INTO users (email, full_name, last_login)
VALUES ('alice@example.com', 'Alice', NOW())
ON CONFLICT (email)
DO UPDATE SET
full_name = EXCLUDED.full_name,
last_login = EXCLUDED.last_login;EXCLUDED: الصف المقترح
داخل DO UPDATE، تعني EXCLUDED.col «القيمة التي حاول INSERT إدراجها». أما اسم العمود المجرد (أو users.col) فيشير إلى الصف الموجود.
ON CONFLICT (email)
DO UPDATE SET visits = users.visits + 1,
last_seen = EXCLUDED.last_seen;هدف التعارض
يجب تحديد قيد UNIQUE أو مفتاح أساسي:
ON CONFLICT (email) -- column with UNIQUE
ON CONFLICT (user_id, day) -- composite UNIQUE
ON CONFLICT ON CONSTRAINT users_email_key -- by nameUPSERT مشروط (استخدام WHERE في DO UPDATE)
حدّث الصف فقط عند تحقق شرط معين:
INSERT INTO inventory (product_id, qty)
VALUES (42, 5)
ON CONFLICT (product_id)
DO UPDATE SET qty = inventory.qty + EXCLUDED.qty
WHERE inventory.qty + EXCLUDED.qty <= 1000;UPSERT متعدد الصفوف
أدرج عدة صفوف، مع معالجة كل صف على حدة:
INSERT INTO page_views (path, day, count)
VALUES ('/home', CURRENT_DATE, 1), ('/about', CURRENT_DATE, 1)
ON CONFLICT (path, day)
DO UPDATE SET count = page_views.count + EXCLUDED.count;استخدام RETURNING مع UPSERT
استرجع الصف الناتج، سواء أُدرج أو حُدّث:
INSERT INTO users (email, full_name)
VALUES ('alice@example.com', 'Alice')
ON CONFLICT (email) DO UPDATE
SET full_name = EXCLUDED.full_name
RETURNING id, full_name;سير العمل الآمن عند التكرار
يجعل UPSERT عمليات إعادة المحاولة آمنة. فإذا أُطلق webhook مرتين، تحدّث المكالمة الثانية الصف نفسه بدلًا من إنشاء نسخة مكررة.
MERGE (معيار SQL، في PG15 فأحدث)
أضافت PostgreSQL 15 الأمر MERGE المتوافق مع معيار SQL، والذي يمكنه تنفيذ INSERT/UPDATE/DELETE في عبارة واحدة:
MERGE INTO users AS u
USING (VALUES ('alice@example.com','Alice')) AS src(email, name)
ON u.email = src.email
WHEN MATCHED THEN UPDATE SET full_name = src.name
WHEN NOT MATCHED THEN INSERT (email, full_name) VALUES (src.email, src.name);متى لا تستخدم UPSERT
يتطلب UPSERT قيدًا فريدًا. إذا لم يكن لديك قيد كهذا، فعادةً ما تحتاج إلى تنفيذ SELECT منفصل ثم INSERT أو UPDATE، لكن انتبه إلى حالات التنافس؛ غلّف العملية داخل معاملة مع استخدام آلية القفل المناسبة.
مراجعة
يُعد ON CONFLICT طريقة PostgreSQL النظيفة والذرّية لتنفيذ UPSERT.
- استخدم DO NOTHING من أجل «الإدراج إذا لم يكن الصف موجودًا»
- استخدم DO UPDATE لتنفيذ UPSERT فعلي
EXCLUDED= الصف المقترح- حدّد هدف تعارض دائمًا
اختبار سريع
في العبارة ON CONFLICT (email) DO UPDATE SET last_login = EXCLUDED.last_login، إلى ماذا تشير EXCLUDED؟
الأسئلة الشائعة
هل درس «UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)» مجاني؟
نعم — نص درس «UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة SQL Academy، انتقل إلى CoddyKit PRO. تتضمن دورة SQL Academy 4 دروس في المجموع.
ماذا ستتعلم في «UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)»؟
نفّذ عمليات إدراج متكررة آمنة باستخدام ON CONFLICT DO UPDATE، واستخدم EXCLUDED، واختر هدف التعارض المناسب. تتمرن على SQL Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ SQL Academy؟
لا تُشترط خبرة سابقة. SQL Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس SQL Academy هذا؟
نعم. كل درس في SQL Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- INSERT مع صفوف متعددة
- UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)
- UPDATE مع FROM وتحديثات بأسلوب JOIN
- DELETE مع USING وأنماط آمنة