انتقال للمقال

تعديل البيانات في الجداول باستخدام UPDATE

السلام عليكم ورحمة الله وبركاته

وقت القراءة: ≈ 10 دقائق

المقدمة

لقد تعلمنا كيفية إضافة البيانات إلى الجداول باستخدام أمر INSERT
وتعلمنا كيفية قراءتها باستخدام أمر SELECT
والآن في هذه المقالة سنتعلم كيفية تعديل البيانات الموجودة في الجداول باستخدام أمر UPDATE

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

كل هذه الأمثلة تتطلب تعديل البيانات الموجودة وليس إضافة بيانات جديدة
وهنا يأتي دور أمر UPDATE الذي سنتعلمه في هذه المقالة بالتفصيل مع أمثلة عملية ونصائح مهمة

ما هو أمر الـ UPDATE ؟

أمر الـ UPDATE يستخدم لـ تعديل البيانات الموجودة في الجداول
وهو أمر قوي جدًا لكن خطير في نفس الوقت إذا لم تستخدمه بحذر
لأن أمر الـ UPDATE يقوم بتعديل كل البيانات في الجدول
بالتالي لو كان لديك جدول يحتوى على 10000 صف، ستجد أنك لو نفذت أمر UPDATE سيتم تعديل الـ 10000 صف
بالطبع هذا ليس ما تريده في معظم الحالات، أنت لا تريد تعديل كل البيانات بل تريد تعديل صفوف معينة فقط

لذا يتم استخدامم شرط الـ WHERE دائمًا مع أمر الـ UPDATE لتحديد الصفوف التي تريد تعديلها بناءً على شروط معينة
هذا الشرط هو الذي يحدد الصفوف التي سيتم تعديلها، وإذا لم تستخدمه، سيتم تعديل كل الصفوف في الجدول
وسنرى هذا في الأمثلة العملية التالية

تجهيز الجدول للأمثلة العملية

كالعادة قبل أن نبدأ، أحتاج لتذكيركم بشكل جدول الـ Students الذي سنستخدمه في هذه المقالة
والبيانات التي يحتويه من المقالات السابقة

في هذه المقالة سنستخدم جدولًا بسيطًا اسمه Students يحتوي على بيانات الطلاب

CREATE TABLE Students (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100) NOT NULL UNIQUE,
    age INT,
    level VARCHAR(50) DEFAULT 'Beginner'
);

والبيانات التي سنستخدمها في هذا الجدول هي:

+----+-----------------+------+--------------+------------------------+
| id | name            | age  | level        | email                  |
+----+-----------------+------+--------------+------------------------+
| 1  | Ahmed Moustafa  | 20   | Beginner     | [email protected]   |
| 2  | Osama Ali       | 19   | Intermediate | [email protected]   |
| 3  | Mohamed Adel    | 22   | Advanced     | [email protected] |
| 4  | Kamal Mahmoud   | 21   | Beginner     | [email protected]   |
| 5  | Ayman Hassan    | 20   | Advanced     | [email protected]   |
| 6  | Adam Ibrahim    | NULL | Beginner     | [email protected]    |
| 7  | Ismail Khaled   | 22   | NULL         | [email protected]  |
| 8  | Ali Hassan      | NULL | NULL         | [email protected]     |
+----+-----------------+------+--------------+------------------------+

هذه البيانات التي سنستخدمها في جميع الأمثلة، والآن دعونا نتعلم كيفية استخدام أمر UPDATE

الشكل الأساسي لأمر UPDATE

أمر UPDATE يستخدم لتعديل أعمدة معينة
ونستخدم معه الـ WHERE لتحديد الصفوف التي نريد تعديلها

لنفترض أننا نريد تعديل مستوى طالب معين في جدول Students
نريد تغيير مستوى الطالب Ahmed Moustafa من Beginner إلى Intermediate

أولًا سنقوم باخبار الأمر UPDATE باسم الجدول الذي نريد تعديله، وهو Students

UPDATE Students

ثم نستخدم SET لتحديد العمود الذي نريد تعديله والقيمة الجديدة التي نريد تعيينها له
وفي هذه الحالة نريد تعديل عمود level إلى Intermediate

SET level = 'Intermediate'

ثم نأتي للجزء الأهم وهو تحديد الصف الذي نريد تعديله باستخدام WHERE

WHERE name = 'Ahmed Moustafa';

وبالتالي الشكل الكامل لأمر UPDATE سيكون كالتالي:

UPDATE Students
SET level = 'Intermediate'
WHERE name = 'Ahmed Moustafa';

دعونا نفهم كل جزء:

  • UPDATE Students: نحدد اسم الجدول الذي نريد تعديل البيانات فيه وفي حالتنا كان جدول الـ Students
  • SET level = 'Intermediate': نحدد العمود الذي نريد تعديله والقيمة الجديدة
    ولاحظ أننا يمكننا تعديل أكثر من عمود في نفس الأمر باستخدام الفاصلة ,
  • WHERE name = 'Ahmed Moustafa': الجزء الأهم وهو تحديد الشرط الذي يحدد الصفوف التي نريد تعديلها
    إذا لم نستخدم WHERE، سيتم تعديل كل الصفوف في الجدول، وهذا هو الجزء الذي يجب أن نكون حذرين معه

تعديل البيانات باستخدام UPDATE

سأعرض لك بعض الأمثلة العملية لتوضيح كيفية استخدام أمر UPDATE لتعديل البيانات في الجداول
بطرق مختلفة وحالات متعددة

لكن أولًا دعنا نرى نتذكر البيانات الموجودة في جدول Students الذي أنشأناه سابقًا

+----+-----------------+------+--------------+------------------------+
| id | name            | age  | level        | email                  |
+----+-----------------+------+--------------+------------------------+
| 1  | Ahmed Moustafa  | 20   | Beginner     | [email protected]   |
| 2  | Osama Ali       | 19   | Intermediate | [email protected]   |
| 3  | Mohamed Adel    | 22   | Advanced     | [email protected] |
| 4  | Kamal Mahmoud   | 21   | Beginner     | [email protected]   |
| 5  | Ayman Hassan    | 20   | Advanced     | [email protected]   |
| 6  | Adam Ibrahim    | NULL | Beginner     | [email protected]    |
| 7  | Ismail Khaled   | 22   | NULL         | [email protected]  |
| 8  | Ali Hassan      | NULL | NULL         | [email protected]     |
+----+-----------------+------+--------------+------------------------+

تعديل قيمة عمود واحد لصف معين

حسنًا كما فعلنا سابقًا لنفترض أننا نريد تعديل مستوى الطالب Ahmed Moustafa من Beginner إلى Intermediate

الأمر كما رأيناه سابقًا في المقدمة كان بسيطًا جدًا
فقط نحدد اسم الجدول، العمود الذي نريد تعديله، والقيمة الجديدة
ثم نستخدم WHERE لتحديد الصف الذي نريد تعديله

UPDATE Students
SET level = 'Intermediate'
WHERE name = 'Ahmed Moustafa';

الأمر كما ترى بسيط مثله مثل أوامر الـ INSERT و SELECT التي تعلمناها سابقًا
وهو ببمجرد قراءتها ستفهم ما الذي تفعله حتى لو لم يكن لك معرفة بالـ SQL من الأساس
نحن نبحث عن الطالب الذي اسمه Ahmed Moustafa ونعدل قيمة العمود level إلى Intermediate

وبعد تنفيذ هذا الأمر، ستصبح البيانات كالتالي:

+----+-----------------+------+--------------+------------------------+
| id | name            | age  | level        | email                  |
+----+-----------------+------+--------------+------------------------+
| 1  | Ahmed Moustafa  | 20   | Intermediate | [email protected]   |
| 2  | Osama Ali       | 19   | Intermediate | [email protected]   |
| 3  | Mohamed Adel    | 22   | Advanced     | [email protected] |
| 4  | Kamal Mahmoud   | 21   | Beginner     | [email protected]   |
| 5  | Ayman Hassan    | 20   | Advanced     | [email protected]   |
| 6  | Adam Ibrahim    | NULL | Beginner     | [email protected]    |
| 7  | Ismail Khaled   | 22   | NULL         | [email protected]  |
| 8  | Ali Hassan      | NULL | NULL         | [email protected]     |
+----+-----------------+------+--------------+------------------------+

لاحظ أن مستوى Ahmed Moustafa تغير من Beginner إلى Intermediate

وطبعًا كما ذكرنا سابقًا، إذا لم نستخدم WHERE، سيتم تعديل كل الصفوف في الجدول
وستتفاجئ بأن كل الطلاب أصبحوا في المستوى Intermediate لمجرد أنك نسيت استخدام WHERE

تعديل قيم أعمدة متعددة لصف معين

يمكنك تعديل أكثر من عمود في نفس الأمر باستخدام الفاصلة , في جزء الـ SET

لنفترض أننا نريد تعديل العمر والبريد الإلكتروني للطالب Osama Ali في آن واحد

UPDATE Students
SET age = 20, email = '[email protected]'
WHERE name = 'Osama Ali';

بعد تنفيذ هذا الأمر، ستصبح البيانات كالتالي:

+----+-----------------+------+--------------+--------------------------+
| id | name            | age  | level        | email                    |
+----+-----------------+------+--------------+--------------------------+
| 1  | Ahmed Moustafa  | 20   | Intermediate | [email protected]     |
| 2  | Osama Ali       | 20   | Intermediate | [email protected] |
| 3  | Mohamed Adel    | 22   | Advanced     | [email protected]   |
| 4  | Kamal Mahmoud   | 21   | Beginner     | [email protected]     |
| 5  | Ayman Hassan    | 20   | Advanced     | [email protected]     |
| 6  | Adam Ibrahim    | NULL | Beginner     | [email protected]      |
| 7  | Ismail Khaled   | 22   | NULL         | [email protected]    |
| 8  | Ali Hassan      | NULL | NULL         | [email protected]       |
+----+-----------------+------+--------------+--------------------------+

تعديل الصفوف بناءً على شرط معين

طبعًا طالما نحن نستخدم الـ WHERE مع أمر الـ UPDATE فيمكننا تحديد أي شرط نريده وتعديل مجموعة من الطلاب في آن واحد
لنفترض أننا نريد تحديث مستوى جميع الطلاب الذين عمرهم أكثر من 20 عامًا ليصبح Advanced

UPDATE Students
SET level = 'Advanced'
WHERE age > 20;

بعد تنفيذ هذا الأمر، ستصبح البيانات كالتالي:

+----+-----------------+------+--------------+--------------------------+
| id | name            | age  | level        | email                    |
+----+-----------------+------+--------------+--------------------------+
| 1  | Ahmed Moustafa  | 20   | Intermediate | [email protected]     |
| 2  | Osama Ali       | 20   | Intermediate | [email protected] |
| 3  | Mohamed Adel    | 22   | Advanced     | [email protected]   |
| 4  | Kamal Mahmoud   | 21   | Advanced     | [email protected]     |
| 5  | Ayman Hassan    | 20   | Advanced     | [email protected]     |
| 6  | Adam Ibrahim    | NULL | Beginner     | [email protected]      |
| 7  | Ismail Khaled   | 22   | Advanced     | [email protected]    |
| 8  | Ali Hassan      | NULL | NULL         | [email protected]       |
+----+-----------------+------+--------------+--------------------------+

لاحظ أن الطلاب Mohamed Adel و Kamal Mahmoud و Ismail Khaled تم تحديث مستواهم إلى Advanced لأن أعمارهم أكثر من 20 عامًا
وعليك الحذر هنا لأننا استخدمنا WHERE age > 20 وليس WHERE age >= 20 بالتالي لو كان هناك طالب عمره 20 عامًا لن يتم تحديث مستواه
لأننا حددنا أن الشرط يجب أن يكون أكبر من 20 وليس أكبر من أو يساوي 20

تحديث قيمة عمود باستخدام قيمته الحالية

تخيل معي أنه قد مرت سنة دراسية جديدة وجميع الطلاب كبروا عامًا واحدًا بالطبع
بالتالي علينا زيادة أعمارهم بمقدار عام واحد

كيف يمكننا فعل هذا ؟

الأمر بسيط جدًا، نحن نستطيع استخدام القيمة الحالية للعمود في التعبير عن القيمة الجديدة في عملية رياضية

UPDATE Students
SET age = age + 1;

هكذا نحن نقول لـ SQL أننا نريد تعديل عمود age ليصبح قيمته الحالية زائد 1
وبالتالي سيقوم SQL بزيادة عمر كل طالب بمقدار عام واحد

+----+-----------------+------+--------------+--------------------------+
| id | name            | age  | level        | email                    |
+----+-----------------+------+--------------+--------------------------+
| 1  | Ahmed Moustafa  | 21   | Intermediate | [email protected]     |
| 2  | Osama Ali       | 21   | Intermediate | [email protected] |
| 3  | Mohamed Adel    | 23   | Advanced     | [email protected]   |
| 4  | Kamal Mahmoud   | 22   | Advanced     | [email protected]     |
| 5  | Ayman Hassan    | 21   | Advanced     | [email protected]     |
| 6  | Adam Ibrahim    | NULL | Beginner     | [email protected]      |
| 7  | Ismail Khaled   | 23   | Advanced     | [email protected]    |
| 8  | Ali Hassan      | NULL | NULL         | [email protected]       |
+----+-----------------+------+--------------+--------------------------+

هنا يوجد عدة ملحوظات مهمة يجب أن تعرفها:

لاحظ أننا لم نستخدم الـ WHERE في هذا الأمر
لأننا نريد تعديل جميع الصفوف في الجدول وهذا الأمر اجباري
لكن المشكلة في حد ذاتها تكمن في أننا لم نستخدم WHERE برغم من أننا مجبرين على تعديل كل الصفوف
لأنه لا يستحب أبدًا استخدام UPDATE بدون WHERE
لأنه تخيل لو كان الجدول يحتوي على 1000000 صف، ستجد نفسك تقوم بتعديل كل هذه الصفوف والـ Query ستستغرق وقتًا طويلاً جدًا لتنفيذها

لذا في هذه الأمور يرجع إلى كيف تم تصميم هذا الجدول وما هى البيانات التي نستطيع الاستغناء عنها والتى يمكننا تجاهلها
في حالتنا هذه نسأل سؤال لماذا نخزن عمر الطلاب من الأساس
كان من الأفضل أن نخزن تاريخ ميلادهم بدلًا من العمر وعن طريق تاريخ الميلاد نستطيع حساب العمر في أي وقت نحتاجه
وأيضًا تاريخ الميلاد ثابت لا يتغير لذا لم نكن لنضطر للقيام بهذه الـ Query في كل مرة

التعامل مع الـ Constraints

عند استخدام UPDATE، يجب أن تتذكر القيود الموضوعة على الأعمدة
لأنه لو كان هناك قيود مثل NOT NULL أو UNIQUE، فإن عملية UPDATE قد تفشل إذا انتهكت هذه الـ Constraints
على سبيل المثال لنفترض أننا نريد جعل قيمة العمود name تساوي NULL
بالطبع كما تتذكر فإن العمود name كنا قد جعلناه بـ NOT NULL

بالتالي إذا حاولنا تنفيذ الأمر التالي وتعديل اسم الطالب Ahmed Moustafa إلى NULL، ستفشل العملية

UPDATE Students
SET name = NULL
WHERE id = 1;

ستصادف الرسالة الجميلة التالية:

SQL Error: Column 'name' cannot be null

الرسالة بديهيًا تخبرك أن العمود name لا يمكن أن يكون NULL
بالتالي عملية الـ UPDATE ستفشل


نفس الأمر مع الـ UNIQUE إذا حاولت تحديث قيمة عمود الـ email إلى قيمة موجودة بالفعل في صف آخر فلن تنجح العملية
فالنفترض أنك تريد تحديث البريد الإلكتروني للطالب Ahmed Moustafa إلى نفس البريد الإلكتروني للطالب Mohamed Adel

UPDATE Students
SET email = '[email protected]'
WHERE id = 1;

هنا ستظر لك رسالة خطأ تخبرك أن البريد الإلكتروني موجود بالفعل في صف آخر

SQL Error: Duplicate entry '[email protected]' for key 'students.email'

الأمر ذاته ينطبق على نوع البيانات فمثلًا إذا حاولت تعديل عمود age إلى قيمة نصية مثل 'Twenty' وهو في الأساس من نوع INT، ستفشل العملية أيضًا

UPDATE Students
SET age = 'Twenty'
WHERE id = 1;

ستظهر لك رسالة خطأ تخبرك أن القيمة غير متوافقة مع نوع البيانات

SQL Error: Incorrect integer value: 'Twenty' for column 'age' at row 1

لذا عليك دائمًا أن تكون حذرًا عند استخدام UPDATE وأن تتأكد من أنك لا تنتهك أي Constraints موجودة على الأعمدة التي تريد تعديلها
والانتباه إلى نوع البيانات والقيم التي تقوم بتعيينها للأعمدة

استخدم الـ id عند تعديل بيانات شخص معين

في بعض الأمثلة السابقة استخدمنا الاسم في جزء الـ WHERE لتحديد الطالب الذي نريد تعديله مثل

WHERE name = 'Ahmed Moustafa';

لكن في الحياة الواقعية، يُفضل دائمًا استخدام الـ id بدلاً من الاسم أو أي عمود آخر

لماذا ؟ لأن الـ id هو العمود الوحيد الذي يمثل هوية الطالب وهو لا يتكرر ولا يتغير
بينما الاسم قد يتكرر، فقد يكون طالبان باسم Ahmed Moustafa أو يغير الطالب اسمه بعد فترة
حتى البريد الإلكتروني رغم أنه Unique ولا يتكرر، إلا أنه قد يتغير
لذا دائما عندما تريد البحث عن شخص لتقوم بتعديله، حاول دائما استخدام الـ id الخاص به
وخصوصًا إذا كان لديك جدول كبير يحتوي على العديد من الصفوف
لأن الـ id يتم انشاء شيء يدعى index table له وهو جدول خاص يساعد في تسريع عمليات البحث والتعديل على الصفوف بناءً على الـ id
سنتعرف على الـ index في المقالات القادمة

لذا الطريقة الذي ينصح بها هي استخدام الـ id كما في المثال التالي:

UPDATE Students
SET level = 'Advanced'
WHERE id = 3;

هذا يضمن أنك تعدل الطالب الصحيح دون أي خطأ

الخاتمة

أمر UPDATE هو كما لاحظت فهي من الأوامر الأساسية في الـ SQL
وهي أيضًا من الأوامر الضرورية لكي تقوم بتعديل البيانات كيف تشاء كما رأينا في الأمثلة

ملخص ما تعلمناه في هذه المقالة:

  • الغرض من UPDATE: تعديل البيانات الموجودة في الجداول
  • الصيغة الأساسية: UPDATE table_name SET column1 = value1, ... WHERE condition;
  • استخدم دائمًا WHERE: القاعدة الأهم عند استخدام UPDATE هي عدم نسيان الـ WHERE
    لأنها تحدد نطاق التعديل وتحمي بياناتك من التغييرات غير المقصودة على جميع الصفوف
  • تحقق من الـ Constraints: تذكر دائماً أن الـ Constraints الموضوعة على الأعمدة يتم التحقق منها أثناء عملية UPDATE
    الأمر بديهي ومشابه لما يحدث في أوامر INSERT وأيضًا نفس الشيء سنصادفه في المقالة القادمة عن DELETE
  • تعديل أعمدة متعددة: يمكن تحديد عدة أعمدة في جملة SET مفصولة بفواصل
  • تعديل عدة صفوف: يمكن تعديل أكثر من صف في نفس الوقت بناءً على شروط معينة
  • العمليات الحسابية: يمكن استخدام العمليات الحسابية والدوال لتحديد القيم الجديدة
  • التعامل مع القيود: UPDATE يلتزم بقيود NOT NULL وUNIQUE وغيرها، وستفشل العملية إذا انتهكت هذه القيود
  • استخدام الـ id: يُفضل استخدام الـ id بدلاً من الأسماء لضمان تعديل الصف الصحيح

الآن بعد أن فهمت كيفية تعديل البيانات، أصبحت قادراً على التعامل مع عمليات CREATE وINSERT وSELECT وUPDATE في SQL
تبقى لنا أمر أساسي واحد وهو DELETE، والذي سيسمح لنا بحذف البيانات من الجداول
ونكون في المقالة القادمة قد غطينا كل العمليات الأساسية في لغة الـ SQL والذي نسميها الـ DML اختصارًا لـ Data Manipulation Language
والتي تعني الأوامر التي تسمح لنا بالتحكم في البيانات داخل الجداول
وهي التي ترمز بالـ CRUD اختصارًا لـ Create وRead وUpdate وDelete