طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 121 · مبادئ قواعد البيانات
الدرس 20 · الوحدة 8: تحديث وإدخال البيانات

تحديث البيانات: UPDATE والمعاملات

نعدّل البيانات بدقة، ونجمع العمليات المترابطة في معاملة آمنة. ⏱ نحو 30 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تعدّل قيم صف أو صفوف بـ UPDATE … SET … WHERE.
  • تحسب القيمة الجديدة من القديمة، وتعدّل بشرط من جدول آخر.
  • تتجنب كارثة UPDATE بلا WHERE.
  • تستخدم المعاملات BEGIN و COMMIT و ROLLBACK وتشرح ACID.

١تعديل القيم: UPDATE

UPDATE يغيّر قيمًا في صفوف موجودة: الجدول، ثم SET العمود = القيمة الجديدة، ثم WHERE لتحديد الصفوف:

query.sql
UPDATE productsSET price = 40WHERE id = 1; SELECT id, name, price FROM products WHERE id = 1;
✓ عُدِّل صف واحد
النتيجة · صف واحد
idnameprice
1قهوة عربية 250غ40

عدة أعمدة معًا، وقيمة محسوبة من القيمة القديمة:

query.sql
-- رفع أسعار العسل 10% وإضافة 5 قطع للمخزونUPDATE productsSET price = ROUND(price * 1.10, 2),    stock = stock + 5WHERE category = 'عسل'; SELECT name, price, stock FROM products WHERE category = 'عسل';
✓ عُدِّل صفّان
النتيجة · صفّان
namepricestock
عسل سدر 500غ16517
عسل زهور 500غ6635

٢أخطر سطر في SQL

نسيان WHERE يعدّل كل صفوف الجدول، بلا تحذير:

query.sql
UPDATE customers SET city = 'جدة';   -- نسينا WHERE! SELECT name, city FROM customers;
✓ عُدِّل 10 صفوف
النتيجة · 10 صفوف
namecity
سعود العتيبيجدة
نورة القحطانيجدة
خالد الحربيجدة
ريم الشهريجدة
فهد الدوسريجدة
سارة المطيريجدة
عبدالله الزهرانيجدة
هند السبيعيجدة
ماجد الغامديجدة
لمى العنزيجدة
✗ خطأ
query.sql
UPDATE orders SET status = 'مُسلَّم';
✓ عُدِّل 12 صفًّا
✓ صواب
query.sql
SELECT id, status FROM orders WHERE id = 7;   -- تأكد أولًاUPDATE orders SET status = 'مُسلَّم' WHERE id = 7;
النتيجة · صف واحد
idstatus
7قيد الشحن
✓ عُدِّل صف واحد

٣التحديث بشرط من جدول آخر

«سلّموا كل طلبات العملاء في الرياض». الشرط في جدول العملاء، والتعديل في جدول الطلبات، فنستخدم استعلامًا فرعيًّا:

query.sql
UPDATE ordersSET status = 'مُسلَّم'WHERE customer_id IN (SELECT id FROM customers WHERE city = 'الرياض'); SELECT id, customer_id, status FROM orders WHERE customer_id IN (2, 5);
✓ عُدِّل 3 صفوف
النتيجة · 3 صفوف
idcustomer_idstatus
22مُسلَّم
65مُسلَّم
72مُسلَّم

٤المعاملة: كل شيء أو لا شيء

تحويل 500 ريال من نواف إلى عزام عمليتان: خصم من الأول، وإضافة للثاني. لو انقطع التيار بينهما ضاعت 500 ريال! المعاملة Transaction تجمع عدة أوامر في وحدة واحدة: إما تُنفَّذ كلها، وإما لا يُنفَّذ منها شيء:

الأمرالوظيفة
BEGIN (في MySQL أيضًا START TRANSACTION)بداية المعاملة
COMMITاعتماد كل التغييرات نهائيًّا
ROLLBACKإلغاء كل التغييرات منذ BEGIN
query.sql
CREATE TABLE accounts (  id      INTEGER PRIMARY KEY,  owner   TEXT,  balance REAL CHECK (balance >= 0));INSERT INTO accounts VALUES (1, 'نواف', 1000), (2, 'عزام', 300); BEGIN;UPDATE accounts SET balance = balance - 500 WHERE id = 1;UPDATE accounts SET balance = balance + 500 WHERE id = 2;COMMIT; SELECT * FROM accounts;
النتيجة · صفّان
idownerbalance
1نواف500
2عزام800

والآن تراجعنا قبل الاعتماد:

query.sql
CREATE TABLE accounts (  id      INTEGER PRIMARY KEY,  owner   TEXT,  balance REAL CHECK (balance >= 0));INSERT INTO accounts VALUES (1, 'نواف', 1000), (2, 'عزام', 300); BEGIN;UPDATE accounts SET balance = 0;      -- خطأ كارثي!SELECT * FROM accounts;               -- داخل المعاملة: صفرROLLBACK; SELECT * FROM accounts;               -- بعد التراجع: كما كانت
✓ أُنشئ الجدول
✓ أُضيف صفّان
⏳ بدأت المعاملة
✓ عُدِّل صفّان
النتيجة · صفّان
idownerbalance
1نواف0
2عزام0
↩ أُلغيت المعاملة (ROLLBACK)
النتيجة · صفّان
idownerbalance
1نواف1000
2عزام300

٥خصائص ACID

أنظمة قواعد البيانات العلائقية تضمن للمعاملة أربع خصائص، تُختصر ACID:

الخاصيةمعناهافي مثال التحويل
Atomicity الذريةكلها أو لا شيء.لا خصم بلا إضافة.
Consistency الاتساقتنقل القاعدة من حالة صحيحة إلى حالة صحيحة، والقيود محترمة.CHECK يمنع رصيدًا سالبًا.
Isolation العزلالمعاملات المتزامنة لا يرى بعضها نصف عمل بعض.لا يرى أحد الرصيدين في منتصف التحويل.
Durability الديمومةبعد COMMIT تبقى التغييرات حتى لو انقطع التيار.التحويل محفوظ.
query.sql
CREATE TABLE accounts (  id      INTEGER PRIMARY KEY,  owner   TEXT,  balance REAL CHECK (balance >= 0));INSERT INTO accounts VALUES (1, 'نواف', 1000), (2, 'عزام', 300); BEGIN;UPDATE accounts SET balance = balance - 800 WHERE id = 2;
⏳ بدأت المعاملة
✗ خطأ (السطر 9): مخالفة قيد CHECK: balance >= 0

عزام لديه 300 فقط، فرفض قيد CHECK الخصم. وفي التطبيق الحقيقي يلتقط البرنامج هذا الخطأ وينفّذ ROLLBACK للمعاملة كلها.

توقّع وتحقّق

تعديل القيم يكون بالأمر:

DML.

UPDATE بلا WHERE:

خطير.

لإلغاء تغييرات المعاملة:

قبل COMMIT.

حرف A في ACID:

كلها أو لا شيء.

الخلاصة

تحدٍّ برمجي: تحديث المخزون والأسعار

متوسط

وصلت شحنة جديدة وتغيرت الأسعار. نفّذ التعديلات داخل معاملة واحدة واعتمدها.

المطلوب:
  • ابدأ معاملة.
  • التمر السكري (رقم 4) وصلت منه 30 قطعة، وكان مخزونه صفرًا: اجعل مخزونه 30.
  • خفّض سعر كل منتجات «أدوات» 5 ريالات.
  • اعتمد المعاملة.
👀 اعرض النتيجة المطلوبة
بعد التنفيذ: SELECT stock FROM products WHERE id = 4
stock
30
بعد التنفيذ: SELECT id, price FROM products WHERE category = 'أدوات' ORDER BY id
idprice
770
835
12115
بعد التنفيذ: SELECT id, price, stock FROM products WHERE category <> 'أدوات' AND id <> 4 ORDER BY id
idpricestock
13540
21865
39025
515012
66030
92850
105515
1112100
✓ التحقق الآلي من حلّك:
  • الكود يعمل بلا أخطاء
  • مخزون التمر السكري 30
  • أسعار الأدوات انخفضت 5 ريالات
  • بقية المنتجات لم تتغير
  • تبدأ معاملة
  • تعتمدها بـ COMMIT

💡 تلميح 1
UPDATE products SET stock = 30 WHERE id = 4;
💡 تلميح 2
price = price - 5 مع WHERE category = 'أدوات'

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

solution.sql
BEGIN; UPDATE products SET stock = 30 WHERE id = 4; UPDATE products SET price = price - 5 WHERE category = 'أدوات'; COMMIT;
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

📝 معلم؟ أرسل ملاحظة للمؤلف عن هذا الدرس