4. التعبيرات في لغة SQL
4.1. Introduction
في معظم الأوامر SQL، يمكن استخدام تعبير. لنأخذ على سبيل المثال الأمر SELECT:
SELECT expr1، expr2، ... من table WHERE expression |
يختار SELECT الأسطر التي تنطبق عليها القيمة الصحيحة لـ expression ويعرض قيم expri لكل منها.
أمثلة
نهدف في هذه الفقرة إلى توضيح مفهوم التعبير. التعبير الأساسي يكون من النوع:
المعامل1 opérateur المعامل2
أو
دالة(معلمات)
مثال
في التعبير ، فإن GENRE = 'ROMAN'
- GENRE هو المعامل 1
- «ROMAN» هو المعامل 2
- = هو عامل العمليات
في التعبير upper(genre)
- upper هي دالة
- genre هو معلمة لهذه الدالة.
سنبدأ أولاً بمعالجة التعبيرات التي تحتوي على عوامل، ثم سنعرض الدوال المتوفرة في Firebird.
4.2. التعبيرات التي تحتوي على علامات عملية
سنصنف التعبيرات التي تحتوي على عوامل حسابية وفقًا لنوع المعاملات:
- رقمي
- سلسلة أحرف
- التاريخ
- منطقية أو بولية
4.2.1. التعبيرات ذات المعاملات من النوع الرقمي
4.2.1.1. قائمة العوامل الحسابية
لنفترض أن nombre1 و nombre2 و nombre3 أرقام. العوامل التي يمكن استخدامها هي التالية:
المعاملات النسبية
: العدد 1 أكبر من العدد 2 | |
: الرقم 1 أكبر من أو يساوي الرقم 2 | |
: العدد 1 أصغر من العدد 2 | |
: العدد 1 أصغر من أو يساوي العدد 2 | |
: العدد 1 يساوي العدد 2 | |
: العدد 1 يختلف عن العدد 2 | |
: كما سبق | |
: الرقم 1 يقع في النطاق [nombre2,nombre3] | |
: الرقم 1 ينتمي إلى قائمة الأرقام | |
: الرقم 1 ليس له قيمة | |
: الرقم1 له قيمة |
المُشغِّلات الحسابية
: الجمع | |
: الطرح | |
: الضرب | |
: القسمة |
4.2.1.2. المشغلات النسبية
يعبر التعبير النسبي عن علاقة تكون صحيحة أو خاطئة. وبالتالي، فإن نتيجة هذا التعبير هي قيمة بولية أو قيمة منطقية.
أمثلة:
![]()

![]()
4.2.1.3. العمليات الحسابية
التعبير الحسابي مألوف لنا. فهو يعبر عن عملية حسابية يجب إجراؤها بين بيانات رقمية. وقد سبق أن صادفنا مثل هذه التعبيرات: نفترض أن السعر المخزّن في السجلات الخاصة بالملف BIBLIO هو سعر غير شامل للضرائب. ونريد عرض كل ورقة مالية بسعرها TTC بمعدل TVA يبلغ 18.6%:
إذا كان من المقرر أن ترتفع الأسعار بنسبة 3٪، فسيكون الأمر كما يلي
يمكن أن نجد عدة عوامل حسابية في تعبير واحد، بالإضافة إلى الدوال والأقواس. تتم معالجة هذه العناصر وفقًا لأولويات مختلفة:
1 | <---- الأولوية الأعلى | |
2 | ||
3 | ||
4 | <---- أولوية أقل |
عندما يتواجد عاملان لهما نفس الأولوية في التعبير، يتم تقييم العامل الموجود في أقصى اليسار من التعبير أولاً.
أمثلة
سيتم تقييم التعبير PRIX*TAUX+TAXES على النحو التالي (PRIX*TAUX)+TAXES. ففي الواقع، سيتم استخدام عامل الضرب أولاً. سيتم تقييم التعبير PRIX*TAUX/100 على النحو التالي: (PRIX*TAUX)/100.
4.2.2. التعبيرات التي تحتوي على معاملات من نوع الأحرف
4.2.2.1. قائمة العوامل الحسابية
المُشغِّلات التي يمكن استخدامها هي التالية:
لنفترض أن «chaine1» و«chaine2» و«chaine3» هي نماذج لسلاسل الأحرف
: السلسلة 1 أكبر من السلسلة 2 | |
: السلسلة 1 أكبر من أو تساوي السلسلة 2 | |
: السلسلة 1 أصغر من السلسلة 2 | |
: السلسلة 1 أصغر من أو تساوي السلسلة 2 | |
: السلسلة 1 تساوي السلسلة 2 | |
: السلسلة 1 تختلف عن السلسلة 2 | |
: كما سبق | |
: السلسلة 1 تقع ضمن النطاق [chaine2,chaine3] | |
: السلسلة 1 تنتمي إلى قائمة السلاسل | |
: السلسلة 1 ليس لها قيمة | |
: السلسلة 1 لها قيمة | |
: السلسلة 1 تتطابق مع النموذج |
عامل التسلسل
السلسلة1 || السلسلة2 : تم ربط chaine2 بـ chaine1
4.2.2.2. عوامل العلاقة
ما معنى مقارنة السلاسل باستخدام عوامل مثل <، <=، إلخ...؟
يتم ترميز كل حرف برقم صحيح. وعند مقارنة حرفين، تتم مقارنة الرموز الصحيحة الخاصة بهما. يتبع الترميز المعتمد الترتيب الطبيعي للقاموس:
تأتي الأرقام قبل الحروف، والحروف الكبيرة قبل الحروف الصغيرة.
4.2.2.3. مقارنة سلسلتين
لنفترض العلاقة 'CHAT' < 'CHIEN'. هل هي صحيحة أم خاطئة؟ لإجراء هذه المقارنة، يقوم SGBD بمقارنة السلسلتين حرفًا حرفًا بناءً على رموزهما الصحيحة. بمجرد العثور على حرفين مختلفين، تُعتبر السلسلة التي تحتوي على الحرف الأصغر من بين الحرفين أصغر من السلسلة الأخرى. في مثالنا، تتم مقارنة 'CHAT' بـ 'CHIEN'. ونحصل على النتائج المتتالية التالية:
بعد هذه المقارنة الأخيرة، تم إعلان أن السلسلة 'CHAT' أصغر من السلسلة 'CHIEN'. وبالتالي، فإن العلاقة 'CHAT' < 'CHIEN' صحيحة.
لنقارن الآن بين «CHAT» و«chat».
بعد هذه المقارنة، تُعتبر العلاقة 'CHAT' < 'chat' صحيحة.
أمثلة


4.2.2.4. المشغل LIKE
يُستخدم المشغل LIKE على النحو التالي: chaîne LIKE modèle
تكون العلاقة صحيحة إذا كان chaîne مطابقًا لـ modèle. وهذا الأخير عبارة عن سلسلة أحرف قد تحتوي على حرفين بديلين:
التي تشير إلى أي تسلسل من الأحرف | |
التي تشير إلى حرف واحد أيًا كان |
أمثلة

![]()
![]()
4.2.2.5. مشغل التسلسل
![]()
4.2.3. التعبيرات التي تحتوي على معاملات من نوع التاريخ
لنفترض أن date1 و date2 و date3 هي تواريخ. العوامل التي يمكن استخدامها هي التالية:
المشغلات العلائقية
تكون صحيحة إذا كان date1 أقدم من date2 | |
تكون صحيحة إذا كان تاريخ1 أقدم من تاريخ2 أو يساويه | |
تكون صحيحة إذا كانت date1 لاحقة لـ date2 | |
تكون صحيحة إذا كانت date1 لاحقة لـ date2 أو مساوية لها | |
تكون صحيحة إذا كانت date1 و date2 متطابقتين | |
تكون صحيحة إذا كانت date1 و date2 مختلفتين. | |
كما سبق | |
تكون صحيحة إذا كانت date1 تقع بين date2 و date3 | |
تكون صحيحة إذا كان date1 موجودًا في قائمة التواريخ | |
تكون صحيحة إذا كانت date1 لا تحتوي على قيمة | |
تكون صحيحة إذا كانت date1 لها قيمة | |
تكون صحيحة إذا كانت date1 تتطابق مع النموذج | |
المشغلات الحسابية
: عدد الأيام الفاصلة بين date1 و date2 | |
: التاريخ 2 بحيث يكون التاريخ 1 - التاريخ 2 = العدد | |
: التاريخ 2 بحيث التاريخ 2 - التاريخ 1 = الرقم |
أمثلة

![]()
![]()
كم عمر الكتب الموجودة في المكتبة؟

4.2.4. التعبيرات ذات المعاملات المنطقية
تجدر الإشارة إلى أن القيمة المنطقية لها قيمتان محتملتان: صحيح أو خطأ. غالبًا ما تكون المعامل المنطقي نتيجة تعبير علائقي.
لنفترض أن booléen1 و booléen2 قيمتان منطقيتان. هناك ثلاثة عوامل حسابية ممكنة مرتبة حسب الأولوية:
| صحيح إذا كان كل من booléen1 و booléen2 صحيحين. |
| صحيح إذا كان booléen1 أو booléen2 صحيحًا. |
| تكون قيمتها عكس قيمة booléen1. |
أمثلة

نبحث عن الكتب التي تقع أسعارها بين:
![]()
البحث العكسي:

انتبه لأولوية العوامل الحسابية!
SQL> select titre,genre,prix from biblio
where genre='ROMAN' and prix>200 or prix<100
order by prix asc

نستخدم الأقواس للتحكم في أولوية العوامل الحسابية:
SQL> select titre,genre,prix from biblio
where genre='ROMAN' and (prix>200 or prix<100)
order by prix asc

4.3. الدوال المحددة مسبقًا في Firebird
يحتوي Firebird على دوال محددة مسبقًا. لا يمكن استخدامها مباشرةً في الأوامر SQL. يجب أولاً تشغيل البرنامج النصي SQL <firebird>\UDF\ib_udf.sql حيث يشير <firebird> إلى مجلد تثبيت Firebird:

مع IBExpert، نتبع الخطوات التالية:
- نستخدم الأداة [Script Excecutive] التي تم الحصول عليها عبر الخيار [Tools/ Script Executive]:

- بمجرد توفر الأداة، نقوم بتحميل البرنامج النصي <firebird>\UDF\ib_udf.sql:

- ثم نقوم بتنفيذ البرنامج النصي:

وبذلك، تصبح الدوال المحددة مسبقًا في Firebird متاحة للقاعدة التي كنا متصلين بها عند تنفيذ البرنامج النصي. وللتحقق من ذلك، يكفي الانتقال إلى مستكشف قواعد البيانات، والنقر على العقدة [UDF] الخاصة بالقاعدة التي تم استيراد الدوال إليها:

فيما سبق، نرى الوظائف المتاحة في قاعدة البيانات. لاختبارها، من المفيد أن يكون لدينا جدول مكون من سطر واحد. لنسمه TEST:

ونحددها على النحو التالي (انقر بزر الماوس الأيمن على «Tables» / «New Table»):
لنضع سطرًا واحدًا في هذا الجدول:


لننتقل الآن إلى محرر SQL (F12) ونصدر الأمر SQL التالي:
التي تستخدم الدالة المحددة مسبقًا cos (جيب التمام). يقوم الأمر أعلاه بحساب cos(0) لكل سطر في الجدول TEST، أي في الواقع لسطر واحد فقط. وبالتالي، يتم ببساطة عرض قيمة cos(0):
![]()
الدوال UDF (دوال محددة من قبل المستخدم) هي دوال يمكن للمستخدم إنشاؤها، ويمكن العثور على مكتبات من دوال UDF على الويب. لن نستعرض هنا سوى بعض الدوال المتوفرة مع الإصدار القابل للتنزيل من Firebird (2005). ونصنفها وفقًا للنوع السائد لمعلماتها أو وفقًا لدورها:
- الدوال ذات المعلمات من النوع الرقمي
- الدوال ذات المعلمات من نوع سلسلة الأحرف
4.3.1. الدوال ذات المعلمات من النوع الرقمي
| القيمة المطلقة لعدد abs(-15)=15 |
| أصغر عدد صحيح أكبر من أو يساوي nombre ceil(15.7) = 16 |
| أكبر عدد صحيح أصغر من أو يساوي nombre floor(14.3)=14 |
| حاصل القسمة الصحيحة (الحاصل عدد صحيح) لـ nombre1 على nombre2 div(7,3)=2 |
| بقية القسمة الصحيحة (النتيجة عدد صحيح) لـ nombre1 على nombre2 mod(7,3)=1 |
| -1 إذا كان nombre < 0 0 إذا كان nombre = 0 +1 إذا كان nombre > 0 sign(-6) = -1 |
| الجذر التربيعي لـ nombre إذا كان nombre ≥ 0 -1 إذا كان nombre < 0 sqrt(16)=4 |
4.3.2. الدوال ذات المعلمات من نوع سلسلة الأحرف
ascii_char(رقم) | الحرف ذو الرمز ASCII nombre ascii_char(65) = 'A' |
lower(سلسلة) | تحويل chaine إلى أحرف صغيرة lower('INFO') = 'info' |
ltrim(سلسلة) | Left Trim - يتم حذف المسافات التي تسبق النص chaine: ltrim(' chaton')='chaton' |
replace(سلسلة1,سلسلة2,سلسلة3) | يستبدل chaine2 بـ chaine3 في chaine1. replace('chat et chien','ch','**')='**at et **ien' |
rtrim(السلسلة1,السلسلة2) | Right Trim - مثل ltrim ولكن من اليمين rtrim('chat ')='chat' |
substr(السلسلة,p,q) | سلسلة فرعية من chaine تبدأ عند الموضع p وتنتهي عند الموضع q. substr('chaton',3,5)='ato' |
ascii_val(حرف) | رمز ASCII لـ caractère ascii_val('A')=65 |
strlen(سلسلة) | عدد أحرف chaine strlen('chaton')=6 |