لماذا البرمجة الإجرائية داخل قاعدة البيانات؟
لماذا نكتب برامج داخل قاعدة البيانات نفسها؟ وما PL/SQL وأخواتها؟ ⏱ نحو 35 دقيقة.
- تفرّق بين
SQLالتصريحية والبرمجة الإجرائية داخل قاعدة البيانات. - تعرف
PL/SQLوأخواتها، ولماذا نتعلم بـPL/pgSQL. - تتعرف على جداول قاعدة المتجر.
- تكتب كتلة
DOفيها متغير وSELECT INTOوRAISE NOTICE.
١SQL تقول «ماذا»، والإجرائية تضيف «كيف»
في مقرر مبادئ قواعد البيانات كتبت استعلامات SQL: تصف ماذا تريد (SELECT name FROM products WHERE stock = 0)، وتترك لقاعدة البيانات أن تقرر كيف تجده. هذه لغة تصريحية Declarative.
لكن العمل الحقيقي يحتاج أحيانًا خطوات: «إذا نقص المخزون عن 5 فأنشئ طلب توريد، وإلا فسجّل البيع، وفي الحالتين حدّث الرصيد». هنا نحتاج متغيرات وشروطًا وحلقات تعمل داخل قاعدة البيانات. هذه هي البرمجة الإجرائية Procedural.
| SQL وحدها | مع البرمجة الإجرائية | |
|---|---|---|
| الأسلوب | أمر واحد يصف النتيجة | كتلة خطوات: متغيرات، و IF، و LOOP |
| أين تُكتب منطق الخطوات؟ | في التطبيق (PHP أو JavaScript…) | في قاعدة البيانات نفسها، قرب البيانات |
| عدد الرحلات عبر الشبكة | رحلة لكل استعلام | رحلة واحدة تنفّذ كل الخطوات |
| قواعد العمل | مكررة في كل تطبيق يستخدم القاعدة | مكتوبة مرة واحدة، يلتزم بها الجميع |
٢PL/SQL وأخواتها
كل نظام قواعد بيانات كبير أضاف إلى SQL لغة إجرائية. أشهرها PL/SQL من Oracle (المذكورة في خطة المقرر)، وعلى نمطها بُنيت PL/pgSQL في PostgreSQL التي نستخدمها هنا:
| النظام | اللغة الإجرائية | ملاحظة |
|---|---|---|
| Oracle | PL/SQL | الأقدم والأشهر في الشركات الكبيرة |
| PostgreSQL | PL/pgSQL | مبنية على PL/SQL: البنية والكلمات متقاربة جدًّا. نستخدمها في هذا المقرر |
MySQL / MariaDB | Stored Programs | إجراءات ودوال ومحفزات بصياغة أبسط |
| SQL Server | T-SQL | من Microsoft |
٣بيئة العمل
في هذا المقرر لا تحتاج تثبيت شيء: محرك PostgreSQL حقيقي يعمل في متصفحك. يُحمَّل أول مرة تضغط فيها ▶ تشغيل (نحو 6 ميغابايت)، ثم يعمل فورًا.
| البيئة | على جهازك | على الويب |
|---|---|---|
| PostgreSQL | خادم PostgreSQL مع pgAdmin أو الطرفية psql | هذه الصفحة |
| Oracle | Oracle Database XE مع SQL Developer | Oracle Live SQL (مجاني بحساب Oracle) |
| MySQL | XAMPP مع phpMyAdmin أو MySQL Workbench | — |
٤قاعدة «متجر الريان»
نتدرّب في المقرر على قاعدة متجر صغيرة: تصنيفات ومنتجات، وعملاء وطلبات، وبنود كل طلب. اعرف جداولها، فستعود إليها في كل درس:
categories 5 rows
- id integer PK
- name text
products 12 rows
- id integer PK
- name text
- category_id integer FK→categories
- price numeric(8,2)
- stock integer
customers 8 rows
- id integer PK
- name text
- city text
- email text
- joined date
orders 12 rows
- id integer PK
- customer_id integer FK→customers
- order_date date
- status text
order_items 21 rows
- order_id integer PKFK→orders
- product_id integer PKFK→products
- qty integer
- unit_price numeric(8,2)
SELECT id, name, price, stock FROM products ORDER BY id LIMIT 5;| id | name | price | stock |
|---|---|---|---|
| 1 | حاسب محمول | 3200 | 7 |
| 2 | جهاز لوحي | 1450 | 12 |
| 3 | شاشة 27 بوصة | 980 | 4 |
| 4 | فأرة لاسلكية | 75 | 60 |
| 5 | لوحة مفاتيح | 140 | 35 |
استعلام SQL عادي يعمل كما تعلّمت. اضغط ✏️ جرّب وعدّل وغيّر الشرط أو الأعمدة؛ كل تشغيل يبدأ من القاعدة الأصلية، فلا تخف من التجربة.
٥أول كتلة إجرائية: DO
أصغر برنامج إجرائي كتلة مجهولة Anonymous block: تُكتب وتُنفّذ مرة واحدة ولا تُحفظ. وRAISE NOTICE تطبع رسالة، مثل print في بايثون:
DO $$BEGIN RAISE NOTICE 'مرحبًا من داخل قاعدة البيانات';END $$;
الكتلة بين BEGIN و END، والعلامتان $$ تحيطان نصها كاملًا. الرسالة ظهرت في الشريط الداكن (NOTICE).
وتستطيع الكتلة أن تقرأ من الجداول وتحفظ النتيجة في متغير تعرّفه في قسم DECLARE، ثم تطبعه. علامة % في الرسالة تُستبدل بالقيمة:
DO $$DECLARE n int;BEGIN SELECT count(*) INTO n FROM products; RAISE NOTICE 'عدد المنتجات: %', n;END $$;
توقّع وتحقّق
لغة Oracle الإجرائية اسمها:
PL/pgSQL.ما الذي تضيفه البرمجة الإجرائية إلى SQL؟
أين يُعرَّف المتغير في الكتلة؟
ماذا تفعل RAISE NOTICE؟
print.الخلاصة
SQLتصف ماذا تريد؛ البرمجة الإجرائية تضيف المتغيرات والشروط والحلقات داخل القاعدة.PL/SQLلغةOracle، وPL/pgSQLفيPostgreSQLمبنية على نمطها.- الكتلة:
DO $$ DECLARE … BEGIN … END $$; SELECT … INTO متغيريحفظ النتيجة، وRAISE NOTICEتطبع.
تحدٍّ برمجي: عدّاد عملاء الرياض
تمهيدياكتب كتلة DO تحسب عدد العملاء في مدينة الرياض وتطبع النتيجة.
- متغير من النوع
intفي قسم DECLARE. - استعلام يحسب عملاء الرياض ويحفظ العدد في المتغير بـ
INTO. - رسالة NOTICE نصها:
عدد عملاء الرياض: 3(الرقم من المتغير لا مكتوب باليد).
👀 اعرض الناتج المطلوب
- الكود يعمل بلا أخطاء
- الرسالة «عدد عملاء الرياض: 3»
- العدد يُحفظ في متغير بـ INTO
- الرقم يُطبع من المتغير بـ %
- تعريف متغير في DECLARE
💡 تلميح 1
WHERE city = 'الرياض'.💡 تلميح 2
'عدد عملاء الرياض: %', n.حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.
DO $$DECLARE n int;BEGIN SELECT count(*) INTO n FROM customers WHERE city = 'الرياض'; RAISE NOTICE 'عدد عملاء الرياض: %', n;END $$;