"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > قم برفع صف في قاعدة بيانات لا يستخدم المفاتيح الأساسية أو القيود الفريدة

قم برفع صف في قاعدة بيانات لا يستخدم المفاتيح الأساسية أو القيود الفريدة

تم النشر بتاريخ 2024-11-08
تصفح:169

Upsert a row in a DB that doesn

خلال مسيرتي المهنية التي امتدت لـ 7 سنوات كمبرمج، تفاعلت مع SQL عبر ORM في معظم الأوقات. إحدى ميزات Laravel's Eloquent ORM التي أجدها مفيدة بشكل خاص هي طريقة updateOrInsert():

DB::table('posts')
    ->updateOrInsert(
        ['slug' => 'about'], // matching condition
        ['content' => 'Like and subscribe'] // created or updated values
    );

في المثال أعلاه، سيبحث Eloquent عن صف في جدول المنشورات حيث يكون الارتباط التقريبي يساوي "about". إذا كان هناك صف به هذا الارتباط الثابت، فسيقوم Eloquent بتحديث محتوى هذا الصف إلى "أعجبني واشترك". إذا كان الصف غير موجود مع تلك السلسلة الثابتة، فسيقوم Eloquent بإنشاء صف جديد مع السلسلة الثابتة "about" ومحتوى "أعجبني والاشتراك".

المشكلة: لا يوجد مفتاح أساسي أو قيود فريدة

أقوم حاليًا بكتابة برنامج نصي للترحيل لنقل بيانات الصفحة من موقع WordPress القديم إلى موقع WordPress الجديد. يتصل البرنامج النصي بقاعدة بيانات الموقع القديم ثم يقوم بإنشاء ملف SQL يمكن استيراده إلى قاعدة بيانات الموقع الجديد. يحتوي الموقع الجديد بالفعل على بعض الصفحات التي تم نقلها يدويًا، ولكن محتواها قد يكون قديمًا. عندما تكون هناك صفحة موجودة بالفعل على الموقع الجديد، فإننا لا نريد إنشائها مرة أخرى: بل نريد تحديث الصفحة الموجودة هناك بالفعل. يمكننا تحديد ما إذا كانت الصفحة موجودة بالفعل باستخدام عمود post_name في قاعدة بيانات WordPress، والذي يتوافق مع الارتباط الثابت لعنوان URL الخاص بالصفحة.

إذا كان post_name هو المفتاح الأساسي، فيمكننا إنجاز شيء مشابه لطريقة createOrUpdate() الخاصة بـ Eloquent باستخدام عبارة REPLACE، لكن post_name ليس المفتاح الأساسي.

إذا كان لدى post_name قيد فريد، فيمكننا إنجاز شيء مشابه لطريقة createOrUpdate() الخاصة بـ Eloquent باستخدام عبارة INSERT... ON DUPLICATE KEY UPDATE، لكن post_name لا يحتوي على قيد فريد.

آه، أفراح ووردبريس.

لقد بحثت في عبارة IF الخاصة بـ MySQL، لكن عبارة IF تعمل فقط في الإجراءات والمشغلات والوظائف المخزنة. لم أرغب في إنشاء إجراءات مخزنة في ملف SQL الذي سأقوم باستيراده إلى قاعدة بيانات الموقع الجديد، لذلك كان علي البحث عن خيارات أخرى.

الحل: 2 بيان

كان الحل الأبسط الذي يمكن أن أجده لمحاكاة وظيفة UpdateOrInsert() في Eloquent في لغة SQL الخالصة هو تقسيم المشكلة إلى جزأين:

  1. تحديث أي صفوف موجودة مع سبيكة مطابقة.
  2. قم بإنشاء صف جديد في حالة عدم وجود صفوف تحتوي على حلقات ثابتة متطابقة.

إليك ما يبدو عليه الأمر عمليًا:

-- Update the post if it already exists.

UPDATE wp_posts
SET post_type = 'page',
    post_title = 'About',
    post_content = 'Like and subscribe'
WHERE post_name = 'about';

-- Create a new post if it does not exist.

INSERT INTO wp_posts (post_name, post_type, post_title, post_content)
SELECT 'about', 'page', 'About', 'Like and subscribe'
WHERE NOT EXISTS (
    SELECT 1
    FROM wp_posts
    WHERE post_name = 'about'
);

ملاحظة: يحذف هذا المثال العديد من أعمدة wp_posts المطلوبة في WordPress للإيجاز والوضوح.

التعرف على عبارة INSERT... SELECT كانت بمثابة لحظة "آها" بالنسبة لي. الغرض منه هو استخدام نتائج استعلام من جدول آخر لإجراء عدة عمليات إدراج في وقت واحد. ومع ذلك، يمكنك استخدام وإساءة استخدام إمكانات SQL من خلال توفير القيم الخاصة بك وتنفيذ عملية الإدراج فقط في حالة عدم وجود منشور يحمل اسم post_name "about".

هل هذا هو الحل الأكثر أناقة وكفاءة لهذه المشكلة؟ ربما لا. ولكنها جيدة بما يكفي لترحيل موقع WordPress لمرة واحدة، وتسمح لك بتحديث أو إدراج صف دون الحاجة إلى إجراءات مخزنة أو أي منطق تطبيق. نأمل أن يساعدك هذا المنشور أثناء كتابة استعلامات قوية دون مساعدة ORM.

بيان الافراج تم إعادة إنتاج هذه المقالة على: https://dev.to/tylerlwsmith/upsert-a-row-in-a-db-that-doesnt-use-primary-keys-or-unique-constraints-2jnl?1إذا كان هناك أي التعدي، يرجى الاتصال بـ [email protected] للحذف
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3