تخطَّ إلى المحتوى

الإضافة والتعديل والحذف في MySQL

الدرس 6 من 12 · MySQL

المتجر الحي يتغير كل دقيقة: منتج جديد يُضاف، ومخزون ينقص مع كل عملية بيع، وأسعار تتغير في موسم التخفيضات، ومنتجات قديمة تُحذف. في هذا الدرس ستتعلم أوامر تعديل البيانات في MySQL، ومعها أدوات خاصة بها تحل مشاكل حقيقية تواجهها كل التطبيقات.

INSERT INTO products (name, category, price, stock, added_on) VALUES
('كتاب البرمجة للمبتدئين', 'كتب', 120.00, 15, '2026-09-01'),
('سماعة لاسلكية', 'إلكترونيات', 450.50, 8, '2026-09-15');

لاحظ أننا لم نذكر العمود id، لأنه AUTO_INCREMENT: تعطيه MySQL الرقم التالي تلقائياً. وأي عمود لا تذكره يأخذ قيمته الافتراضية، فلو أضفت منتجاً دون stock سيأخذ 0 من DEFAULT 0.

ما رقم المنتج الجديد؟ LAST_INSERT_ID

Section titled “ما رقم المنتج الجديد؟ LAST_INSERT_ID”

بعد إضافة منتج، كثيراً ما تحتاج رقمه فوراً، مثلاً لتحويل المستخدم إلى صفحة المنتج الجديد:

INSERT INTO products (name, category, price) VALUES ('مسطرة', 'أدوات مدرسية', 10);
SELECT LAST_INSERT_ID();

الناتج: 7

LAST_INSERT_ID() تُرجع آخر رقم تلقائي أُنشئ في اتصالك أنت، فلا تختلط بإضافات مستخدمين آخرين في نفس اللحظة. وفي PHP مع PDO، المقابل هو $pdo->lastInsertId() الذي تعرفت عليه في كورس PHP.

عملية بيع: ينقص مخزون السماعة واحداً:

UPDATE products SET stock = stock - 1 WHERE id = 2;
SELECT ROW_COUNT();

الناتج: 1

ROW_COUNT() تخبرك بعدد الصفوف التي تغيرت فعلاً. مفيدة للتأكد: إذا كانت 0، فالشرط لم يطابق أي منتج، وربما الرقم خاطئ.

تخفيضات 10% على كل الكتب:

UPDATE products SET price = price * 0.9 WHERE category = 'كتب';
SELECT name, price FROM products WHERE category = 'كتب';

الناتج:

name price
كتاب البرمجة للمبتدئين 108.00
قصص الأطفال 58.50

«أضف أو حدّث»: ON DUPLICATE KEY UPDATE

Section titled “«أضف أو حدّث»: ON DUPLICATE KEY UPDATE”

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

CREATE TABLE subscribers (
email VARCHAR(100) PRIMARY KEY,
visits INT DEFAULT 1
);
INSERT INTO subscribers (email) VALUES ('sara@example.com');
INSERT INTO subscribers (email) VALUES ('sara@example.com')
ON DUPLICATE KEY UPDATE visits = visits + 1;
SELECT * FROM subscribers;

الناتج:

email visits
sara@example.com 2

الإضافة الثانية وجدت البريد موجوداً (مفتاح مكرر)، فبدلاً من الخطأ نفّذت التحديث وزادت الزيارات. هذه الميزة الخاصة بـ MySQL تسمى أحياناً Upsert (من Update و Insert).

ولو أضفت نفس البريد بدون ON DUPLICATE KEY UPDATE:

الناتج: ERROR 1062 (23000): Duplicate entry 'sara@example.com' for key 'subscribers.PRIMARY'

DELETE FROM products WHERE id = 7;
SELECT COUNT(*) FROM products;

الناتج: 6

تذكّر أخطر خطأ في SQL: UPDATE أو DELETE بدون WHERE يؤثر على كل الصفوف. MySQL تقدم حماية إضافية اسمها وضع التحديثات الآمنة (Safe Updates)، مفعّل افتراضياً في MySQL Workbench، ويمكنك تفعيله بنفسك:

SET SQL_SAFE_UPDATES = 1;

في هذا الوضع، ترفض MySQL أي UPDATE أو DELETE بدون WHERE يعتمد على مفتاح، فتمنعك من مسح الجدول كله بالخطأ. وتظهر رسالة: ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.

TRUNCATE TABLE subscribers; تحذف كل الصفوف بسرعة كبيرة، وتعيد الترقيم التلقائي إلى 1. تستخدم عادة في بيئة التجربة فقط، ولا يمكن التراجع عنها.

  1. أضف منتجين جديدين، واطبع LAST_INSERT_ID() بعد كل إضافة.
  2. سجّل عملية بيع 3 قطع من الآلة الحاسبة، واستخدم ROW_COUNT() للتأكد.
  3. ارفع أسعار الإلكترونيات 5%، واطبعها مقرّبة لرقمين.
  4. أنشئ جدولاً لعدد مشاهدات كل منتج (product_id مفتاح أساسي، و views)، واستخدم ON DUPLICATE KEY UPDATE لزيادة المشاهدات عند كل زيارة.
  • ذكر قيمة لعمود AUTO_INCREMENT: ليس خطأ، لكنه قد يسبب تعارضاً مع الأرقام التلقائية. دع MySQL تختار.
  • نسيان WHERE: يعدّل أو يحذف الجدول كله. فعّل SQL_SAFE_UPDATES أثناء التعلم.
  • قيمة مكررة لمفتاح فريد: خطأ Duplicate entry. استخدم ON DUPLICATE KEY UPDATE إذا كان التكرار متوقعاً.

سؤال

ما الدالة التي تعطيك رقم id للصف الذي أضفته للتو؟

سؤال

ماذا يفعل INSERT ... ON DUPLICATE KEY UPDATE؟

  • INSERT دون ذكر id، و LAST_INSERT_ID() لمعرفة الرقم الجديد.
  • UPDATE ... SET col = col - 1 لتحديث يعتمد على القيمة الحالية، و ROW_COUNT() لعدد الصفوف المتغيرة.
  • ON DUPLICATE KEY UPDATE يضيف أو يحدّث حسب وجود المفتاح.
  • SQL_SAFE_UPDATES يحميك من التعديل والحذف بدون WHERE.
  • TRUNCATE يفرّغ الجدول ويعيد الترقيم، والنسخ الاحتياطي بـ mysqldump قبل العمليات الخطيرة.