المساعد الشخصي الرقمي

مشاهدة النسخة كاملة : الطريق لاحتراف الاوراكل .. دورة مطوري اوراكل .. من الالف الى الياء



The Coder
06-11-2005, 01:45 AM
بسم الله الرحمن الرحيم



مقدمة :



الحمد لله رب العالمين .. والصلاة والسلام على اشرف الانبياء والمرسلين .. سيدنا محمد وعلى اله وصحبه اجمعين .. وبعد ,,



محال ان تجبر شخص على عمل شيء لا يريده ...

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

وكل ما لدي قوله هو ان تساعد نفسك اولا .. فانا لا استطيع مساعدتك طالما لم ترد انت ذلك ...

وكلي ثقة انني سوف أساعدك على مساعدة نفسك ... بكل ما لدي من طاقة ... وان اترجم طاقاتك ابداعا ..

سأحاول بقدر المستطاع ان اجعلك تحصل على شهادة مطور اوراكل , وان اجعلك جديرا بحملها ,

ان اصبت فمن الله ... وان اخطأت فمن نفسي ومن الشيطان , فلا خير فيني ان لم اعترف بخطأي ... ولا خير فيكم ان لم تقوموني





المؤلف ,,

The Coder
06-11-2005, 01:49 AM
معلومات عن المؤلف :
لا معلومات ... غير ان اسمي حمزة ..... ولي خبرة في الاوراكل ..
تستطيع ان تقول .... "فاعل خير"

The Coder
06-11-2005, 01:51 AM
ملاحظات هامة جدا :

- استفسارات الدورة ... هنا على هذا الرابط :
http://www.montada.com/showthread.php?p=4304677#post4304677

- قد تجد بعض الصور مختفية او مفقودة , ماذا تفعل ؟ كل ما تفعله ان تأخذ ارقام الصور المفقودة , ثم تراسلني لكي ارسلها لك واصححها في الموضوع .



- قد تجد وصلات لا تعمل .. ماذا تقعل ؟ كل ما تفعله هو ان تأخذ ارقام الوصلات المفقودة , وتراسلني لكي ارسلها لك و اصححها في الموضوع .



- ليس كل ما أقوله قران منزل لا خطأ فيه ... قد اصيب او اخطئ !! لكن لا تخف .. سأشير الى النقاط التي لست متأكدا منها .. وما عداها فهي ان شاء الله صائبة ,,,



- اذا شاهدت خطأ ما .. فراسلني او اعرض خطأك في الموضوع ,,,



- اذا صعب عليك شيء ... راسلني او اعرض ما صعب عليك في الموضوع ..



- بعد انتهاء الدورة .. سوف اجمع الدروس واجعلها كتابا الكترونيا مجانا ..



- سوف اشير الى المصادر التي اخذت منها ... فترقبها



- اعتمدت المصادر العربية لكي يسهل عليك كعربي ان تراجعها .. وسوف ارسلها لك فيما بعد ... وسأرسل ايضا مصادر اجنبية ان شاء الله ,,



- ستلاحظ في دورتي الكثير الكثير من الامثلة .. والتي تسهل عليك فهم المادة ..



- ستلاحظ ان طرح الدروس غير منتظم .. مثل ان اطرح في الاسبوع الاول 7 دروس و الاسبوع الثاني درسين على سبيل المثال .. وهلم جر .. والسبب قد انشغل في بعض الاحيان .



- اذا لم يعجبك طريقة الشرح .. ارسل لي طريقة ترتاح لها انت .. او ارسل لي النقطة التي تزعجك !!



- لا تستحي من طرح أي شيء تريده ...



- ارجو عدم طرح أي رد ... لا اريد ان ارى "مشكور ما قصرت" ولا "الى الامام" او أي كلمات اخرى لا تغني او تسمن من جوع ,, الا اذا كان استفسار او تنبيه لنقطة او شيء من هذا القبيل



- ستجد الدروس على شكل ملف PDF وايضا على شكل رد في هذا الموضوع .. انتظر الملفات



- الواجبات ارسلها لي على الخاص او ارسلها لي على الايميل .... وحلها سوف تجده بعد المدة التي اراها انا .. انها مناسبة .. سوف احدد التاريخ ,,,



- اريد منك شيء واحد ... ان تجلس لمدة 60 ثانية من عمرك .. تدعي لي ولنفسك ولسائر المسلمين .. بس هاااااه .. لا تقول "جزاك الله خير " وخلاص !! ... ابيها من صميم قلبك .. مؤمن بأن الله يجيب دعوتك ...



- هذا كل ما لدي الان .. واي استفسار .. انا حاضر






بعد انتهاء الدورة .. سوف اجمع الدروس واجعلها كتابا الكترونيا مجانا ..</U></FONT></FONT>




- سوف اشير الى المصادر التي اخذت منها ... فترقبها



- اعتمدت المصادر العربية لكي يسهل عليك كعربي ان تراجعها .. وسوف ارسلها لك فيما بعد ... وسأرسل ايضا مصادر اجنبية ان شاء الله ,,



- ستلاحظ في دورتي الكثير الكثير من الامثلة .. والتي تسهل عليك فهم المادة ..



- ستلاحظ ان طرح الدروس غير منتظم .. مثل ان اطرح في الاسبوع الاول 7 دروس و الاسبوع الثاني درسين على سبيل المثال .. وهلم جر .. والسبب قد انشغل في بعض الاحيان .



- اذا لم يعجبك طريقة الشرح .. ارسل لي طريقة ترتاح لها انت .. او ارسل لي النقطة التي تزعجك !!



- لا تستحي من طرح أي شيء تريده ...



- ارجو عدم طرح أي رد ... لا اريد ان ارى "مشكور ما قصرت" ولا "الى الامام" او أي كلمات اخرى لا تغني او تسمن من جوع ,, الا اذا كان استفسار او تنبيه لنقطة او شيء من هذا القبيل



- ستجد الدروس على شكل ملف PDF وايضا على شكل رد في هذا الموضوع .. انتظر الملفات



- الواجبات ارسلها لي على الخاص او ارسلها لي على الايميل .... وحلها سوف تجده بعد المدة التي اراها انا .. انها مناسبة .. سوف احدد التاريخ ,,,



- اريد منك شيء واحد ... ان تجلس لمدة 60 ثانية من عمرك .. تدعي لي ولنفسك ولسائر المسلمين .. بس هاااااه .. لا تقول "جزاك الله خير " وخلاص !! ... ابيها من صميم قلبك .. مؤمن بأن الله يجيب دعوتك ...



- هذا كل ما لدي الان .. واي استفسار .. انا حاضر










JAVA

The Coder
06-11-2005, 01:54 AM
الخطة الحالية :

-مقدمة عن قواعد البيانات ,,

-لغة الـ SQL

-لغة الـ PL\SQL

-الـ Forms

-الـ Reports

-دروس في بناء وتصميم قواعد البيانات

- - ماهية قواعد البيانات

من الممكن ان اضع دروس بناء وتصميم قواعد البيانات في البداية قبل لغة الـ SQL

اما من ناحية ماهية قواعد البيانات وبصراحة ... سوف اقوم بالبحث عن ماهية قواعد البيانات لأنني لم ابرمجها .. فسأحاول معرفة ماهيتها لكي اشرحها لكم بكل يسر وسهولة ,, لذا لن اطيل في تعريف قواعد البيانات كثيرا , وقصدي في ماهية قواعد البيانات .. طريقة برمجتها + كيفية عملها تقنيا .

The Coder
06-11-2005, 02:04 AM
الدرس الاول :




مقدمة عن قواعد البيانات

-----------------------------------------------------------------

المتوقع منك :

- فكرة بسيطة جدا عن قواعد البيانات

- معرفة نظام قواعد البيانات المتبع في منهجنا ... الا وهو " نظام قواعد البيانات العلائقية"

- معرفة نظام ادارة قواعد البيانات

- معرفة المكونات الخاصة بنظام قواعد البيانات

---------------------------------------------------------------

· ماهي قواعد البيانات؟...ولماذا قواعد بيانات ؟؟





لا يخفى علينا اهمية البيانات لاي مؤسسة ولاي غرض كان ...

مثلا نريد بيانات الطلاب في جامعة ما , لكل طالب له بياناته الخاصة ,مثل (اسم الطالب , رقمه الجامعي .....الخ)

الان نسمي كل بيان من بيانات الطالب بـ "حقل"(Field) , يعني حقل اسم الطالب , حقل الرقم الجامعي ,

الان نجمع هذه الحقول , لينتج ما يسمى بـ "سجل"(Record) , سجل الطالب احمد او بيانات الطالب احمد ...

الان لدينا سجل لاحمد ومحمد وصالح وفارس وكل الطلبة بالجامعة

اذا جمعنا جميـــــــــــع السجلات ... نتج ما يسمى بـ "قواعد البيانات" (DATABASE)



يعني ان قواعد البيانات هي مجموعة من البيانات والمعلومات مخزنة بطريقة نموذجية وخاصة ودون تكرار والمتصلة مع بعضها وفق علاقات متبادلة .

- اكتفي الان بأنها طريقة نموذجية وخاصة !!

- مع الملاحظ اننا بقدر الامكان ان لا نكرر البيانات .. حتى لا تكبر مساحة قاعدة البيانات .

- لاحظ شيء مهم جدا جدا جدا .. قواعد البيانات مجرد ملف .. ملف عااادي جدا .. ولكن تركيبته خاصة جدا وسوف اشرحها فيما بعد ان شاء الله








· قواعد البيانات العلائقية :



قام علماء قواعد البيانات بتطوير قواعد البيانات .. وظهرت اشكال وانظمة عديدة لقواعد البيانات .. واشهر هذه الانظمة هي "نظام قواعد البيانات العلائقية" (علائقية ؟؟ ما معنى هذه الكلمة)

فكرة قواعد البيانات العلائقية هي .. مجرد جداول ...

جداول عديدة .. بينها علاقات (Relations)... (كيف ذلك ؟؟)

<ew Roman">- معرفة المكونات الخاصة بنظام قواعد البيانات </FONT>


---------------------------------------------------------------

· ماهي قواعد البيانات؟...ولماذا قواعد بيانات ؟؟





لا يخفى علينا اهمية البيانات لاي مؤسسة ولاي غرض كان ...

مثلا نريد بيانات الطلاب في جامعة ما , لكل طالب له بياناته الخاصة ,مثل (اسم الطالب , رقمه الجامعي .....الخ)

الان نسمي كل بيان من بيانات الطالب بـ "حقل"(Field) , يعني حقل اسم الطالب , حقل الرقم الجامعي ,

الان نجمع هذه الحقول , لينتج ما يسمى بـ "سجل"(Record) , سجل الطالب احمد او بيانات الطالب احمد ...

الان لدينا سجل لاحمد ومحمد وصالح وفارس وكل الطلبة بالجامعة

اذا جمعنا جميـــــــــــع السجلات ... نتج ما يسمى بـ "قواعد البيانات" (DATABASE)



يعني ان قواعد البيانات هي مجموعة من البيانات والمعلومات مخزنة بطريقة نموذجية وخاصة ودون تكرار والمتصلة مع بعضها وفق علاقات متبادلة .

- اكتفي الان بأنها طريقة نموذجية وخاصة !!

- مع الملاحظ اننا بقدر الامكان ان لا نكرر البيانات .. حتى لا تكبر مساحة قاعدة البيانات .

- لاحظ شيء مهم جدا جدا جدا .. قواعد البيانات مجرد ملف .. ملف عااادي جدا .. ولكن تركيبته خاصة جدا وسوف اشرحها فيما بعد ان شاء الله








· قواعد البيانات العلائقية :



قام علماء قواعد البيانات بتطوير قواعد البيانات .. وظهرت اشكال وانظمة عديدة لقواعد البيانات .. واشهر هذه الانظمة هي "نظام قواعد البيانات العلائقية" (علائقية ؟؟ ما معنى هذه الكلمة)

فكرة قواعد البيانات العلائقية هي .. مجرد جداول ...

جداول عديدة .. بينها علاقات (Relations)... (كيف ذلك ؟؟)

بمجرد وضع صفوف واعمدة ... العمود الواحد يمثل الحقل !! والصف الواحد يمثل سجل !!



انظر الصورة (11)



http://www.w6w.net/upload2/21-11-2005/w6w_20051121011950127cfb97.JPG


هذا جدول الطلاب او قواعد البيانات الخاصة بالطلبة و به معلومات عن الطلبة ...
ونعمل جدول اخر للكليات مثلا وبه معلومات للكليات ... وجدول ثالث للمواد .... وهكذا ..





نقاط مهمة عن نظام قواعد البيانات العلائقية :



- نظام قواعد البيانات العلائقية اشهر واقوى الانظمة والتي تعتمد عليه اغلب برامج قواعد البيانات ومن ضمنها اوراكل

- لماذا هذا النظام بهذه القوة ؟

- لانه يستوعب قدر كبير جدا من البيانات

- لان ادائه من ناحية السرعة والدقة .. لا تتأثران مع كمية البيانات الضخمة

- لانه يتمتع بالسرية التامة والامان لاحتوائه على نظام اعطاء الصلاحيات






* نظام ادارة قاعدة البيانات DBMS (اختصار لـ Database Management Information System )



عبارة عن برامج .. والتي تعتبر حلقة الوصل بين المستخدم (المستخدم ؟؟ ومن هو المستخدم يا ترى؟) وقاعدة البيانات .

البرامج هذه تعدل على البيانات وتضيف وتحذف وتخزن البيانات , أي انها تدير البيانات .

البرامج ايضا تستقبل طلبات المستخدمين و تنادي برامج اخرى تنفذ العملية والطلب على قواعد البيانات .. ومن ثم ترجع بالنتيجة الى المستخدم .. مثل مستخدم طلب معلومات الطالب احمد .. هذه البرامج متكفلة باحضار معلومات احمد من جدول الطلاب وتعرضها للمستخدم .



هذه البرامج تسمى DBMS






* مكونات نظام قواعد البيانات :

1- المكونات المادية

مثل الحاسبات المتصلة بقواعد البيانات , الطابعات , اجهزة الاتصالات ..... الخ



2- البرمجيات او البرامج .

وهي ثلاث اقسام ,

- نظام التشغيل مثل وندوز او ماكنتوش او لينيكس.....

- برنامج قواعد البيانات مثل الاوراكل او الاكسس ...

- برامج تطبيقية وبرامج اخرى مساعدة : مثل التي تستخرج التقارير مثلا لعرضها وطباعتها على ورق .. او برامج لتصميم النوافذ والواجهات ....الخ .



3- المستخدمون .

وهم كما يلي :

* مدير النظام : الذي يدير عمل البيئة ككل ومهامه :

- يقوم بمتابعة عمل النظام ,

- يدير اجهزة التخزين والاجهزة الاخرى

- يدير المستخدمين ويعطي الصلاحيات المناسبة لكل مستخدم .



* مدير قاعدة البيانات : يقوم بادارة قاعدة البيانات ومهامه :

- يحدد متطلبات قواعد البيانات من برامج وتجهيزات ,

- يتابع نظام قواعد البيانات .

- يوفر الامن للنظام

- يحافظ على قواعد البيانات ويوفر الخدمات للمستخدمين الاخرين



*مصمم قاعدة البيانات : وهو الشخص الذي يصمم قواعد البيانات ومهامه :

- تحدد البيانات الواجب تخزينها في قواعد البيانات

- تصميم افضل التراكيب لحفظ البيانات

- تصميم قاعدة بيانات خالية من التكرار

- يصمم الشاشات والتقارير بطريقة سهلة للوصول الى البيانات والتعامل معها

- توثيق عملية التصميم وطرق الوصول للبيانات



*المبرمجون ومحللو النظم : وهم الذين يقومون ببرمجة النظام ومهامهم :

- تصميم النظام وبرمجته باللغة او اللغات البرمجية المقررة

- اختبار تلك البرامج للتأكد من خلوها من الاخطاء

- صيانة البرامج .



* المستخدم النهائي : وهو الذي يقول باضافة البيانات والتعديل والحذف وووو .. ويقوم باستخدام النظام ... على سبيل المثال مدخل البيانات





4- الإجراءات والعمليات : بعض القوانين التي تحكم قواعد البيانات .. وتختلف من مؤسسة الى اخرى ,



5- البيانات : هي اهم المكونات .. وهي الحقائق المخزنة مثل اسماء الطلاب وارقامهم وبقية البيانات الاخرى ..

احب ان اشير الى ان المصمم لقواعد البيانات هو الذي يحدد مكان وتخزين البيانات هذه .








لا يوجد عندي اسئلة ... غير ان هذا ليس كل شيء عن قواعد البيانات .. وسوف يكون هناك المزيد ان شاء الله ,,,

The Coder
06-11-2005, 05:56 AM
احب ان اشير لشيء ..

لا ترد برد .. الا ذو نفع لنا ..

راجعو النقاط والملاحظات المهمة ,,,

ياسرر
06-11-2005, 11:53 AM
شكررررررررررررررررررررا

CHALLENGER
06-11-2005, 02:30 PM
لا ترد برد .. الا ذو نفع لنا ..
[size=7]size]




شكررررررررررررررررررررا



سبحان الله :)

اتمنى من المشرفين مسح الرد يلي قبلي و ردي كمان ما نريد ردود الا مفيدة او فيها سؤال

The Coder
07-11-2005, 05:29 AM
ايميلي :
اسف (hamzah79@hotmail.com) ,, يوجد ضغط عجيـــــــــــــــــــــب في ايميلي ... حنشوف لكم حل في مسألة الايميل قريبا ان شاء ربي

The Coder
09-11-2005, 03:23 AM
اقووووووول ..
لم يصلني الا ثلاث اشخاص !!!!!!

وين الناس .. لي يومين انتظر .... فين المعلومات الي طلبتهم ؟؟


على فكرة ... عندي قوانين جديدة .... جديرة بان تكون دورة على اسمها ...

1- انتم من يتحكم في سرعة طرح الدروس .. وليس انا ,.. اي انني من الممكن انتهي من الدرس .. ولن اطرحه حتى ارى التفاعل ...


2- الواجبات ... لازم يحلها على الاقل 10 اشخاص ... رغم انه يوجد اكثر من 25 شخص تكفلو بحل الواجبات ... اذا لم تصلني الحلول العشر على الاقل فسوف اطرح الدرس الي بعده .. ولن اطرح اي درس ... حتى تأتيني حلول .. او محاولات ...


3- يوجد عندي جدول بقائمة الاسماء او الالقاب التي تتابعني .... فأعرف من معي على الخط ... واعرف من لم يكن معي ....


4- لن احل الواجبات ابدا .. الا اذا جائتني العشر محاولات او الحلول ..


5- واخيرا ... كيفية الارسال ...

العنوان : !!!!!!!!!!!!!!!!!!
الرسالة :
الاسم او اللقب او اي شي يدل على وجود انسان يكلمني : _ _ _ _ _ _
العمر : __ ____ (يلزمني العمر .. لمعرفة على الاقل عقلية هذا الشخص.. واذا ارسل سابقا ... فلا داعي للعمر)
الواجب :
_ _ _ _ _
_ _ _ _ _
_ _ _ _ _


اسف على ازعاجكم ...

ولكن انا لا اكتب كتاب فقط .. انا اعمل دورة على الهواء مباشرة ^^

وعلى فكرة .. الدرس الثاني غدا اضعه ان شاء الله ...
ولا ارى اي وجود بشري لايميلي ...

تفاعلو حفظكم الله .. الزوار عددهم اكثر من المئة ....

The Coder
09-11-2005, 07:06 AM
بسم الله الرحمن الرحيم
الدرس الثاني
ملاحظة مهمة : ما بين القوسين تنبيه او ما اتوقعه من القاريء

اسم الدرس : مدخلك الى تصميم قواعد البيانات

نوع الدرس : نظري مع مفاهيم أساسية ...

صعوبة الدرس : *** من *****

الوقت المتوقع منك لفهم الدرس : ساعة و 30 دقيقة ربما تزيد كثيرا أو تنقص

متطلبات تتوفر فيك : تحمل على قراءة السطور .. وتفهمها لكي ترتاح مستقبلا

ملاحظات :

- قد لا تفهم بعض النقاط !! لا تخف .. سوف تعرفها بالتمرس والتكرار فيما بعد ,,

- أصابني التعب والإعياء في هذا الدرس الصغير , لكي اجعله مفهوم لدرجة أن الأبله يفهمه !



المتوقع منك في هذا الدرس :

- معرفة أكثر عن قواعد البيانات

- معرفة أكثر في قواعد البيانات العلائقية

- معرفة ما هو المفتاح الاساسي

- العلاقات وانواعها

- ماهو المفتاح الاجنبي

===================================


قواعد البيانات .. بتعمق :
تحدثنا عن قواعد البيانات وقلنا انه مجموعة من البيانات مخزنة بطريقة نموذجية دون تكرار والمتصلة مع بعضها وفق علاقات متبادلة .

وانها ملفات تركيبتها خاصة .. (لماذا لها هذه التركيبة الخاصة ؟) لكي تستوفي بعض الشروط وبعض المميزات سوف اذكر بعض منها .. بعد ان قرأتها في احد المذكرات الالكترونية من الكاتب "الاسيف" جزاه الله الف الف خير وبعض المميزات مايلي :

- عدم تكرار البيانات

- تجانس وتوافق البيانات : أي مهما حدث من تغيير في البيانات لا تتأثر بنية البيانات

- قابلية التطوير : بامكاننا ان نطور قاعدة البيانات بسهولة وبدون ان نحذف القديم

- استقلالية البيانات عن البرامج .

- السرية

- امكانية وصول اكثر من مستخدم لقواعد البيانات



ذكر لنا الاخ أسيف انه يوجد احد الانظمة القديمة التي تسمى بنظام الملفات التقليدية وهو نظام استخدم قبل قواعد البيانات.. كانوا يخزنون البيانات في ملفات مستقلة (مستقلة = لا يوجد بينها علاقة ) وبها عيوب وهي :
- التكرار :

مثلا للطلاب ملف خاص وبهذا الملف معلومات الطلاب . اسم الطالب , رقم الطالب , معدله ......
للمدرسين ملف خاص وبهذا الملف معلومات المدرسين . اسم المدرس , رقم المدرس , راتبه ....
طيب ... لو اردنا اسماء المدرسين الذين الطالب احمد ؟ او اسماء كل الطلبة الذين يدرسون عند المدرس خالد ؟ مالحل ؟ طبعا ملف ثالث وفيه اسماء الطلبة ومدرسيهم .. يعني تكراااااااار ...
سوف يتم كتابة معلومات الطلبة والمدرسين مرة اخرى في هذا الملف الثالث
ولا اعرف ما اذا كان في هذا النظام القديم يتم عمل ملف رابع وفيه اسماء المدرسين وطلبتهم ؟ ولكن لا نستغرب اذا كان هناك ملف رابع .



- عدم توافق البيانات

يجب ان لا نفقد تجانس وتوافق البيانات اذا عدلنا او اضفنا او حذفنا بيانات ,, لكن في مثالنا السابق.. قلنا انه يوجد ملف طلاب .. وملف مدرسين .. وملف الطلاب ومدرسينهم , فلو حذفنا طالب في ملف الطلاب ولم نحذفه في الملف الثالث (الملف المشترك بين الطلاب والمدرسين) فسوف نجد معلوماته في ملف و ولا نجده في الملف الاخر .

فهذه ميزة في قواعد البيانات , وهي عيب في نظام الملفات التقليدية .



- زيادة زمن بناء الانظمة :

لماذا الزمن يزيد مع هذا النظام ؟ لاننا سوف نلجأ الى انشاء ملفات كثيرة لتحقيق المتطلبات المختلفة .



- الحاجة المستمرة لاعادة هيكلة البرامج والملفات : أي ان التطوير صعب جدا .. يفرض علينا ان نغير ونبدل ونضحي عن بعض هيكلة البرامج والملفات القديمة .



==========================================



قواعد البيانات العلائقية ... بتعمق
تحدثنا عن نظام قواعد البيانات العلائقية .. وقلنا بأنه تمثيل البيانات بجداول ثنائية الابعاد (2D- Table ) , صفوفها سجلات , واعمدتها حقول .

الان اريدك ان تعرف مسمى للاعمدة .. لان المسميات مزعجة قليلا .. فمثلا Attribute" " (خصائص .. او صفات ).... فهي تخص الاعمدة .. أي ان الحقول (Field) هي نفسها خصائص هي نفسها صفات هي نفسها الاعمدة .



الان يجب ان نراعي في قاعدة البيانات العلائقية وجود المفاهيم التالية :

- اسم للجدول : مثل جدول الطالب , جدول المواد , جدول ......

- الصفات : المقصود بها الاعمدة .. تسمى صفات الجدول كما ذكرنا ... مثل اسم الطالب , رقم الطالب ..... الخ

- مجال القيم (Domain) :المقصود بها .. القيم الموجودة بداخل اسم الطالب مثلا , كم تأخذ حرف ؟ مثال اخر , رقم الطالب .. ماهو مجاله ؟؟ يعني هل من 0 – 9999 ؟؟ او من 0- 100000 مثلا ؟؟ ويمكننا تحديد مجال القيم لكل صفة على حسب احتياجنا .(لم افهم؟)

مثلا العمود "اسم الطالب" انا افرض انه يأخذ 15 حرف كحد اقصى .. و3 حروف كحد ادنى
والعمود "المعدل " افرضه من صفر الى 5 وان يكون كسري
والعمود "راتب المدرس" مثلا .. افرضه من 3500 ريال الى 9000 ريال ... بالعقل يعني هل من الممكن ان يكون راتب مدرس صفر ريال ؟؟ اذن مجال راتب المدرس هو من 3500 الى 9000

- العلاقة (Relation) : مثلا جدول المواد وجدول الطلاب , بينهما علاقة (Relation) ماهي هذه العلاقة ؟ سوف تعرف ذلك فيما بعد

- المفتاح الرئيسي للجدول (Primary key) : ماهو هذا المفتاح ؟ مجرد عمود , ولكن هذا العمود له شروط لكي يصبح مفتاح رئيسي للجدول .





* المفتاح الاساسي :

الشروط اللازمة لتوفرها في العمود لكي يكون مفتاح اساسي هو :

1- عدم التكرار

2- ان لا يكون خالي

وهذا العمود له غرض مهم جدا . وهو ان نميز الصف من بين الصفوف (لم افهم ؟)

انظر المثال :
يوجد لدينا جدول خاص بالموظفين لاحد الشركات
جدول الموظفين كما يلي : (صورة 12 )


http://www.w6w.net/upload2/21-11-2005/w6w_20051121041216d52dfe51.JPG

مارأيك .. ما هو العمود الذي ترى انه مفتاح اساسي .. أي عمود لم يتكرر او لم يكن خاليا ؟

انا اقول "اسم الموظف الاول " ... هذا العمود هو المفتاح الاساسي !! هل هذا صحيح ؟ طبعا لا ,, لماذا ؟ لانه تكرر فيه صفين .. هما خالد و خالد

هل "اسم الاب " هو المفتاح الاساسي ؟ لا لان سعيد تكرر مرتين .
هل "الراتب " هو المفتاح الاساسي ؟ لا
هل تاريخ الميلاد هو المفتاح الاساسي ؟ لا
هل المكافئة الاضافية هو المفتاح الاساسي ؟ نعم لانه لم يتكرر ... ولكن لحظة !! قلنا انه من صفات المفتاح الاساسي ان لا يتكرر + ان لا يكون فيه قيم خالية
والمكافئة الاضافية .. عمود لا يستحق ان يكون مفتاح اساسي . لان به قيم خالية ... فمثلا محمد سعيد الثاني لا يوجد لديه مكافئة اضافية (قيمة خالية)
(ما الحل ؟) نضيف عمود نجده يصلح بأن يكون مفتاح اساسي

(لماذا نضيف عمود .. ونزيد كمية البيانات بلا داعي؟) بل يوجد هناك سبب مقنع لاضافته ..
من جدول الموظفين (الصورة 12 السابقة ) اريد معلومات خالد منصور بذاته ... سوف تجد ان هناك اثنين ولا استطيع التمييز بينهما يمكن يكون هناك 1000 موظف اسمه خالد منصور ولا نعرف ان نفرق بينهما

انا من ناحيتي ... ارى ان نضيف عمود جديد ويسمى "رقم بطاقة الاحوال المدنية" وهو رقم لا يتكرر ابدا بين المواطنين في دولة ما .. ولا يمكن ان يكون خاليا !!

ماذا تقترح انت ؟ مارأيك ان نضيف مثلا عمود يسمى رقم الموظف كما في الجدول التالي (الصورة22)



http://www.w6w.net/upload2/21-11-2005/w6w_20051121041327c9571bae.JPG
اذن المفتاح الاساسي هو رقم الموظف ... لو أتى موظف جديد نعطيه الرقم 6 ...

مع العلم ان المفتاح الاساسي في الجدول يجب ان يكون تحته خط .. كما تشاهد الخط تحت رقم الموظف

-------------------------------------------------------------------

معلومة اضافية : بعض الشركات تعمل برامج خاصة تولد المفتاح الرئيسي (كيف تولد المفتاح الرئيسي ؟)

مثلا تأخذ اول حرف من اسمه واول حرف من اسم الاب وتأخذ سنة ولادته وتضيف عداد بجانب الرمز الناتج على سبيل المثال وتولد المفتاح الاساسي من هذه المعلومات . على سبيل المثال .. الموظف سامي عبدالرحمن (انظر الصورة 22) ممكن يكون رمزه " سع 1401_01" بدلا من الرقم 5 (في الصورة 22)

ولو فيه موظف اخر اسمه سامي عبدالرحمن ومولود في نفس سنة سامي عبدالرحمن السابق فان رمزه هو

"سع 1401_02"

وهذا مجرد مثال .... على حسب الشركة على حسب الغرض ينتج الرمز .


فاصل اعلاني ,,,

The Coder
09-11-2005, 07:23 AM
تابع الدرس الثاني

العلاقات :
بين كل جدول وجدول علاقة , فمثلا جدول الموظفين و جدول الأقسام بينهما علاقة

العلاقة ما هي يا ترى ؟

العلاقة هي ان الموظف الواحد يعمل تحت قسم واحد

وان القسم الواحد به اكثر من موظف يعمل به

ما رأيك ان نفترض هذا الجدول (الصورة 32) :


http://www.w6w.net/upload2/21-11-2005/w6w_2005112104153831eadbe0.JPG



لاحظ معي هذه المعلومات , انظر الى قسم المحاسبة وهو قسم واحد ويوجد بمكة ويستوعب 60 شخص ...

لاحظ معي ان هذا القسم به 3 موظفين وهم وليد وسعد واحمد ...

لاحظ معي ان القسم به معلومات خاصة تكررت !!

كم مرة ذكرنا ان قسم المحاسبة موقعه في مكة وانه يستوعب 60 موظف ؟؟

ولو هناك 1000000 موظف في هذا القسم على سبيل المثال !! هل لاحظت ان هذا التكرار قد يجعل حجم البيانات ضخم لدرجة الهوس !

نكتشف انه يوجد تكرار للمعلومات !! ويجب ان نتحاشى هذا التكرار . كيف ؟

نصمم جدول خاص بمعلومات الاقسام . وليكن هذا الجدول (صورة 42) "جدول الاقسام "




http://www.w6w.net/upload2/21-11-2005/w6w_200511210425576bea0403.JPG



اين المفتاح الاساسي ؟

رقم القسم هو المفتاح الاساسي (لاحظ الخط الذي تحت رقم القسم )

الان دعنا نتصور الجدول الاساسي وقد صار فيه معلومات الموظفين ونسميه مثلا "جدول الموظفين "

الصورة (52)

http://www.w6w.net/upload2/21-11-2005/w6w_20051121043213fb042e7a.JPG


نريد ان نعرف ان الموظف يوسف مثلا في قسم الرواتب !! كيف ؟؟ نريد ان نربط بين الجدولين ؟؟ كيف نربط بين الجدولين ؟؟

اليك هذا الحل :

نزيد عمود في جدول الموظفين ونسميه "رقم القسم" ونكتب رقم القسم فيه ... اليك الجدول الجديد (الصورة 62)




http://www.w6w.net/upload2/21-11-2005/w6w_20051121043429676c0c9b.JPG




لاحظ هذه الارقام (ارقام القسم ) لم تأتي عبطا !!

فاحمد وسعد ووليد ... جميعهم في القسم رقم واحد ,,, والقسم رقم واحد من أين نأتي به ؟؟ من جدول الاقسام (راجع الصورة 42)

وهو المحاسبة ومقر القسم بمكة ويستوعب 60 شخص ....

يوسف في القسم 2 .. وهو قسم الرواتب الذي يقع في الرياض ويستوعب 40 موظف

(وماذا عن سالم ؟)

(لم افهم حقا ما حصل !! لماذا فصلتهما في جدولين ؟ لماذا فعلت ذلك ؟)

لاحظ يا عزيزي انه في الصورة 62 قد تكرر الرقم "واحد" ثلاث مرات ... (نعم صحيح .. اذن طريقتك خاطئة !)

ليست طريقة خاطئة ولكن كم عمود به تكرار ؟ عمود واحد وهو رقم القسم فقط ... شاهد الصورة 62

واما الجدول القديم (الصورة 32) فقد تكررت المعلومات في ثلاث اعمدة !! وهي اسم القسم ومكانه واستيعابه .

(طيب .. لم تفرق كثيرا ..)

بل تفرق كثيييييييييرا لو فكرت مليا !! ... فكر لو يوجد 1000000 موظف كم من البيانات تتكرر في الجدول السابق (انظر الصورة 32) ؟؟

فكر لو ان جدول الاقسام به 50 عمود ... كم من البيانات سوف تتكرر ؟؟؟

الان ... هل شاهدت العمود الذي اضفته في جدول الموظفين (اقصد عمود رقم القسم ) ؟(انظر الصورة 62)

هذا العمود يدعى المفتاح الاجنبي Foreign Key (ما فائدة هذا المفتاح ؟؟ وكيف اعرف ما اذا كان هذا العمود مفتاح اجنبي او لا ؟؟)

المفتاح الاجنبي :

كما شاهدنا .... غرضه هو ربط جدولين ... وكما في مثالنا السابق .. ربطنا جدول الموظفين بجدول الاقسام ... وجعلنا المفتاح الاجنبي في جدول الموظفين وهو العمود الخاص برقم القسم .

( كيف أميز المفتاح الاجنبي ) المفتاح الاجنبي هو مفتاح اساسي في جدول اخر .. أي انه مفتاح اساسي في جدول الاقسام , وهو في جدول الموظفين اجنبي !!

(استنتجت شيء !! هل يوجد مفتاح اجنبي في جدول الاقسام ؟؟ ) لا لا يوجد (لماذا ؟على أي اساس اضيف المفتاح الاجنبي ؟)

نحن اضفنا عمود في جدول الموظفين وسميناه مفتاح اجنبي ولم نضيف مفتاح اجنبي في جدول الاقسام لسبب .. ستعرفه في الدرس القادم ان شاء الله :

اريدك الان ان تستنتج ذلك عبر درجات العلاقات


درجة العلاقات :

سوف نتكلم نظريا عن مفاهيم هذه الدرجات فهناك ثلاث درجات وهي /

- واحد لواحد : مثل علاقة المسافر بالتذكرة ... فالمسافر الواحد يملك تذكرة واحدة للرحلة الواحدة .. والتذكرة الواحدة يمتلكها مسافر واحد للرحلة الواحدة

هل يمكن لمسافرين ان يمتلكان تذكرة واحدة للرحلة الواحدة ؟؟ لا .... وهل يمكن للمسافر ان يمتلك تذكرتين للرحلة الواحدة ؟ لا طبعا ...

مثال اخر ...

الشخص الواحد لديه روح واحدة .... الروح الواحدة في شخص واحد ...

- واحد لمتعدد أو متعدد لواحد : مثلا ان يعمل الموظف الواحد في قسم واحد .. والقسم الواحد يعمل تحته مجموعة موظفين (موظفين متعددين .. يعني ممكن يكون موظف واحد ويمكن اكثر ) هل استنتجت لماذا اضفنا المفتاح الاجنبي في جدول الموظفين ؟

مثال اخر .. العلاقة بين رجل وامرأة الزواج .. الرجل يتزوج اكثر من امرأة (طالما انهم جميعا احياء) وان المرأة لا تتزوج الا رجل واحد (طالما انهما احياء)....

- متعدد لمتعدد : مثل .. الطالب يدرس تحت مجموعة معلمين ... والمعلم الواحد يدرس اكثر من طالب

مثال اخر .....

الكابتن الواحد يقود اكثر من طائرة ... والطائرة الواحدة يقودها اكثر من كبتن



انتهى الدرس ولله الحمد





الواجب :

نوعه : اعتمادي على الطالب

ملاحظات :

اريد منك شيء واحد .. اقرأ الدرس جيدا ... ثم حل الواجب بدون ان ترجع للدرس ... لان فيه تمرين العقل وقوة استيعابه ... وهو تكنيك رااااااائع



س1 : اضرب لي 3 امثلة لم اذكرها لدرجة العلاقات (واحد لواحد ... و متعدد لمتعدد ... و متعدد لواحد او واحد لمتعدد)



س2:في رأيك ... عندنا جدولين .. ويلزمنا ان نربط بينهما ... هما جدول المدينة وجدول الدولة

اين نضع المفتاح الاجنبي ؟ في أي جدول ؟



س3: اشرح لي مايلي بطريقتك الخاصة وبفهمك .. ولا يهمني اذا كان صحيح ام خاطيء:

- المفتاح الرئيسي ماهو ؟ ولماذا نستخدمه ؟ ومتى نعرف ما اذا كان هذا مفتاح اساسي او لا ؟

- المفتاح الاجنبي ماهو ؟؟ ولماذا نستخدمه ؟ ومتى نعرف ما اذا كان هذا مفتاح اجنبي او لا ؟

- قواعد البيانات ماهي ؟

- نظام قاعدة البيانات العلائقية ما هو ؟



س4 : فكر في جدولين (مثال من عقلك لاي جدولين ) واضف مفتاح اساسي , ولو استطعت اضف مفتاح اجنبي ...



س5: اجلب برنامج الفيزيو .. من شركة مايكروسوفت .... وهو خاص برسم الـنماذج ... حاول ان تحصل عليه ... فهو مفيد جدا جدا جدا ... في دروسنا وغيرها .. وله مأرب أخرى ,,,,

The Coder
12-11-2005, 04:36 PM
السلام عليكم ...
لم يصلني الا 4 واجبات او 5 ....
يالله .. انا انتظر ......

ولا تنسو شكل الرسالة الي بترسلون لي .....
يالله يا هووووه .... الواجب مايستاهل ... (اقول ... والله محد درى عنك ><)

The Coder
21-11-2005, 01:33 PM
6 واجبات !!!

احباااااااط ... فين الناس ؟؟ فين العالم ؟؟

صراحة .. انا قررت اطرح الدروس ..... بدون التقيد بالواجبات ..
شكرا لكل من حل الواجبات ,,,,,
واطلعت عليها ....
جهود مشجعة للاكمال .. ^^

الدرس الثالث اليوم او الغد ان شاء الله .. وما اخرني الا فايروس .. ضرب مخي وجهازي >_<
يالله .. انتظروني

The Coder
22-11-2005, 10:45 PM
بسم الله الرحمن الرحيم

الدرس الثالث


اسم الدرس :نموذج الكيانات والعلاقات ER



نوع الدرس : نظري + رسومي + تحليلي


صعوبة الدرس : ***** من *****

اهميــة الدرس : ***** من *****

الوقت المتوقع منك لفهم الدرس : ساعتين و 30 دقيقة ربما تزيد كثيرا أو تنقص

متطلبات تتوفر فيك : تحمل على قراءة السطور + التأمل

ملاحظات :







- يجب ان تتمرس كثيرا ,,

















المتوقع منك في هذا الدرس :






معرفةمشاكل تكرار البيانات بشكل اعمق .
معرفة تحليل نموذج ER .



* المفتاح الاجنبي :

عرفنا ان المفتاح الاجنبي ... عبارة عن عمود موجود في جدول .. ممكن ان يتكرر في هذا الجدول ... وهو مفتاح رئيسي في جدول اخر .. ويستخدم في الربط بين الجداول كحل قوي في مشاكل تكرار البيانات .

(ماهي هذه المشاكل ؟) المشاكل هي :


مشاكل الاضافة
مشاكل الحذف
مشاكل التعديل

سوف اعرض مثال .... على هذه المشاكل ,,

انظر هذا الجدول (صورة 13)



http://www.w6w.net/upload2/22-11-2005/w6w_200511221244121f1e22ba.jpg






جدول خاص بالاطباء والمستشفيات التي يعملون فيها .


تكررت البيانات كما تعرفون .. والحل هو فصله الى جدولين , جدول الاطباء وجدول المستشفيات

سوف استعرض لكم مشاكل تكرار البيانات في هذا الجدول (الصورة السابقة 31)





مشاكل الاضافة : لو اردنا ان نضيف مستشفى جديد ؟؟ ماذا برأيك ان نعمل ؟؟

سوف نضيفه هكذا (الصورة 23)



http://www.w6w.net/upload2/22-11-2005/w6w_2005112212485408aaceed.jpg






لايوجد طبيب ؟؟ ... وقلنا ان المفتاح الاساسي لا يتكرر ولا يكون خالي ؟؟


ولكن رقم الطبيب مفتاح اساسي .. واصبح خالي ؟؟

هنا تكمل المشكلة ... سوف نضطر الى اضافة طبيب جديد مع أي اضافة لمستشفى جديد ... وهذه مشكلة ..















مشاكل الحذف :

في الجدول السابق (صورة 13) احذف لي الطبيب حسن .... مالذي يحدث ؟؟ (انظر الصورة 33)

http://www.w6w.net/upload2/22-11-2005/w6w_200511221254223061670a.jpg




سوف تختفي مع معلومات حسن ... معلومات المستشفى ج والذي يقع بالمدينة الوسطى!!......



(وماذا في ذلك ؟؟ ارى انه طبيعي ) المشكلة .. لو اردت الان معلومات المستشفى ج ... اين هي ؟؟؟


هل فهمت ؟؟


مشاكل التعديل :

وقع زلزال عنيف .. في المدينة الشرقية ... واسفر عن ذلك 3 حالات جروح طفيفة ... ولم يحدث وفاة ولله الحمد ... ولكن ... المستشفى ب في المدينة الشرقية ... تدمر عن بكرة ابيه ...

افتتح مؤخرا مستشفى ب الجديد ... والذي يقع في المدينة الشمالية الشرقية ....

نريد ان نعدل هذه المعلومة في الجدول .. نريد ان نجعل المستشفى ب بالمدينة الشمالية الشرقية .. مالذي يحدث ؟؟

سوف يتم تعديل جميـــــــــــــــــــــــــع السجلات (الصفوف) الموجودة بالجدول والتي تحتوي على القيمة "المدينة الشرقية" ... لاحظ ذلك (الصورة 43)



http://www.w6w.net/upload2/22-11-2005/w6w_20051122125541397522f6.jpg









اضطررنا ان نعدل على 3 صفوف ...(هه .. 3 صفوف فقط .. مالمشكلة)
تخيل معي لو انه يوجد 1000000 طبيب بالمدينة الشمالية الشرقية .... كم صف سوف نعدل ؟؟؟(اوبس ..)

والان .. هذه المشاكل ... وحلها فصل الجدول الى جدولين .. جدول الاطباء وجدول المستشفيات .

كما في الصورة 53 والصورة 63 ..
















( الصورة 53 )

http://www.w6w.net/upload2/22-11-2005/w6w_20051122132813c5be056b.jpg










(الصورة 63)







http://www.w6w.net/upload2/22-11-2005/w6w_20051122131212746bfc23.jpg








هل تستطيع ملاحظة المشاكل كيف اختفت ؟؟














هل شاهدت المفتاح الاجنبي ؟؟ اين هو ؟؟

















رقم المستشفى الموجود في جدول الاطباء .. هو مفتاح اجنبي ,, ونضع تحته .. خط متقطع لكي يرمز انه مفتاح اجنبي .


لماذا يوجد مفتاح اجنبي في جدول الاطباء .. ولا يوجد في جدول المستشفى ؟

لان العلاقة بين المستشفى والطبيب هي واحد لمتعدد ومتعدد لواحد .

في المستشفى الواحد مجموعة اطباء .... الطبيب الواحد يعمل تحت مستشفى واحد

لاحظ كلمة "مجموعة" .... المستشفى به "مجموعة" اطباء ... ضع المفتاح الاجنبي في جدول الاطباء وانت مغمض العينين .

لو ان العلاقة واحد لواحد ؟؟

هنا بامكانك ان تضع المفتاح في أي جدول .. اختر احدهما .. وضع المفتاح ... ولكن هناك حالات انا شخصيا افضل ان تضعها في جدول دون الاخر .. سوف ندرسها بتعمق ان شاء الله .
















لو ان العلاقة متعدد لمتعدد ؟؟


سوف نستعرض حل هذه العلاقة في أمثلة نموذج العلاقات والكيانات .





تابعونا بعد الفاصل ,,,

The Coder
22-11-2005, 11:15 PM
النموذج العلائقي الكياني (Entity Relationship Diagram )









* تصميم قواعد اليبانات :



افترض اننا نريد ان نبني نظام (برنامج ) , فاول ما نفعله هو تحليل هذا النظام , أي معرفة متطلباته ومعرفة ما هو النظام اصلا , وغيرها من الامور والتي تساعدنا على فهم النظام بشكل يجعلنا لتحويله الى برنامج منفذ على ارض الواقع , بعد فهم هذا النظام ... سوف نصمم النظام بشكل افتراضي , أي تصميم رسومي على الورق مثلا , وهي من اختصاص مصمم قواعد البيانات , والذي يفترض شكل قاعدة البيانات ويفترض شكل الشاشات اللازمة التي تظهر ويرسم ويخطط ويصمم كل شيء ولكن .. بشكل افتراضي أي رسومات وتخطيطات على احد البرامج الرسومية المساعدة او حتى على الورق كما اسلفنا .

وما على المبرمج الا ان يأخذ التخطيط ويبرمجه (ينفذه) .

وفي برمجة قاعدة البيانات ... سوف نتوقع من المصمم ان يصمم نموذج يدعى النموذج العلائقي الكياني .



* ماهو النموذج ؟

هو مجرد تمثيل البيانات ووصفها والحقائق بالرسوم .. (وصف الحقائق بالرسم )

أي ان النموذج هو عبارة وصف رسومي (تمثيلي) للحقائق التي لا يمكن ان ترى مباشرة

(ولماذا نوصف البيانات بالرسم ؟)

لانها تعتبر اللغة ما بين المصمم والمبرمج .





مثال :




المهندس المعماري يصمم بالرسم نموذج لمنزل ما .. المقاول ينفذ التصميم (ينفذه بالبناء)
المصمم لقاعدة البيانات يصمم النموذج .. المبرمج يبرمج وينفذ التصميم .
المصمم (المهندس) يرسم ويخطط .. والمبرمج (المقاول) ينفذ ويبني .




* اجزاء هذا النموذج :
النموذج العلائقي الكياني هذا .. هو عبارة عن مجموعة من :






الكيانات
صفات الكيانات
العلاقات بين هذه الكيانات


سوف نشرح بشيء من التفصيل .. عبر هذا المثال لطلاب ومدرسيهم :



انظر الشكل (صورة 73)



http://www.w6w.net/upload2/21-11-2005/w6w_2005112104413736a422cc.jpg



الكيان (Entity) :














سوف تشاهد في الصورة ... مستطيلات .. مستطيل للمعلم .. ومستطيل للطالب

هذه المستطيلات ترمز للكائنات أو الكيانات . والكيان في الاصل هو ما يهمنا في أي نظام .. فمثلا نظام الطلاب يهمنا الكيان "طالب" والكيان "مادة" والكيان "معلم" والكيان "قاعة" ..... الخ

وعلى حسب النظام ... تظهر هذه الكيانات ... ولا يخفى علينا ان ايجاد الكيانات تخصص بحد ذاته .

من الممكن ان يكون الكيان مايلي :






شخص : مثل الزبون , المبرمج , المدير......
مكان : موقع , مدينة , حي ....
شيء : قطعة غيار , سيارة , بيت ......
حدث : طلب , تسجيل , تجديد .......
مفهوم : رحلة , مشروع , تكلفة .....




قد تجدها صعبة الفهم في هذه المرحلة .. وقد تجدها مفهومة جدا , ولكن أشيرإلى أن الكيان يمثل عادة الجدول في منهجنا هذا .







الصفة :



تشاهد في الصورة أن كل كيان ينبعث منه أشكال بيضاوية .... وهي تمثل صفات الكيان

فالكيان المعلم له صفاته وهي الاسم والرقم ... والكيان الطالب له صفاته وهو الاسم والمعدل والرقم .









والصفة تمثل عادة بحقول أو أعمدة الجدول .





























العلاقة :



المعين .. يرمز لنوع العلاقة بين الكيانات .. وفي الصورة نلاحظ ان العلاقة بين المعلم والطالب وهي علاقة "تدريس"

نشير ان الطالب الواحد يتعلم من مجموعة معلمين

وان المعلم الواحد يعلم مجموعة طلبة أي نوع العلاقة متعدد لمتعدد ... ستشاهد في الصورة حرفي M و N












نمثل العلاقة واحد لواحد بالشكل التالي (الصورة 83) :










http://www.w6w.net/upload2/21-11-2005/w6w_200511210444307ec48955.jpg

العقل الواحد بالشخص الواحد .. والشخص الواحد يملك عقل واحد ... العلاقة هي الملكية .. لاحظ الرقم واحد عند العقل وعند الشخص




نمثل العلاقة واحد لمتعدد ومتعدد لواحد بالشكل التالي (الصورة 93) :


http://www.w6w.net/upload2/21-11-2005/w6w_20051121050327f888782c.jpg











لاحظ في الصورة 93 ... ان المدير الواحد يدير مجموعة موظفين .. وان الموظف الواحد تحت إدارة مدير واحد !!..



انظر أين علامة المجموعة ... انها بالقرب من الكائن "موظف " ورمزنا لها بالرمز M





نضع الرمز الخاص بالتعدد (M) بالقرب من الكائن موظف لاننا قلنا مجموعة موظفين (بالمنطق تفهمها )




امثلة لنماذج اخرى :


الكيان الضعيف (Weak Entity) :



الكيان كما قلنا هو شيء يهمنا في النظام , بعض هذه الكيانات لا تظهر الا بظهور كيانات اخرى وتسمى الكيانات الضعيفة .. وهي التي تعتمد على الكيانات الاخرى ..سأعطيك امثلة معنوية لهذا المفهوم :

لا يوجد العقل البشري الحي والذي يفكر طالما انه لا يوجد انسان اصلا (العقل هنا كيان ضعيف )

لا يوجد معدل طالما انه لا يوجد درجات اصلا (المعدل هنا كيان ضعيف)

لا يوجد خادم طالما انه لا يوجد سيد اصلا (الخادم هنا كيان ضعيف)

لا يوجد نظر طالما انه لا توجد العينين اصلا (النظر كيان ضعيف يعتمد وجوده على وجود العينين)




لا يوجد ابن طالما انه لا يوجد اب اصلا (الابن كيان ضعيف وجوده يعتمد على وجود كيان الاب)

طيب ...

مارأيك في هذه الجملة ..

لا توجد برامج طالما انه لا يوجد كمبيوتر ...

هنا من الممكن ان يكون لدينا برامج ... بالرغم من اننا لا نملك كمبيوتر ... وهنا البرامج ليست كيان ضعيف ...

انظر الى الجملة حينما تكون بالشكل التالي :

لا توجد برامج طالما انه لا يوجد كمبيوتر اصلا (اصلا أي على ارض الواقع )

فهنا اصبحت البرامج كيان ضعيف .. لانه لو لم يكن هناك شيء اسمه كمبيوتر .. ولم يخترعه الانسان .. فلا وجود لبرنامج الـ Real Player مثلا !! ... ارجو ان تتعمق في التأمل ,,





نمثل الكيان الضعيف على نموذج ER بهذا الشكل ....(انظر الصورة 103)



http://www.w6w.net/upload2/21-11-2005/w6w_200511210505528868a25f.jpg




فالابن يعتمد وجودة على وجود الاب اصلا ... اذن الابن كيان ضعيف .. وتمثيله بنفس المستطيل الخاص بالكيان ولكن باطار ذو خطين ..... لاحظ الخطين الذان يمتدان من الكيان الابن الى العلاقة .... يجب وضعها خطين عند الكيان الضعيف ...





الصفات البسيطة والمركبة (Simple And Composite Attributes ) :



ان الصفات الخاصة باي كيان .. تكون عادة بسيطة ... مثل صفة رقم الطالب للكيان الطالب او صفة تاريح الميلاد للكيان المعلم .... وكلها صفات بسيطة ...

الصفة المركبة .. هي صفة بامكاننا ان نقسمها .... فمثلا رقم الطالب لا يمكننا ان نقسمه .. ولكن اسم الطالب نقسمه للاسم الاول .. والاسم الثاني ... واللقب .. انظر (الصورة 113 )



http://www.w6w.net/upload2/21-11-2005/w6w_200511210510534c804670.jpg


الصفات المتعددة القيم ... والصفات الوحيدة القيم (Single-Value and Multiple-Value Attributes) :



الاغلبية من الصفات تكون وحيدة القيم , فمثلا تاريخ صنع السيارة قيمة واحدة فقط ..لا يوجد بجانبها قيمة اخرى ,, ولكن لو قلنا رقم الجوال الخاص بالموظف , فمن الممكن ان يملك 3 ارقام جوالات , نشير هنا ان رقم الجوال في هذه الحالة صفة ذو قيمة متعددة .

انظر شكل الصفات المتعددة القيم (صورة 123) :




http://www.w6w.net/upload2/22-11-2005/w6w_2005112213534947eca54e.jpg



كما تشاهد في الصورة , الطالب لديه ارقام تلفون متعددة .





الصفات المشتقة (Derived Attribute ) :




الصفات التي بامكاننا ان نجد قيمتها من الصفات المجاورة الاخرى .. مثل عمر الشخص نجده من طرح التاريخ الحالي من تاريخ الميلاد .



انظر شكل الصفات المشتقة (الصورة 133)








http://www.w6w.net/upload2/22-11-2005/w6w_20051122134848793e53d5.jpg





أي ان معدل الطالب بامكاننا ان نوجده من صفات اخرى مثل الدرجات وعدد الساعات المدروسة .... الخ







اشير الى نقطة في الصفات المشتقة انها لا تخزن عادة ... بل نوجدها في كل مرة نريدها , ولكن اذا كان ايجادها صعب ومعقد وتأخذ وقت طويل فيفضل ان نخزنها .. فمثلا معدل الطالب , اذا كنا نطلبه كثيرا ..فيجب ان نخزنه.


5- الانواع الرئيسية والانواع الفرعية (Super-type and Sub-type ) :










نقصد بها الكيانات الرئيسية والكيانات الفرعية , مثال :

الكتب , منها نوعين ..


كتب الكترونية وكتب ورقية .
صحيح ان النوعين كتب .. ولكن لكل منها صفات خاصة بها .
الكتب الالكترونية تقاس بالحجم الالكتروني .
الكتب الورقية تقاس بالوزن .
كلا النوعين كتب , وتتكلم عن تخصص معين .




انظر الشكل كما يلي : (الصورة 143 )




http://www.w6w.net/upload2/22-11-2005/w6w_20051122135244d66d0d00.jpg





لاحظ المثلث المقلوب , حيث انه يشير الى تفرع النوع الرئيسي للانواع الفرعية ,



ولا تغفل عن امكانية انقسام الكيانات الى اكثر من قسمين ,,,











6- تمثيل علاقة الكيان مع نفسه :



كما شاهدنا العلاقات بين كيان واخر , فمن الممكن ان نشاهد علاقة كيان مع نفسه , امثلة :







الانسان (ونقصد به أي انسان سواء ذكر او انثى ) يتزوج انسان اخر .
الموظف يدير موظف او مجموعة موظفين اخرين .
المواد تتطلب مواد اخرى سابقة .

انظر الى شكل العلاقة في الصورتين (لا تسألني لماذا لم اجعلهما في صورة واحدة , يوجد سبب ^_^): (الصورة 153)


http://www.w6w.net/upload2/22-11-2005/w6w_20051122135347b32d54ed.jpg




لاحظ ان الموظف الواحد يدير مجموعة من الموظفين ... علاقة واحد لمتعدد ومتعدد لواحد








(الصورة 163)


http://www.w6w.net/upload2/22-11-2005/w6w_20051122135556b98fe105.jpg






لو كنت جامعي .. فسوف تعرف انك لا تستطيع تسجيل بعض المواد حتى تأخذ مواد اخرى قبلها .. أي ان المادة الواحدة تتطلب مجموعة مواد اخرى سابقة , وان المادة السابقة الواحدة من الممكن ان تكون مطلوبة من مجموعة مواد اخرى , أي ان علاقة التطلب هذه متعدد لمتعدد .





فاصل اخر ^^

The Coder
22-11-2005, 11:23 PM
انتهى الدرس ولله الحمد ,,, وسوف تطرق في الدرس القادم ان شاء الله لبعض الامثلة للنموذج وحالات للدراسة ..

و لا اخفيك انني لا املك هذه الامثلة بشكل كافي .. ولكن لا تخف ,سوف ابحث عنها , سوف اجدها , سوف

اخترعها ... وستحصل على امثلة حقيقية فعلية تتخيل بواسطتها العالم الواقعي !!










التحديات



اتحداك 3 تحديات ... اعتقد انك لا تستطيع ان تعرف أي منها ....


التحدي الاول : اذكر لي مالفرق بين الصفات ذات القيم المتعددة والصفات المركبة ؟

التحدي الثاني : ارسم نموذج واحد انت تختاره (غير ما ذكرت ) وارجو ان تراعي فيه وجود مايلي :

- صفات مركبة وصفات مشتقة .

- اكثر من كيان و بينهم علاقات .

- علاقة كيان بنفسه .

- كيانات رئيسية وفرعية .

أريد في هذا السؤال أن يكون نموذج واحد لنظام (أي نظام مثل نظام الطلبة , نظام مستشفيات , نظام من رأسك ....)


التحدي الثالث : في الصورتين 53 و 63 ... قلنا انه اختفت مشاكل ... ما هي هذه المشاكل ؟ أقنعني .... هل اختفت فعلا ام لا ....



-----------------------




المهام





اليك هذه المهام ,,


المهمة الاولى : معرفة برنامج الفيزيو .. وكيفية الرسم عليه , اذا لم تعرف فراسلني .
المهمة الثانية : اذا كان لديك انتقاد .. سؤال عبيط ... نقطة لم تفهمها .... راسلني او اطرح مشاركتك ..
المهمة الاخيرة : اسرع و جهز برنامج الاوراكل و حاول ان تركبه في جهازك .

The Coder
25-11-2005, 07:17 AM
السلام عليكم ,,,,,

شباااااااااااااب ,,,

- ارسلو التحديات الثلاث على الخاص او على الايميل ,,,, وارجو ان ترسلها بعنوان "؟؟؟؟؟؟؟؟؟؟؟؟" وان تذكر اسمك او كنيتك + عمرك + حل اسالتك ,,,

- اي سوال او استفسار اطرحه هنا في الموضوع .

- بامكانك تراسلني لو عندك اي استفسار ....

- لو تبيني على الماسنجر ... ساكون متواجد يوميا ان شاء الله بعد صلاة الصبح الى الحادية عشر ان شاء الله ...

طارق ذياب محمد
30-11-2005, 09:22 PM
السلام عليكم ورحمة الله وبركاتة
اما بعد



ارجو منك التكرم بالمزيد من هذة اللغه (sql)وماهى الفائدة وكيف تعمل بها فى حياتك العملية

طارق ذياب محمد
30-11-2005, 09:29 PM
السلام عليكم ورحمة الله وبركاتة
اما بعد



ارجو منك التكرم بالمزيد من هذة اللغه (sql)وماهى الفائدة وكيف تعمل بها فى حياتك العملية

The Coder
01-12-2005, 06:36 AM
السلام عليكم ورحمة الله وبركاتة
اما بعد



ارجو منك التكرم بالمزيد من هذة اللغه (sql)وماهى الفائدة وكيف تعمل بها فى حياتك العملية

وعليكم السلام ورحمة الله وبركاته
يقول الشاعر "كل شي بوقته حلوووو " ...
صح ^^
سوف اتكلم كثيرا في الاس كيو ال حتى اجعلك تملني .. وتمل الاس كيو ال ... وتمل الاوراكل ^^
هذا وعد ^^

The Coder
03-12-2005, 12:49 PM
السلام عليكم ,,
عدنا ثانية .. ولكن بدون درس ... بطلت اعطي دروس .....









امزح ,
سوف اتأخر في طرح الدرس الرابع ليومين او ثلاثة لاسباب كثيرة ...
المهم اشير الى نقاط مهمة ,,,

1- لم يأتني الا شخصين حلو التحديات ... وكما توقعت انها صعبة جدا .. لدرجة انكم لم تعرفو , الذكاء مطلوب لحلها :mad22: :mad22: :mad22: :mad22: ,,,,
2- دروسي مملة جدا .. لذا .. باغير الطريقة للافضل ان شاء الله ,,
3- الصور كلها او معظمها اختفت ... سوف ارفعها غدا ان شاء الله ,
4- ... انا لم استفد من اعطائكم الدروس .... ولم اتعلم زيادة على علمي .. ففكر ليش باقي اعطيكم دروس ؟؟
لاني اريد الاجر هذا اولا .. ولاني اريد الاجر هذا السبب الثاني .. والسبب الثالث .. انني اريد الاجر ...
5- واخيرا ... عارف انه ... لا يوجد شخص .. يقرأ الان ... هلوووو اني بودي هير ؟؟ نو ون ؟؟؟


سو بي ات ,,,

احلامو ادوماتو
03-12-2005, 05:36 PM
انا حقدت خلاص >_<

كيف لشخص واحد يكتب مواضيع مبدعة مثل هذي ما شاء الله لا اله الا الله

ينطيك العافيه استاذي وداوم على هذا

p.s: باحفظ الدروس بجهازي ، شكلك حاط واجبات XD

باحاول احلهن و اعلمك ^_^

The Coder
04-12-2005, 07:51 AM
انا حقدت خلاص >_<

كيف لشخص واحد يكتب مواضيع مبدعة مثل هذي ما شاء الله لا اله الا الله

ينطيك العافيه استاذي وداوم على هذا

p.s: باحفظ الدروس بجهازي ، شكلك حاط واجبات XD

باحاول احلهن و اعلمك ^_^

اهلا .,,
كنت بامسح مشاركتك ... ولكن ,,,, جاتني فكرة ....
الا وهي ...
اي استفسار اي سوال اي نقد ... اي مناقشة ,, تريدون ان تطرحوها ...
على رابط استفسارات هذه الدورة ....
http://www.montada.com/showthread.php?p=4304677#post4304677

وانت يا سيد ... حل الاسئلة .. والتحديات .. ولا تتأخر

The Coder
07-12-2005, 11:12 AM
بسم الله الرحمن الرحيم






الدرس الرابع :


اسم الدرس :نموذج الكيانات والعلاقات ER



نوع الدرس : نظري + رسومي + تحليلي


صعوبة الدرس : **** من *****

اهميــة الدرس : ****** من ***** (Over)

الوقت المتوقع منك لفهم الدرس : 4 ساعات ربما تزيد كثيرا أو تنقص

متطلبات تتوفر فيك : التركيز و الصبر والتحليل الصوري ,,






المتوقع منك في هذا الدرس :


- القدرة على التحليل المنطقي .




- معرفة اين يوضع المفتاح الاجنبي عادة .




- القدرة على تحويل أي نظام الى نموذج العلائقي الكياني( ER )







هيا لنؤركل ^^





قبل البدأ بالدرس .. احب ان اشير لنقطة مهمة جدا جدا جدا ,,


نحن لا نصمم قواعد البيانات ولا نصمم الجداول على كيفنا .... لا يا حبيبي ...

نحن نمشي على وصف .. على متطلبات من الزبون .. نمشي على هذه المتطلبات ولا نبرمج ونصمم متطلبات لا يريدها الزبون .. ولا أن نترك متطلبات يريدها الزبون !!

أي انك انت مبرمج ... تنتظر خرائط رسومية ونماذج من المصمم , وتمشي عليها وتبرمج عليها ولا تزيد ولا تنقص شيء !! هل فهمت ...




قاااعدة مهمة (قاعدة رقم 1): على حسب المتطلبات .. نبرمج .. اوكيه ..





حتى المصمم ... يصمم على حسب ما جائه من محلل النظم ..

حتى المحلل ... يحلل النظام على حسب ما جائه من معلومات من الزبون نفسه ...



نحن نعمل كفريق عمل ... وانت مكانك في هذا الكورس هو المبرمج .... والذي يتلقى النماذج والرسوميات من المصمم ...



نتطرق لموضوع المفتاح الاجنبي ...

The Coder
07-12-2005, 11:20 AM
تابع الدرس الرابع




* ماهي حقيقة المفتاح الاجنبي (Foreign Key) :






سابقا درسنا مشكلة التكرار ... وحليناها بطريقة ربط الجداول ... ووضع المفتاح الأجنبي في احد هذه الجداول ..


المفتاح الأجنبي مرة ثانية هو عمود يتكرر ولا يمكن ان يكون خاليا ... وهو مفتاح رئيسي في جدول اخر ..




المصيبة انه لا علاقة له بالجدول .. والمصيبة الأعظم انه يشبه شكليا المفتاح رئيسي في الجدول الاخراليك مثال : لجدولين .. وتركيبهما صحيح (لاحظ .. صحيح ...)

جدول الموظفين (صورة 134)







http://img8.picsplace.to/img8/2/134_002.jpg





وجدول الاقسام (صورة 144)



http://img4.picsplace.to/img4/14/144.jpg




في جدول الموظفين يوجد مفتاح اجنبي .. وهو رقم القسم ( Dept_no ) لونته باللون الاحمر ...

المفتاح الرئيسي هو عمود لايتكرر ولا يمكن ان يكون خاليا ...وهو رقم الموظف واعطيناه الاختصار (Eno)

على فكرة .... لماذا يلزمنا المفتاح الرئيسي ؟؟



تخيل معي ان صاحبك يدعى سعد Saad .... وهو موظف

سعد .. كذب عليك وقال " راتبي 4000 دولار وانا في القسم A " ... وانت تريد ان تتجسس وتطلع على راتب سعد وعلى معلوماته ... تخيل ان عدد الموظفين ضخم جدا ... تخيل عددهم 1000000 موظف (يعني 1000000 صف في الجدول الخاص بالموظفين (في صورة 134) ) ... 250000 موظف منهم ... يدعون بـسعد (Saad) بالله عليك قول لي ... كيف نعرف اين معلومات سعد صاحبك ؟؟

عشان نميز بين الصفوف .. نضع المفتاح الرئيسي .... انظر الصورة 134 .... فالموظف Saad صاحب الرقم 123333 ليس نفسه Saad صاحب الرقم 123334 ......



لاحظ المفتاح الاجنبي (صورة 134 .. عمود باللون الاحمر)

الان اريدك ان ترى جدول الاقسام (الصورة 144) ,, وان ترى المفتاح الرئيسي (رقم القسم Dept_no) .

اكيـــــــد انك استنتجت عدة نقاط ... اليك هذه النقاط ....

1- المفتاح الاجنبي في جدول الموظفين .. يشبه المفتاح الرئيسي في جدول الاقسام

2- لاحظ ان المفتاح الاجنبي في جدول الموظفين .. رقم ... مثله مثل المفتاح الرئيسي .. وليس كلمة !!

3- هل تلاحظ ان المفتاح الاجنبي لا يمكن ان يكون خالي ؟؟ وايضا المفتاح الرئيسي لا يكون خاليا ؟

4-هل تلاحظ ان المفتاح الاجنبي ... تكون قيمه في هذا النطاق (1 , 2 , 3) ؟ هل شاهدت اعداد غير هذه ؟؟

وهي الاعداد نفسها الموجودة في المفتاح الاساسي .... أي ان نطاقه هو نفس نطاق المفتاح الرئيسي في الجدول الاخر ....

5- هل تلاحظ ان المفتاح الاجنبي يتكرر .. بينما المفتاح الرئيسي لا يتكرر

6- هل تلاحظ ان المفتاح الاجنبي .. لا يمت صلة بالجدول .. يعني بالله عليك .. هل رقم القسم صفة للموظف ؟؟ لاحظ ان رقم القسم وهو مفتاح اجنبي ... ليس صفة تابعة لجدول الموظفين ...



هذه ملاحظات مهمة جدا .... وهي قوانين المفتاح الاجنبي

يتكرر .. لا يكون خالي .. لا يكون مفتاح رئيسي .. يشبه للمفتاح الرئيسي في الجدول الاخر كثيرا .. لا تخرج نطاق قيمه عن نطاق قيم المفتاح الرئيسي في الجدول الاخر ...



سوف ندرس في الدرس القادم ان شاء الله .... بعض مفاهيم قواعد البيانات المتماسكة .. والتي تجعلك تتجنب خلخلة موازين قوانين المفتاح الاجنبي .. وبعض القوانين الاخرى .... وسوف ندرس مالذي سيحصل لو خلخلنا هذه القوانين ان شاء الله ,,


لماذا نضع المفتاح الاجنبي في جدول دون جدول اخر ؟

يعتمد على نوع العلاقة .. هل هي واحد لمتعدد .. ام متعدد لمتعدد .. ام واحد لواحد ....

لنجرب ثلاث امثلة .. مارايك ؟؟

لنفكر معا .. ونستنتج هذه القواعد ...

عن اذنكم بروح اشرب موية ...

The Coder
07-12-2005, 11:34 AM
تابع الدرس الرابع

المثال الاول : علاقة واحد لواحد (One to One)








مممممم .. مثال مثال مثال على هذه العلاقة .... أأأأه ... افتكرت ..الموظف الواحد .. يدير قسم واحد فقط ..
والقسم الواحد .. يدار (بضم الياء وفتح الدال فعل مبني للمجهول) من قبل موظف واحد ..


وعلى فكرة ... الي ما بيقولها بهالصيغة ... يجيه تلطيش .. اوكيه !!

بعضهم ارسل لي الواجب على هالصيغة ... "الموظف الواحد يدير قسم واحد .... " وسكت ..

اريدك تذكرها من الجهتين ..." الطبيب الواحد لديه مكتب واحد .. والمكتب الواحد يملكه طبيب واحد"







انتبهوووووو .... لا اريد الاخطاء هذه .. ابدا ,,,

















المهم ... العلاقة واحد لواحد نادرا ما تكون موجودة ... وسوف تعرف فيما بعد ... لماذا هذه العلاقة ؟ ولماذا نستخدمها اصلا ,,








.. هيـــــــــــــــه ...وش فيك ؟؟ شايفك متضايق ... قلتفيما بعد بتعرف .. ما تقدر تصبر !!!!








الان انظر جدول الموظفين (الصورة 154)



http://img7.picsplace.to/img7/4/154.jpg







ثم انظر جدول الاقسام ... (الصورة 164)



http://img8.picsplace.to/img8/2/164.jpg







في جدول الاقسام يوجد متهم (عمود) يدعى "it's Manager" ولونه ازرق .... وهو المفتاح الاجنبي في علاقة الواحد لواحد ...


لماذا وضعناها في جدول الاقسام .. ولم نضعها في جدول الموظفين ؟

يالله نجرب ... ونضعها في جدول الموظفين ..

الان انظر الى جدول الموظفين التالي (الصورة 174)







http://img4.picsplace.to/img4/14/174.jpg






ثم انظر الى جدول الاقسام التالي (الصورة 144 السابقة ^^)







http://img4.picsplace.to/img4/14/144.jpg





مالذي حدث ؟؟

قمنا ووضعنا المفتاح الاجنبي في جدول الموظفين ... هذا كل شيء ^^

هل اثر ذلك في العلاقة ؟؟ ...

مممممم ... مارأيك انت ؟؟؟ انا من ناحيتي ماشفت أي تغيير معنوي .... صحيح قلبنا الامور ... ولكن ... لم يؤثر في تماسك الجدولين ... صح ^^ ؟
















طيب .. مارأيك لو مزجنا الجدولين ^^ ... همممم .. نمزجهما .. ام لا ؟؟


لا ؟؟ لماذا لا نمزجهما ؟؟ عشان التكرار ؟؟ طيب ... نجرب ونمزجهما .. (الصورة 184)

http://img4.picsplace.to/img4/14/184.jpg



وااااه ... حذفنا عمودين ... عمودرقم القسم (dept_no) الذي كان مفتاح اساسي في جدول الاقسام وعمود His_dept والذي كان مفتاح اجنبي في جدول الموظفين ...كلا العمودين لم نحتاجهما في المزج الجديد (صورة 184) ....









مارأيك .. كأن التكرار خف ولو قليلا .... حذفنا عمودين باكملهما (المفتاح الاساسي والاجنبي وهما رقم القسم) ... وصار الجدول مختصر بشكل اكثر,


لا تقول اختصرنا قليلا... تخيل بالله عليك ... انه لدينا 1000000000 قسم ... و 9999999999 موظف ..... كم من البايتات نختصره ؟؟ كثييييييير ^^ ....

نستنتج ان علاقة واحد لواحد ... مالها داعي ... تزيد علينا شقى وتعب ... وزيادة عمودين بأكملهما ...







لييييييييييييش نستخدمها من الاول ؟؟


يقول لك يا سيدي ... لاسباب امنية ^^ ... (اسباب امنية ؟؟ ) ايه اسباب امنية !!!







اذا بغينا نحمي البيانات (لاحظ البيانات .. وليست قاعدة البيانات !!!) نفصل الجدول الى جدولين ونربط بينهما بعلاقة واحد لواحد ^^ ... وهذا على حسب المتطلبات .... (افففففف.. مافهمت شي !)


طيب ... انا لا اريد ان اجعل احد يعرف معلومات الاقسام وله الحق في ان يرى معلومات الموظف ... مالذي اعمله ؟؟؟

انظر الى الجدول في الصورة 174 ... وهو جدول الموظفين ... تخيل ما تقدر تشوف الا هذا الجدول تخيل اني انا مديرك وقلت لك "هيــــه انت .. ايها الموظف .. اين يقع القسم رقم واحد ؟؟"

فترد انت "ما بعرفياسيدي " ... فاقول لك: "هه .. مطرود يا حبيبي ... " (تكنيك رائع للتخلص من الغير مرغوب فيهم بالعمل ^^)







.. تعرف ليش ما بتعرف يا موظف ؟ لاني حجبت عنك جدول الاقسام الي هو الصورة رقم 144 !!!عرفت ليش اسباب امنية ؟؟ ^^

يالله ... باخذ لفتين .. واجي ...
طفشششششششت

The Coder
07-12-2005, 11:51 AM
الدرس الرابع تابع


المثال الثاني : العلاقة واحد لمتعدد ومتعدد لواحد :









مممممممم ... مثال مثال مثال ... أأأه افتكرت ^^


اش رايك بهالمثال ؟

الموظف الواحد يعمل تحت قسم واحد ,,, والقسم الواحد يعمل تحته اكثر من موظف

ياسلام ^^ ... علاقة اخرى بين الموظف والاقسام وهي "عمل" .... هل تذكر العلاقة "ادارة" ؟؟

قلنا ان نضع المفتاح الاجنبي .. من جهة الكيان المتعدد .. والكيان المتعدد هو "موظف " وليس "قسم" ...

انظر جدول الموظفين (صورة 134 السابقة)
http://img8.picsplace.to/img8/2/134_002.jpg
وجدول الاقسام (صورة 144السابقة )
http://img4.picsplace.to/img4/14/144.jpg
ممممم ... مارأيك نجرب ونجعل مكان المفتاح الاجنبي ... في جدول الاقسام ... ^^ .... مثل ما فعلنا في علاقة الواحد للواحد .... ؟؟ انا بنفسي مابعرف .. وش بيصير ...

نجرب ؟؟ هاه ؟؟ اعتقد ان بعضكم ذكي جدا ... واكتشفها قبل ان اعرض المثال .... اما البعض الاخر .. لا يريد التفكير ..

اذا كنت من البعض الاخر الذي لا يريد التفكير ... فالله يعينني عليك .. خذ خذ المثال :



انظر جدول الموظفين (صورة 194)


http://img6.picsplace.to/img6/8/194.jpg
وانظر جدول الأقسام ^^ (صورة 204)

http://img8.picsplace.to/img8/2/204.jpg
اوبس .... أين الباقين ؟؟ كيف نضيفهم .. لو أضفناهم .. حتصير مشاكل تكرار للمفتاح الرئيسي .. وتكرار للبيانات أصلا .. وحتصير مشاكل ليــــــن الليل ..

مممممم .. هل لاحظت المشكلة ... لا لا لا ... انسى الموضوع ^^

اجعل دائما المفتاح الأجنبي .. من جهة الكيان المتعدد ^^ ... وصلت ؟






المثال الثالث : العلاقة متعدد لمتعدد :








مثال على العلاقة هذه .... خليني استمد من واجباتكم ^^


يقول احدهم في حل الواجب الاول ....

الموظف الواحد يتعامل اكثر من زبون .. والزبون الواحد يتعامل مع أكثر من موظف

واعدكم ان قال احدكم "الموظف يتعامل مع اكثر من زبون " وسكت .. اعطيه هدية مني (فيروس VCL)

يالله نرسم جدولهما .. جدول الموظفين (Employee Table) (صورة 194 السابقة ...)

وجدول الزبون (Customer Table) (صورة 214) :


http://img4.picsplace.to/img4/14/214_000.jpg



عذرا على هذا الجدول الصغير .. تخيلوووو .. أن لدينا 200 عمود ... و100000 صف .... اوكيه ,,,

مارأيك .. اين نضع مفتاح الاجنبي .. ؟؟

مممممم .... مارأيك لنجرب .. انا منذ زمن اريد ان اجرب .. مالذي يحدث اذا وضعت المفتاح في جدول الزبون ؟؟ يالله ؟؟؟

مثلا .. الزبون أبراهام (اعتقد ان أبراهام هو إبراهيم بس بالغربي ^^) صاحب الرقم 106 ... تعامل مع الموظف احمد و والموظف خالد

والزبون جاسم ... تعامل مع الموظف اكرم فقط ... ثم تعامل مع اكرم مرة ثانية ...

ومثلا ... الزبائن كلهم الباقين.. لم يتعاملوا مع أي موظف ...

.... كيف نكتبها ذي ؟؟ نجرب ؟؟ يالله نجرب ^^ (صورة 224)
http://img8.picsplace.to/img8/2/224.jpg






ياسلام ... المفتاح الاجنبي بامكانه ان يتكرر ... تكرر مرتين رقم الموظف اكرم .. ^^

ومن خصائص المفتاح الاجنبي ... ايضا هو ان لا يكون خاليا ^^ ....

لحظة ... هناك قيم خالية ..... في المفتاح الاجنبي ..

وهناك تكرار في المفتاح الاساسي ... الخاص بابراهام والجاسم ..!!

وهناك تكرار للبيانات الخاصة بابراهام وجاسم .... !!

لا لا لا ... وضع المفتاح الاجنبي .. في جدول الزبون ... غباء .. انسى الموضوع ^^"



طيب ... لو وضعته في جدول الموظفين ...

مين ذكي ؟؟ هل توجد مشكلة ؟؟

تالله انها نفس المشكلة ... جربوها وشوفو .... يمكن اكون غلطان .. هيا جربها الان ...

دقيقة و اثنان واربعون ثانية ... لا تكلفك شيء .. جربها الان ...



جربتها ؟؟

ممتاز ^^ عظيم ^^ (والله اني عارف انه لا احد جربها ,,,)

المهم ...

مالعمل ... ؟؟؟

العمل يا سيد ... هو انشاء جدول جديد !! ....

نسميه ... جدول (موظفين- زبائن ) (Emp_Cust Table)

نستلف من الجدول الاول مفتاح اجنبي .. ونستلف من الجدول الثاني .. مفتاح اجنبي ..

وووو ... بس ^^ §

يسمى هذا النوع من الجداول بـ Junction Table )) الجدول التقاطعي







يالله ... مرة ثانية ... نشوف الي يصير ....


الزبون أبراهام صاحب الرقم 106 ... تعامل مع الموظف احمد و والموظف خالد

والزبون جاسم ... تعامل مع الموظف اكرم فقط ... ثم تعامل مع اكرم مرة ثانية ...

انظر جدول زبائن_موظفين (صورة 234)


http://img6.picsplace.to/img6/8/234_000.jpg
سبحان الله .. كأن هذا الجدول يرصد تاريخ لقاء الزبون صاحب الرقم 105 (جاسم) مع الموظف 123336 الي هو .... انتظر اشوف جدول الموظفين .......

ايه اكرم ^^ ..



شايفك الان متضايق من الارقام هذه الكبيرة (123336 ... 123335 ... الخخخ) .. ولكن في الحياة العملية ... حتشوف ارقام اكبر واعقد

يمكن تلاقيها ارقام واحرف ..... تدرب من الان ^^



هل شاهدت الان الجدول وكيف يرصد تاريخ علاقة الموظفين بالزبائن ؟؟ (علاقة = التعامل)

او بمعنى اخر .. يرصد تعامل الموظفين مع الزبائن ؟؟

لو مثلا الزبون رقم 102 تعامل مع الموظف صاحب الرقم 123333 .... نضيف صف في الجدول السابق ...

انظر الصورة (244)

http://img8.picsplace.to/img8/2/244.jpg
لو طلبت منك ان تضيف تاريخ للعلاقة بين الموظفين والزبائن ... ماذا تعمل ؟

نضيف حقل .. وهو تاريخ تعامل الموظف مع الزبون ..

لو طلبت منك أين المفتاح الأجنبي .... ؟؟ صح .... ممتاز .... انه رقم الموظف ورقم الزبون كلاهما مفتاحان أجنبيان ^^ ...

لو طلبت منك (ياخي فكنا ياااااخي كل شوي تطلب.. اففف مدير مسوي زحمة ) << طيب .. آخر طلب ^^"

لو طلبت منك .. أن تخبرني .. أين المفتاح الأساسي ؟؟

مفيش ؟؟

والعمل ؟

نضيف مفتاح أساسي .. ونسميه .. مممممم ... أي شي ... وليكن "handle_no" رقم التعامل ...

انظر الجدول (صورة 254)

http://img6.picsplace.to/img6/8/254_000.jpg

الان انظر لهذا الجدول (الصورة 264)

http://img6.picsplace.to/img6/8/264.jpg


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

لو طلب منك المدير حمزة .. ان لا تضع حقل جديد .. ولا يريد ان تضيف حقل وتجعله مفتاح أساسي للجدول ... مالعمل ؟ (تخيل ان المدير حمزة .. معاه حساسية من المفتاح الاساسي ^^)

مستحيل صح ؟ لازم نضيف عمود جديد صح ؟؟؟













خطأ !!!!








بامكاننا ان نخترع من هذان الحقلان مفتاح اساسي ^^ ....


يعني لو مزجنا الحقلان هذان ... ينتج عندنا المفتاح الاساسي ...

خذها قاعدة .. لو لم تجد عمود يستحق ان يكون مفتاح أساسي .... بإمكانك ان تجعل أكثر من عمود مفتاح اساسي ..

يمكن يكون عمودين زي مثالنا ... يمكن ثلاث .... وهلم جر ,,,













ماذا بكم ... ماذا دهاكم ...



كأني أرى الطير فوق رؤوسكم .... أنا عارف معظمكم ما فهم نقطة مزج أكثر من عمود ليصبح مفتاح أساسي ...

إليك شرح مفصل .. أحذرك قبل أن تقرأ ... قد تمل من هذا الشرح .. ولكن .. طريقك الوعر والوحيد في الفهم أكثر وأكثر ...


سنعود بعد قليل :09:

The Coder
07-12-2005, 12:20 PM
شايف الجدول السابق ؟(الصورة 264 السابقة )

http://img6.picsplace.to/img6/8/264.jpg

أول صف .. ضم القيمتين .... وش يصير الناتج ؟


يعني 123336 نضمها مع 105 يصبح لدينا .... 123336105 واو .... هذا المفتاح الاساسي لأول صف !! والمفتاح الأساسي لا يمكن ان يكون خالي او أن يكون مكرر .... صح ؟؟


طيب ... ضم الصف الثاني ..


يصير الناتج ... 123331106 همممممم .... مختلف تماما عن السابق .. ^^ .. لا يوجد قيمة خالية .. ولا يوجد قيمة مكررة ^^ ,,,


لأنه اختلف رقم الزبون ومعاملته مع الموظف عن رقم الزبون الأخر عن الموظف الأخر ...


طيب ضم الصف الثالث ... أوه .. رقم الزبون نفس رقم الزبون في الصف السابق !!


بعد أن ضمينا ... 123335106 ..... رقم مخالف عن 123331106 في الصف الثاني ...


بالرغم من أن رقم الزبون تكرر مرتين .. ولكن اختلف رقم الموظف !!


الزبون 106 تعامل مع موظفين مختلفين ^^


ونتج قيمتين مختلفتين حل رائع صح ^^ !!


الصف الرابع .. تكرر رقم الموظف ثانية !! ... هل سيؤثر ؟؟ هل تعتقد انه سوف يكرر المفتاح الاساسي ؟


الناتج من ضم الصف الرابع هو 123335102 يشبه (من ناحية رقم الموظف ) ناتج الصف الثالث 123335106


ولكن يشبهه قليلا ^^ ..


تعامل الموظف 123335 مع الزبون 106 ومع الزبون 102 ومافيه أي اشكال ^^


هذا حل قوي جدا .... ولكن ... لا نستخدمه في كل الاحيان .. ليييييييش ؟ هناك حالة لو صارت ... لا تستخدم هذا الحل ... ماهي الحالة الجديدة ؟؟





حالة جديدة على حسب المتطلبات :


نتماشى مع القاعدة رقم واحد .. أي جاءتك متطلبات جديدة من مديرك حمزة ...ويخبرك بأنه يريد عدد المرات التي تقابل او تعامل فيها الموظفون مع الزبائن ولا اريد ان تضيف مفتاح اساسي .. ماذا تفعل ... ؟؟


هل تذكر الصورة 244 ؟؟

http://img8.picsplace.to/img8/2/244.jpg







قال لك المدير حمزة ... ان لا تضيف مفتاح أساسي .. وأنت اقترحت أن يكون العمودين معا... مفتاح أساسي صح ؟

انظر الصورة 244 ... لو تعامل الزبون 105 مع الموظف 123336 (الصف الاول ) ثم تعامل الزبون نفسه مع الموظف نفسه !! ( الصف الثاني).. مالذي يحدث !!


ضم الصف الأول .. وضم الصف الثاني وتطلع نتيجة متساوية وهي ... 123336105


مصيبة .... تكرر المفتاح الأساسي ... والعمل ؟؟ مالعمل ؟؟ المدير سوف يطردك لو قلت له انك تريد ان تضيف عمود جديد كمفتاح أساسي ... ولاحظ انه لا يريد المفتاح الأساسي ... (أي بمعنى آخر بإمكانك إضافة حقول ولكن لا يجب ان تكون مفتاح أساسي)


لهذه الحالة يجب ان نضيف حقل ويدعى ..عدد المرات"no_of_time" ... وهو اقتراح ليس الا ......


انظر الجدول (الصورة رقم 274)



http://img8.picsplace.to/img8/2/274.jpg





كم مرة تقابل الموظف 123336 مع الزبون 105 ؟؟ مرتين ^^ ...


لو تعامل الموظف 123336 مع الزبون 105 مرة ثالثة ؟؟ يصبح عدد المرات ثلاثة .... وهلم جر ,,,,








لخبطت راسك صح ^^ ... أنا أعلمك الآن شيء .. لم أتعلمه من كتاب .. بل من خبير قواعد بيانات ..


(سوف أتطرق إليه في الدروس القادمة إن شاء الله ) وبعض من خبرتي المتواضعة جدا ,,








انتهينا من الثلاث الامثلة للعلاقات .. وانتهينا من دراسة المفتاح الاجنبي .. وبقي سوال .. لماذا المفتاح الاجنبي لا يكون خاليا ؟؟ لو جعلناه خاليا .. مالذي يحصل ؟؟ اتحداك ان تعرف ,, (التحدي الاول )





* تحويل الوصف الى نماذج :

في هذا الدرس سوف تتعلم تحويل أي وصف الى نموذج ER
وجدت بعض الأمثلة و إليك هذه الأمثلة وأرجو أن تتبع كل كلمة فيها (تذكر القاعدة رقم 1)... وسوف نحولها الى نموذج ER , وبكل دقة , سوف افصل لك الحل .. واعلمك مادة لن تجد لها شرح كشرحي !! لاني وجدت حلول بدون شرح كيفية التحويل , وستعرف طريقة التحويل , بسيطة للغاااااية , ولكن المشكلة لا تتعلق بتعليمك اياها او لا ... المشكلة انها بالمنطق ,, ولا اعتقد انها صعبة لدى المعظم من الناس .







مثــال 1 :

* تحويل من وصف الى نموذج ER :



شركة تهتم بتسجيل معلومات عن الاقسام والمشاريع التي تنفذها الشركة وكذلك عن الموظفين العاملين فيها والتابعين لهؤلاء الموظفين ,

1- تقسم الشركة الى عدة اقسام ولكل قسم اسم واحد ورقم ولا يجوز ان يكون هناك اكثر من قسم بنفس الاسم او الرقم , لكل قسم موظف يدير هذا القسم ويجب معرفة التاريخ الذي بدأ فيه هذا الموظف بادارة القسم , ولكل قسم موقع واحد فقط .

2- القسم يمكن ان يدير عدة مشاريع , ولكل مشروع رقم واسم , ومكان تنفيذ .

3- يمكن ان يعمل في القسم موظف او اكثر ولكن الموظف يجب ان يتبع لقسم واحد فقط ,ونحتفظ بالمعلومات التالية عن الموظف الرقم ( لكل موظف رقم يميزه عن بقية الموظفين ) , الاسم (الاسم الاول , الثاني ,العائلة ) ,الجنس , الراتب , العنوان

4- الموظف يمكن ان يعمل في عدة مشاريع (ليس بالضرورة ان يدار المشروع من نفس القسم الذي يتبع اليه الموظف ) ونحتفظ بعدد الساعات التي عملها الموظف في كل مشروع .

5- تحتفظ الشركة بمعلومات عن التابعين لكل موظف (التابعين هم الأشخاص الذين يتبعون الموظف مثل الزوجة , الأبناء .... ) هذه المعلومات هي الاسم , تاريخ الميلاد , الجنس , صلة القرابة .

6- تهتم الشركة لمعرفة عدد الموظفين في القسم الواحد

7-المدير لكل قسم يدير جميع الموظفين تحت قسمه .

8- الموظفين نوعين , موظف ثابت ويأخذ راتب ثابت , وموظف يعمل بنظام الساعات ويأخذ نسبة عدد الساعات التي عمل بها .
















الحـــــــــــــل :











الاحمر= علاقة

البني = كيان

الازرق = صفات

بالنظر في التحليل استطعنا ان نستخرج العلاقات + الكيانات + الصفات

اشير الى انه عادة (لاحظ .. عادة وليست دائما ) ..... الاسماء تكون صفات او كيانات ,, والافعال تكون علاقات ^^

استخدم هذه بذكاء ,,

الان نأتي للشرح المفصل ,,,







1- تقسم الشركة الى عدة اقسام ولكل قسم اسم واحد ورقم ولا يجوز ان يكون هناك اكثر من قسم بنفس الاسم او الرقم , لكل قسم موظف يدير هذا القسم ويجب معرفة التاريخ الذي بدأ فيه هذا الموظف بادارة القسم , ولكل قسم موقع واحد فقط .








استخرجنا الاقسام ككيان , واستخرجنا الموظف ككيان , لماذا لا تكون الشركة مثلا كيان ؟


لاحظ انه قال "لكل قسم اسم ورقم " وان الكيانات لديها صفات .... اسم قسم , رقم قسم .. صفات للقسم .. اذن القسم كيان , وصفاته اسم القسم ورقم القسم وموقعه .

لم يقل "الشركة لها أسماء الأقسام , أسماء الموظفين ..." ولكن قال "الشركة تنقسم الى عدة اقسام ...."

لاحظ انه لم يركز في صفات للشركة ... لذا استبعدنا كون الشركة كيان ,,,

استخرجنا موظف ككيان ... هنا لا توجد صفات للموظف ... لماذا استخرجناه ككيان ؟ لانه يوجد علاقة بين الموظف والقسم , وهي الفعل "يدير" , أي ان الموظف الواحد يدير قسم واحد , وان القسم الواحد يدار من موظف واحد , انتبه الى نقطة مهمة ... ذكر " التاريخ الذي بدأ فيه هذا الموظف بادارة القسم " , هذه صفة غريبة بعض الشيء , لانها لا توجد في القسم لوحده , ولا توجد في الموظف لوحدة , أي اذا اجتمع الموظف والقسم وصار بينهما علاقة الادارة , فتنتج هذه الصفة الغريبة !! فلنسميها صفة مشتركة لانها لا يمكن ان تكون موجودة الا بوجود علاقة الكيانين ... كيان القسم وكيان الموظف , ونضعها على العلاقة نفسها اليك النموذج الذي استنتجناه ولا تنسى ان تلاحظ الصفة الغريـبة (الصفة المشتركة ) ( الصورة 14)







http://img7.picsplace.to/img7/4/14_004.jpg








سوف اركز قليلا على اللغة الانجليزية في النماذج لانها لغة standard ,,,

Manage = يدير




Start_date = التاريخ الذي بدأ فيه الموظف بادارة القسم








Dept_no = رقم القسم وهو مفتاح اساسي ( Primary Key )Dept_name = اسم القسم







Loc = اختصار لـ location واعني بها الموقع











ملاحظة مهمة جدا : لاحظ الصفات جميعها بسيطة ,, وليست مركبة او ماشابه !!!.











2- القسم يمكن ان يدير عدة مشاريع , ولكل مشروع رقم واسم , ومكان تنفيذ .
















هنا استنتجنا الكيان "مشروع " لان له صفات وله علاقة بالقسم وهي علاقة تحكم وإدارة , القسم الواحد يتحكم في عدة مشاريع , المشروع الواحد يتحكم (بضم الياء فعل مضارع مبني للمجهول) من قبل قسم واحد .









3- يمكن ان يعمل في القسم موظف او اكثر ولكن الموظف يجب ان يتبع لقسم واحد فقط ,ونحتفظ بالمعلومات التالية عن الموظف الرقم ( لكل موظف رقم يميزه عن بقية الموظفين ) , الاسم (الاسم الاول , الثاني ,العائلة ) ,الجنس , الراتب , العنوان





هنا ظهر صفات للكيان موظف ... ولكن ظهرت لنا علاقة جديدة بين القسم والموظف .. لاحظ انها كانت علاقة ادارة .. والان علاقة عمل !!

صفات الموظف هي : الرقم وهو مفتاح اجنبي كما يظهر لانه قال "لكل موظف رقم يميزه"

الاسم ... صفة مركبة , الجنس والراتب والعنوان .. صفات بسيطة ...











4- الموظف يمكن ان يعمل في عدة مشاريع (ليس بالضرورة ان يدار المشروع من نفس القسم الذي يتبع اليه الموظف ) ونحتفظ بعدد الساعات التي عملها الموظف في كل مشروع .
















توجد علاقة بين كيان الموظف وكيان المشروع ... وهي علاقة العمل (يعمل في ) , وهنا يوجد صفة مشتركة بين الموظف وبين المشروع , وهي عدد الساعات التي عملها الموظف في كل مشروع , وكما قلنا لولا هذان الكيانان لما وجدت (بضم الواو وكسر الجيم ) هذه الصفة ,,, اذن نضع هذه الصفة المشتركة على العلاقة نفسها ..


اليك النموذج الذي استنتجناه (الصورة 24)




http://img8.picsplace.to/img8/2/24_011.jpg




لاحظ الصفة عدد الساعات "Hours" الموجودة في العلاقة "works on" , وهي علاقة مشتركة ,,
















5- تحتفظ الشركة بمعلومات عن التابعين لكل موظف (التابعين هم الأشخاص الذين يتبعون الموظف مثل الزوجة , الأبناء .... ) هذه المعلومات هي الاسم , تاريخ الميلاد , الجنس , صلة القرابة .






تابعين هم بشر ... وهم كيان لهم الصفات اسم , تاريخ الميلاد , جنس , وصلة القرابة ,,


هؤلاء التابعين للموظف في الشركة , لو ان الموظف غير موجود بالشركة ... هل تهتم الشركة بمعلومات التابعين لهذا الموظف ؟




كيان التابعين لن يكون له وجود في النظام طالما ان كيان الموظف لا يكون له وجود في النظام ,


لذا فكيان التابعين هو كيان ضعيف "weak entity "









6- تهتم الشركة لمعرفة عدد الموظفين في القسم الواحد








هذه صفة لاي كيان ؟


هل للكيان موظف ام للكيان القسم ؟

هذه الصفة بامكاننا ان نجعلها بسيطة , ولكنها في الحقيقة ... مشتقة لانه بامكاننا ان نوجدها من عدد الموظفين في أي قسم , هذه الصفة تخص الكيان القسم وليس الكيان موظف , تخيل معي :

قسم أ وبه 50 موظف , قسم ب وبه 60 موظف .... اذن صفة مشتقة وخاصة بالكيان "قسم"









7-المدير لكل قسم يدير جميع الموظفين تحت قسمه .


هنا علاقة كيان الموظف مع كيان الموظف نفسه وهي الادارة (سوبر_فيزر )









8- الموظفين نوعين , موظف ثابت ويأخذ راتب ثابت , وموظف يعمل بنظام الساعات ويأخذ نسبة عدد الساعات التي عمل بها .








كيان الموظف له اكثر من نوع , موظف ثابت وموظف يعمل بنظام الساعات !!


اذن فكيان الموظف كيان رئيسي , سنضطر الى حذف الصفة "راتب " ونضيف صفة راتب ثابت الى الكيان الموظف الثابت , وصفة راتب بنسبة الساعات الى الموظف الذي يعمل بنظام الساعات .









الان انظر النموذج النهائي .. ولا تنسى ان تلاحظ علاقة السوبر فيزر بين الكيان الموظف مع نفسه ,,








... واي سوال أي استفسار احنا حاضرين ( الصورة 34 )

http://img6.picsplace.to/img6/8/34_005.jpg

The Coder
07-12-2005, 12:42 PM
* تحويل من نموذج العلائقي الكياني الى نموذج علائقي :



لماذا هذا التحويل ؟

تسهيل علينا تحويل التصميم الى قاعدة بيانات فعلية .

- الان كل كيان سوف يمثل جدول .

- وكل صفة تمثل حقل في هذا الجدول .

- وكل علاقة ينتج عنها مفتاح اجنبي ... ومن الممكن ينتج جدول .




اولا : الان خذ كل كيان على حدة , مع العلم ان كل كيان يمثل جدول .. اوكيه !!





- كيان الموظف : (الصورة 44)



http://img4.picsplace.to/img4/14/44_001.jpg




سنقوم بتجاهل الصفات المركبة الأصل , وفي كيان الموظف توجد صفة "الاسم" والتي تكون اسم اول , اسم ثاني , العائلة , تجاهل صفة "الاسم " وسوف ينتج لدينا ما يلي : (الصورة 54)



http://img7.picsplace.to/img7/4/54.jpg



والان لدينا جدول موظفين وهذه حقوله , لاحظ تجاهلنا للصفة المركبة "الاسم " واخذنا الصفات البسيطة التي تتكون منها هذه الصفة المتركبة ... الصفات البسيطة هي ..الاسم الأول + الاسم الثاني + العائلة .



- كيان القسم : (الصورة 64)


http://img6.picsplace.to/img6/8/64_000.jpg




وبعد تحويله : (الصورة 74)








http://img6.picsplace.to/img6/8/74_000.jpg











لاحظ اننا تجاهلنا الصفة المشتقة في تحويلنا من نموذج ER الى النموذج العلائقي ....

اذا واجهتك صفة مشتقة .. تجاهلها تماما .. عند هذا التحويل ,,

وسوف تعرف ان شاء الله فيما بعد ... الصفات المشتقة و كيفية ايجادها ,,,,









- كيان المشروع : (الصورة 84)


http://img6.picsplace.to/img6/8/84_000.jpg




وبعد تحويله : (الصورة 94)


http://img7.picsplace.to/img7/4/94.jpg




- كيان التابعين وهو كيان ضعيف (الصورة 104)


http://img8.picsplace.to/img8/2/104.jpg


بعد تحويله : (الصورة 114)




http://img7.picsplace.to/img7/4/114.jpg




بقي كيانين اثنين ... هما كيان الموظف رسمي , وكيان الموظف الذي يعمل بعدد الساعات ,سنشرحهما بعد قليل !!






ثانيا : جاء وقت العلاقات ,, نفصفصها حبة حبة ^^" (يفصفص = يمحص )










- علاقة السوبر فيزر ... مابين كيان الموظف مع كيان الموظف نفسه ...

شوف الصورة 294 (امتحنتكم بالصور ... )


http://img4.picsplace.to/img4/14/294.jpg






مانوع العلاقة ؟

واحد لمتعدد ومتعدد لواحد

نضيف المفتاح الاساسي ... من جهة الكيان المتعدد ... وهنا العلاقة مع الكيان نفسه !!

اذن ... نضيفه في نفس الجدول ^^ وهي حالة خاصة جدا ,, الصورة304

http://img7.picsplace.to/img7/4/304.jpg



Mgr هو رقم المدير .. وهو مفتاح اجنبي ولكن في نفس الجدول ^^ ... وزي مانتو عارفين ان المفتاح الاجنبي يشبه المفتاح الرئيسي المصدر له صح ؟ هذا يعني Mgr يشبه كثيرا Eno في المضمون .



هنا مسئلة تحيرني ... انظر الجدول للموظفين الآن : (صورة 314)

http://img7.picsplace.to/img7/4/314.jpg



لاحظ ان Mgr هو رقم مدير الموظف , لاحظ الفراغ ... لو ان محمد هو المدير , فماذا نكتب في حقل Mgr الخاص به ؟؟ من مديره ؟؟
لو تركناه فارغ . فلن يصبح مفتاح اجنبي ... انا شاهدت امثلة كثيرة يجعلونه فارغ , لماذا يا ترى ؟؟ هل لانه ليس مفتاح اجنبي ؟ لا اعرف لماذا يعملون هذا ...

انا اقول ... ان نضع قيمة 10022 في الفراغ ... وهذا رأيي الشخصي , واعتقد انه صحيح .



هل يوجد صفة مشتركة ؟

لا ..



- علاقة العمل بين الموظف وبين القسم ,, الصورة 324




http://img6.picsplace.to/img6/8/324_000.jpg




مانوع العلاقة ؟

واحد لمتعدد و متعدد لواحد , وانت مغمض عيونك تحط المفتاح الاجنبي في الجدول المتعدد وهو جدول الموظفين . لا يجي واحد ويقول ليش وضعناه في جدول الموظفين .. حح ححححح .... حأجزره جزر!!!

والان يظهر لدينا جدول الموظفين المحسن انظر الصورة 334


http://img8.picsplace.to/img8/2/334_001.jpg


هل شاهدت مالذي حصل ^^ ؟ اضفنا رقم القسم D_no كمفتاح اجنبي ,,,



هل يوجد صفة مشتركة ؟

لا ...

- علاقة الإدارة مابين كيان الموظف و كيان القسم .. انظر الصورة 124


http://img8.picsplace.to/img8/2/124_000.jpg









هذه علاقة أخرى بين الكيانين .. مممممم .. محير صح ^^ .. تعودنا بين الكيانين علاقة .. وهنا تظهر علاقتين .. العمل + الإدارة ... وهذا معناه ماذا ؟ معناه انه بالإمكان تكون أكثر من علاقتين !!






مانوع العلاقة ؟

واحد لواحد (one to one). أي ضع في أي الجدولين مفتاح اجنبي (Foreign Key) .

طيب ... فين وليش نضيف مفتاح اجنبي ؟

انا أقول .... في جدول الاقسام وانت ماذا تقول ؟؟ اتحداك ان تعرف !! (التحدي رقم 2)



هل توجد صفة مشتركة ؟

نعم .. توجد صفة مشتركة وهي .. تاريخ بداية الإدارة ...



انا شخصيا لا ادري اين تضع الصفات المشتركة ... لان المنهج لم يشرح النقطة هذه .. سوف ابحث فيها اكثر ..

المنهج وضعها في جدول الاقسام ... والغالب في الامر انك تستطيع ان تضعها اينما شئت , وعلى حسب الصفة ,,, والله اعلم !!

الان انظر الى جدول الاقسام ( الصورة 284)


http://img7.picsplace.to/img7/4/284.jpg




واو ... انظر الى جدول الاقسام كيف تطور ^^ هل شاهدت رقم المدير (Mgr_no) وهو مفتاح اجنبي ,,,

لاحظ للمرة المليون ان المفتاح الاجنبي يرمز بالخط المقطع تحت عنوانه .




ممممممم ... باروح استريح ^^

The Coder
07-12-2005, 12:47 PM
- العلاقة "ادارة" بين المشروع والقسم :

انظر الصورة 344


http://img4.picsplace.to/img4/14/344.jpg




مانوع العلاقة ؟

واحد لمتعدد ومتعدد لواحد , القسم الواحد يتحكم او يدير اكثر من مشروع .. والمشروع الواحد يدار من قسم واحد بسسسسسسسس .... يعني المفتاح الاجنبي في جدول المشاريع .


الصورة 354


http://img7.picsplace.to/img7/4/354.jpg



يوجد صفة مشتركة ؟

لا



- علاقة "العمل" بين الموظف والمشروع : الصورة 364


http://img8.picsplace.to/img8/2/364.jpg




نوع العلاقة متعدد لمتعدد !!

اوبس !! مالعمل ؟؟... اين نضع المفتاح الاجنبي ؟؟ مين يذكرني ؟

الحل هو الجدول التقاطعي (هل تذكرت فكرة هذا الجدول؟) , ونسميه Proj_Emp table

هل يوجد صفة مشتركة ؟

نعم يوجد .. وهذه الصفة نضعها في ... الجدول Proj_Emp

والان لاحظ حقول الجدول Proj_Emp الصورة 374

http://img8.picsplace.to/img8/2/374_001.jpg

المفتاح الرئيسي لهذا الجدول هو رقم الموظف ورقم المشروع معا !!
وهذه المسئلة لحسن الحظ لا يوجد ذلك المدير اللكدة حمزة ..(اللكدة= الغثة = معقد الامور)
حيث بامكانك تضيف حقل وتجعله مفتاح اساسي .. ومثلا تسميه ماشئت مثلا ...Proj_emp_no او أي اسم اخر ,, ^^
انتهينا من العلاقات ...
هل تذكر منذ زمن بعيد في العصر الحجري تقريبا .... لما قلت لك اترك كيان الموظف رسمي , وكيان الموظف الذي يعمل بعدد الساعات ؟؟
مممم ... ذاكرتك قوية ^^ ... اذن يا صاحب الذاكرة ... فضلتها في الدرس القادم اشرحها ^^ لانه صراحة المسئلة هذه .. لم تمر علي قط , والمنهج العربي الذي استمد منه الدروس اعتبره قديم جدا , وسيء للغاية , ولكن يفي بالغرض ... في بعض الاحيان .
اعتقد انني سوف ابحث عن مناهج اخرى , وليست عربية . هذا المنهج سيء للغاية عن هذه المسئلة .
بامكاني ان اسرد ما ذكره المنهج , ولكن فضلت انني أقف هنا على اساس انني ابحث في تصميم قواعد البيانات الحديثة ... فترقبوا ^^


التحديات :

اتحداك ان تحل احد هذه التحديات او كلها :


التحدي الاول : لماذا المفتاح الاجنبي لا يكون خاليا ؟؟

التحدي الثاني : مارأيك ... لماذا انا اقترحت عليك ان تضع المفتاح الاجنبي في جدول الاقسام ؟؟ وما رأيك انت ؟





المهام : اريد منك ثلاث مهام تعملها ....


- قرائة الدرس .


- قرائة الدرس .

- قرائة الدرس .


انتـــــــــــهى الدرس الرابـــــــــع

The Coder
08-12-2005, 07:03 PM
الدرس الخامس :مفاهيم قواعد البيانات ..



السلام عليكم
بداية الدرس الخامس ... انني لست من سوف يشرحه ... بل .. احد السادة في احد المواقع ..

في هذا الدرس ... سوف تسرد لكم مفاهيم قواعد البيانات الهامة , وبعدها تخش قليلا في العميق , هناك رجل يدعى بـ InternetMaster .... والله يا ناس اسم على مسمى ,,,

كان يعطي في احد المنتديات مفاهيم وخبرة عشرين سنة .... صراحة اعجبت بطريقته واعجبت بتشويقه واعجبت بعلمه و اصراره .....

ستجد كل شي ... عن كلامه .. وجميع الحقوق محفوظة لانترنت ماستر .... فجزاه الله الف الف خير ....صحيح انه لم يكمل دورته .... ولكن صحح الكثير من المفاهيم الخاطئة .. بطريقة عجيبة جدا ....

هذا الرابط .. اذا اردت ان تقرأ كل مقالاته

http://www.arabteam2000-forum.com/index.php?showtopic=35237&st=0 (http://www.arabteam2000-forum.com/index.php?showtopic=35237&st=0)

فهو الدرس الخامس .... واجبرك ان تقرأ جميع كتاباته المتعلقة بـقواعد البيانات ....

3 ساعات كفيلة بان تنسخ خبرة 20 سنة !!! ..... فكر فيها .... هل تضيع 10 سنوات او 20 سنة ؟؟ ام 3 ساعات ..؟؟

الخيار لك !!!

لقد تطرق الى لغة الـHTML ... ولست مطالب بذلك ,,,

ولقد تطرق الى جمل الـ SQL اقرأها بشكل سريع لاني سوف اشرحها بشكل كافي ووافي ... فلا تخف ^^


اهم شي .. في دروس جمل الـ SQL هي ان تعرف معنى استعلام !!


ايضا تطرق الى الاكسس .... فحاول ان لا تطبق معه لاننا هنا اوراكل ^^ ...... ولان البعض لا يعرف الاكسس جيدا

لا تطبق ... ولكن تخيل اوكيه ^^





سوف يتطرق الى قوانين قواعد البيانات والى تماسكها ....

هل تذكر التحدي ... مالذي ينتج من جعل المفتاح الاجنبي فارغ ؟ ستجد حله في هذه المقالات ....




توقع ان الدرس السادس .. امثلة لتصميم قواعد البيانات ....
والدرس السابع هو بداية لغة الـ SQL , اوكيه ؟؟
يالله سلااام ,,

The Coder
08-12-2005, 07:09 PM
السلام عليكم ,,,


















"احدهم" ارسل لي التحديات , اشكره على حلها , وصراحة وجدت عنده خطأ بسيط في مفهوم الكيانات الاساسية .. والكيانات الفرعية .

قلنا ان الكيان اذا كان يوجد منه اكثر من نوع متشابهين.. ولكن مختلفين في الصفات .. فاننا نقسم هذا الكيان بعدد الانواع
















http://img4.picsplace.to/img4/14/__1582___1591___1571_.jpg




























لاحظ هذا النموذج وهو الذي ارسله "احدهم" , قسم كيان القسم الى ثلاث انواع !!!



المشكلة ان الانواع الثلاثة .. صفاتها متشابهة , أي يوجد تكرار

قسم كيان الموظف الى نوعين , الفترة الصباحية والفترة المسائية ,

المشكلة تكمن في ان النوعين متشابهين تماما في الصفات .. ليش التكرار ؟

انا اقترح عليك يا "احدهم" مايلي :














http://img5.picsplace.to/img5/15/__1578___1589___1581___1610___1581_.jpg














انا قسمت الموظف الى قسمين .. موظف يعمل بالساعات H-Employee وموظف رسمي براتب ثابت S_Employee














شايف اقتراحي كيف جعلت الصفات المتشابهه في الكيان "الموظف " ؟ والصفات المختلفة والتي هي "الراتب الثابت Salary" و "الراتب بنسب الساعات hour_rate_salary"














هل فهمت احد اخطائك ؟



شايف الصفات ذو اللون الاحمر ؟












The_interval .. أي الفترة ..



يمكن ان تكن صباحية او مسائية

انا جعلتها صفة للكيان موظف .. افضل من ان اجعله كيان فرعي صح ؟ لا يوجد الان تكرار ^^

شايف الصفة الحمراء الثانية ؟












Dept_name ... صفة للكيان قسم ..



يعني اسم القسم .. ممكن يكون حسابات , او صيانة , او علاقات ....... الخ

ولا يوجد تكرار ولا هم يحزنون ...

وصلت ^^ ؟؟



























حاولت يا "احدهم" واخطأت , والان تستفيد من خطأك ان شاء الله .. راسلني اذا لم تفهم .. سوف اعيد واعيد واعيد ,,, انا من النوع الذي لا يمل الاجوبة ^^ .. صدقني



شكرا لك يا "احدهم" على ارسال التحديات جميعها .. شكرا لك ^^

يا سادة .. تالله لن تفهمو طالما لايوجد تمرس + قرائة + رغبة

حلو الواجبات والتحديات ,, حلوها يا بشر ,,

The Coder
11-12-2005, 10:51 AM
السلام عليكم ...



سأضطر الغياب لمدة اقل من اسبوع ...

فا .... المعذرة :D << سفر



وعلى فكرة .. كنت ناوي انتهي من الدورة لمدة شهرين ..

بس ... ما بتشجعو ... على طرح المواضيع بسرعة ..

فالافضل .. لي ولكم .. عدم الاسراع ..

وانا حسوي تكنيك .. قوي جدا .. لتعليمكم من الصفر الى اللانهائية ^^ ..

والقاعدة رقم اثنين تقول ....

"تعلم كل شي .. او لا تتعلم "

لذا ... حأجعلكم تعملو .. مشروع يفيدكم ..

وسأجعلكم ان شاء الله تتعلمون البرمجة .. حتى ولو لم تتعلمو سطرا واحدا فيها ,,,

تتتتتتتررررررقبوووووووو

The Coder
13-12-2005, 08:58 PM
السلام عليكم
احدهم ارسل لي هذه الرسالة :

"شكرا لك أخي درسك هذا كان رائع و طريقتك في الطرح تعجبتني جدا لكن الموضوع بدأ يصعب شوية فالنموذج كان كبيييييير و يتووووه .
و على فكرة أنت قلت أن وضع المفتاح الأجنبي في جدول الموظفين لن يجربه أحد ، لكن أنا جربته لا تكن بهذا التشاؤم ! "

وارد عليه واقول .. لم يجرب غيرك يا "احدهم " ^^ .... ولم يرسل لي احد التحديات الا انت وأخر فقط ...
وانا اعرف متى اتشائم .. ومتى اتفائل ^^ ,,,, لا تخف علي ^^

ومن ناحية ... ان النموذج كبير ويتوه ..
قصدت ذلك .. وكنت ناوي اضع نموذج اعقد واعقد ... لكي تتدرب بشكل قاسي وقوي ..
وتواجه اي نموذج تجده امامك في المستقبل .. مهما بلغت صعوبته ,,,

شكرا لك يا "احدهم" ... وشكرا لكم ^^

The Coder
18-12-2005, 10:12 AM
الدرس السادس


السلام عليكم ,,,

هذا الدرس ..اعتبره من اهم الدروس .. ويشكل احد الاعمدة الاربعة التي نتكيء عليها في منهجنا هذه ...

ومن ناحية البرنامج الخاص بلغة الـ SQL فسوف اشرحه لاحقا ... لذا اريدك ان تفهم الدرس بدونه الان ,,,,
توقع انني لن اكثر عليك تحديات في هذا الدرس ... اعرف انك سعيد بهذا ,,,





بسم الله الرحمن الرحيم

اسم الدرس : لغة الاستعلامات SQL


نوع الدرس : تطبيقي + فكري


صعوبة الدرس : *** من *****

اهميــة الدرس : ****** من ***** (Over)


الوقت المتوقع منك لفهم الدرس : 8 ساعات (ساعتين فهم و 6 ساعات تطبيق )

متطلبات تتوفر فيك : التطبيق





المتوقع منك في هذا الدرس :

- اتقان جزء كبير من هذه اللغة 100 %


هيا لنؤركل ^^





* لغة الاستعلامات (او الاستفسارات) والتي تدعى بـ SQL :


احب ان اشير الى قاعدة مهمة ... وهي القاعدة رقم 3

(البيانات + معالجة = معلومات)

وكما عرفت في الدرس الخامس .. هذه القاعدة , لذا يفترض انك تعرف مالبيانات .. ومالمعلومات ..

ولماذا البيانات .. ولماذا المعلومات . وما هي اصلا المعالجة , ولماذا نحصل على المعلومات ..

اعرف ان ثلاث ارباعكم ما قرأوا ولا بيعرفوا الاجوبة ....

لكن ... الله المستعان ,,,

اذا لم تقرأ الدرس الخامس ... اذهب ولا تقرأ ....





SQL تعني Structured Query Language أي لغة الاستفسارات وهي لغة برمجة قواعد البيانات ....


وعلى قول انترنت ماستر (الدرس الخـامس) مايلي : (ما بين القوسين كلامي انا )


" Query تعني إستعلام إستفسار إستفهام إستنباط إستنبطاااح ---- وصلت الفكرة؟؟؟

السؤال البديهي والتقليدي هو ما الفرق بين الجدول والإستعلام؟

(الجدول الي هو الملفات الموجودة والمخزنة لدينا والتي تمثل جداول .. الاستعلام هو الحصول على المعلومات من هالجداول وعرضها كجدول ... وايضا تغيير القيم فيه .... مافهمت ؟؟ طيب طيب ... حتعرف بعدين .. نكمل كلامه .. ونعرف الفرق )

الجدول هيكل خرساني شديد التماسك والتكامل يعمل مع بقية الجداول مع محافظته على إستقلاله وشخصيته. الجدول هو رجل ببدلة رسمية منتصب الطول عابس الوجه لا يمزح ويسير في الشارع بجدية مفرطة وإلتزام كبير.

لا تمزح مع الجدول... الجدول لا يقبل المزاح ول لا العبث ويغلب عليه التماسك والشدة والعبوس والتجهم.
(ملف مخزن ... شكله واحد موحد .. ولا يتغير مع الزمن ^^ )
الإستعلام (ولد صايع) على رأي الأخوة في مصر ... حبوب، لذيذ، يحب المزاح، سهل التعامل معه، يقبل كل أنواع المزاح والعبث ولكن إذا مزحت معه من (اليمين)، إذا مزحت معه من (اليسار) --- نسف قاعدة البيانات من جذورها. هل سمعت بمثل إتق شر الحليم اذا غضب --- هذا هو الإستعلام !!!

لأن السيد Codd مزق حقولنا ووزعها في جداول مختلفة كان لا بد من طريقة ما لتجميع هذه الحقول مع بعضها البعض !!!
(تفتكرون ليش قسمنا الجداول ... وتفتكرون ليش طلعت حاجة اسمها المفتاح الاجنبي ... )
الجدول هو الإستعلام، والإستعلام هو الجدول !! مع مرونة عالية جدا جدا جدا في كيفية تشكيل الإستعلام.
(الاستعلام ينتج لنا جدول ... يعني حيصير جدول بس بالطريقة الي احنا نبيها .... )
SQL هي لغة تستخدم علم (المصفوفات) من الرياضيات للوصول إلى الحلول --- ولا يهمك حقيقة ماذا تستخدم ولكن للعلم بالشىء فقط لمحبي هذا العلم الرائع المسمى المصفوفات Matrices ومفردها مصفوفة Matrix.

الغريب في SQL أنها عميقة الجذور وفي غاية التعقيد الشديد جدا، ولكن الممتع في الموضوع أن كامل اللغة بكل أبعادها تتكون من أقل من 10 أوامر -- صدق أولا تصدق أو حتى أقل من 5 أوامر على ما أذكر !!!

قلنا أن SQL تمزح من الجهة اليمين --- وتغضب من الجهة اليسار، ما معنى هذا؟

هناك إستخدامين إثنين فقط للغة SQL واحد أسميه مزاح من اليمين والآخر مزاح من اليسار:

الإستخدام الأول (مزاح من اليمين): هو الحصول على البيانات بأي شكل وبأي كيفية (لكي ينتج البيانات التي طلبناها على شكل جدول )
الإستخدام الثني (مزاح من اليسار) : هو تحديث Skeleton او الهيكل الخرساني لقاعدة البيانات أي تغيير وتعديل الجداول والحقول والروابط ---- اااووو خطير جدا !!!

"




ويضيف " النوع الثاني من المزاح ينقسم إلى شقين:

الأول: تعديل في البيانات داخل الجداول " في السجلات" -- وينبغي الحذر
الثاني: تعديل في الجداول والحقول والروابط بينها --- وهو الخطير -- وينبغي الحذر الشديد جدا

تعدل بيانات الجداول يتم من خلال:
إضافة سجلات جديدة
تعديل سجلات موجودة
حذف سجلات موجودة

"




انتهى كلامه ......

اضيف انا انه في تعديل الجداول والحقول والروابط بينها ... يعني مثل اضافة عمود او حذفه او تعديل اسمه ..

اضافة جدول او حذفه او تعديله ... اضافة علاقة ...... الخ





اذن ... لغة الـSQL تلعب في الجداول لعب .... ولها غرضين ,, غرض استفسار عن معلومات ... يعني نطلب عرض معلومات ,, وغرض تعديل بيانات وتعديل تركيب الجدول .





افهم جيدا .. اذا لم تقم بتركيب الاوراكل .... دبر نفسك .... حمله .. ركبه .. اشتريه .. اسرقه ... يجب ان تمتلك أي اصدار من الاوراكل .. لجمل الـ SQL .. أي اصدار .. قديم حديث لا يهم الان .... دبر نفسك فيما بعد في الاصدارات ,,,

الان سوف اعرض عليك تكنيك قوي جدا جدا جدا ....

وهو ان ... تقرأ ... وتطبق على الورق وتستنتج ... ثم ........................ تطبق على الحاسب ....

التطبيق على الحاسب اجعله اخر ما تفكر فيه الان ...




* اقسام لغة الـ SQL :


خمس اقسام فقط .... حنأخذها بتعمق ... طبعا انا لا اعرف ترجمتها معنويا ..لكن حاولت ذلك ...

نحفظها انجليزي ونفهم عملها .. ركز في المصطلح الانجليزي ,,,,





1- استرجاع البيانات (Data Retrieval) :


تخص الاستعلام عن البيانات من جدول ما ....

مثلا الموظف احمد يبي يعرض جميع الموظفين الي راتبهم اقل من 7500 ريال سعودي (7500 ريال سعودي = 2000 دولار امريكي ... وذلك بقسمة 3.75 .... )

فين وصلنا ؟؟ ايه ايه ... احمد يبي يعرض على الشاشة جميع الموظفين الي راتبهم اقل من 7500 ريال ... ايش يعمل ؟

على طول ... يدخل احد اوامر الاستعلام واسترجاع البيانات ,,





2- لغة التلاعب بالبيانات (Data Manipulation Language) اختصارها DML


وهي تخص بتعديل , حذف , او اضافة البيانات والسجلات في جدول ما .... (المزاح من اليسار ^^)

ممم .. احمد (نفس ذلك الموظف المغلوب على امره ) كان يفكر في البزورة وام العيال , وهو يفكر .. استخدم امر الاضافة و ادخل قيمة 9000 ريال في سجل المدير حمزة ...

في اخر الشهر لما استلم المدير الراتب ... جن جنونه .. ناقص من راتبه 9000 ريال ....

راح لاحمد .. وخذ سب وشتم انواع ....

احمد الان يريد ان يعدل هالمعلومة الخطأ في الجدول .... يعمل ايش ؟

يستخدم امر التعديل ....





3- لغة تعريف البيانات (Data Definition Language) اختصارها DDL


وهي التي تخص بتعديل , حذف او اضافة وانشاء الجداول وخصائصها (الاعمدة) وعلاقاتها ..


احمد (نفس ذلك الموظف .. بس في اليوم الثاني ) استخدم احد اوامر DDL وهو امر انشاء جدول جديد , بعد ما انشئه ماعجبه اسم عمود .. واستخدم احد اوامر الـ DDL وهو امر خاص بتعديل اسم عمود , لو يبي يحذف الجدول كله .... يستخدم امر خاص لحذف الجدول .




4- التحكم بالعمليات (Transaction Control)


هذه خاصة بتثبيت وحفظ العمليات ... يعني لو مثلا (مجرد مثال) عدل احمد اسم جدول الموظف الى "الموظفين"... ويبي يقفل الجهاز , لازم يستخدم امر خاص بحفظ هذه العملية ...


.. ندم احمد انه غير اسم الجدول .... ويبي يتراجع عن هذه العملية (قبل ما يكفشه المدير) وش يعمل ؟

على طول ... يستخدم امر التراجع ... ولا من شاف .. ولا من دري (صراحة ... من الممكن ان المدير عامل برنامج تجسس يعني يعرف حماقات احمد من "طقطق" الى "سلام عليكم " لذا انتبهوا ^^ .. سوف نبرمج هذا البرنامج فيما بعد )




5- لغة التحكم بالبيانات (Data Control Language) اختصارها DCL


خاصة بالصلاحيات .. يعني لو مثلا طنت في راس المدير الغثة (حمزة) في اخر الليل ... انه ما يبي احمد (الموظف المسكين) يعدل على الجدول الموظفين ... ولا يبي اصلا يعطيه صلاحية الوصول الى هذا الجدول , اش يسوي المدير ؟؟

يقوم بدري في الصبح .. قبل ما يجي المسكين احمد .... ويستخدم احد اوامر الـ DCL ,, ويلغي صلاحية المسكين للوصول الى الجدول ... فهمت ؟؟؟







سوف اركز كثيرا على الاختصارات .... لذا احفظها جيدا

اعرف انك تبي تقتلني عشان المصطلحات هذه ... ولكن تحمل قليلا ^^"


لن اشرح الان البرنامج المستخدم لتنفيذ جمل الـSQL لذا حاول تفهم الان بدونه .

The Coder
18-12-2005, 10:27 AM
القسم الاول ( ( Data Retrieval :







في استرجاع البيانات .. نستخدم امر واحد .. وهو الأمر Select









اذا لم يكن لديك برنامج SQL Plus فلا بأس ... انا سوف اشرح الان على اساس انك لا تملكه الان ...








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








الان تخيل انه لدينا جدول الموظفين EMP ... وبه الحقول التالية الصورة (16):








http://img7.picsplace.to/img7/4/16_015.jpg


Empno هو رقم الموظف (مفتاح اساسي)



Ename هو اسم الموظف








Job هو وظيفة الموظف








MGR هو رقم مدير الموظف








Hiredate هو تاريخ توظيف الموظف








Sal راتب الموظف الاساسي








Comm الزيادات .. أي الرواتب الاضافية على الراتب الاساسي sal


Deptno رقم القسم الذي يعمل فيه ... (مفتاح اجبي (مفتاج غريب) )

الان تخيل انه ممتليء بهذه البيانات :












EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

------ ---------- --------- ---------- -------- ---------- ---------- ----------

7369 SMITH CLERK 7902 17/12/80 800 20

7499 ALLEN SALESMAN 7698 20/02/81 1600 300 30

7521 WARD SALESMAN 7698 22/02/81 1250 500 30

7566 JONES MANAGER 7839 02/04/81 2975 20

7654 MARTIN SALESMAN 7698 28/09/81 1250 1400 30

7698 BLAKE MANAGER 7839 01/05/81 2850 30

7782 CLARK MANAGER 7839 09/06/81 2450 10

7788 SCOTT ANALYST 7566 19/04/87 3000 20

7839 KING PRESIDENT 17/11/81 5000 10

7844 TURNER SALESMAN 7698 08/09/81 1500 0 30

7876 ADAMS CLERK 7788 23/05/87 1100 20

7900 JAMES CLERK 7698 03/12/81 950 30

7902 FORD ANALYST 7566 03/12/81 3000 20

7934 MILLER CLERK 7782 23/01/82 1300 10






وتخيل انه لدينا جدول الاقسام DEPT وبه الحقول التالية (الصورة 26) :








http://img7.picsplace.to/img7/4/26_008.jpg





Deptno رقم القسم (مفتاح اساسي)




Dname اسم القسم (او نوعه)








Loc موقع هذا القسم

















تخيل ان به هذه البيانات :














DEPTNO DNAME LOC

------ -------------- ---------

10 ACCOUNTING NEW YORK

20 RESEARCH DALLAS

30 SALES CHICAGO

40 OPERATIONS BOSTON







الان انظر هذا التركيب البسيط للامر Select

Select * from dept ;

معنى هذا السطر هو ....





Select = اختر


* = جميع الحقول






From = من








Dept = الجدول dept








اختر جميع الحقول من الجدول dept ؟؟


لاحظ الفاصلة المنقوطة (;) في آخرالأمر ..... ومعناه نفذ الجملة ...

لو كتبنا الأمر السابق وضغطنا Enter






سوف ينتج لنا مايلي (بافتراض أن جدول الأقسام به هذه السجلات أصلا ) :





DEPTNO DNAME LOC

------ -------------- ---------

10 ACCOUNTING NEW YORK

20 RESEARCH DALLAS

30 SALES CHICAGO

40 OPERATIONS BOSTON










ممممم.. عرض جميع السجلات الموجودة بهذا الجدول

نجرب الان هذا الامر ...







SELECT * FROM EMP ;

مالذي تغير ؟؟
وضعت اسم جدول اخر .... وهو جدول الموظفين وكأني اقول اختر جميع حقول الجدول EMP






وضعت جميع الحروف capital وليست small؟؟ هل تتوقع ان هذا خطأ ؟؟ لحسن الحظ انه ليس من الخطأ فعل ذلك
















بعد ضغط زر الـEnter هل ستعرف مالذي سيعرض لنا ؟؟ شاهد ....





EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

------ ---------- --------- ---------- -------- ---------- ---------- ----------

7369 SMITH CLERK 7902 17/12/80 800 20

7499 ALLEN SALESMAN 7698 20/02/81 1600 300 30

7521 WARD SALESMAN 7698 22/02/81 1250 500 30

7566 JONES MANAGER 7839 02/04/81 2975 20

7654 MARTIN SALESMAN 7698 28/09/81 1250 1400 30

7698 BLAKE MANAGER 7839 01/05/81 2850 30

7782 CLARK MANAGER 7839 09/06/81 2450 10

7788 SCOTT ANALYST 7566 19/04/87 3000 20

7839 KING PRESIDENT 17/11/81 5000 10

7844 TURNER SALESMAN 7698 08/09/81 1500 0 30

7876 ADAMS CLERK 7788 23/05/87 1100 20

7900 JAMES CLERK 7698 03/12/81 950 30

7902 FORD ANALYST 7566 03/12/81 3000 20

7934 MILLER CLERK 7782 23/01/82 1300 10



عرض جميع السجلات الموجودة بالجدول الخاص بالموظفين ...
جرب الان هذا الامر ...







SeLeCt * FrOm EmP ;


سوف تعرض نفس النتيجة السابقة ... أي ان لغة الـ SQL ليست حساسة من ناحية الاحرف ,,,
طيب ... اريد ان اعرض رواتب (Salary) الموظفين جميعهم ... كيف ؟








Select sal from emp ;


ونتيجة التنفيذ هي :






SAL


----

800

1600

1250

2975

1250

2850

2450

3000

5000

1500

1100

950

3000

1300










اوبس ... ظهر عمود الرواتب فقط ؟؟؟ مالذي حدث بالضبط ؟







Select sal from emp;


معنى هذا الامر هو اعرض لي القيم في العمود sal من الجدول emp






طيب .. اريد عرض عمودي الرواتب والاسماء الخاصة بالموظفين ؟؟









Select sal,ename from emp ;



SAL ENAME
---- ------

800 SMITH

1600 ALLEN

1250 WARD

2975 JONES

1250 MARTIN

2850 BLAKE

2450 CLARK

3000 SCOTT

5000 KING

1500 TURNER

1100 ADAMS

950 JAMES

3000 FORD

1300 MILLER



عرض لي سجلات العمودين الرواتب و الاسماء الخاصة بالموظفين





.....







مممممم ... علامة النجمة تعني "كل الاعمدة " ,,


طيب لو كتبنا الامر السابق بهذه الصيغة ..


Select *

From emp

;



وضغطنا Enter .... فسوف ينفذها من دون أي مشاكل ... يعني انه لا مشكلة من تجزئة وضع الامر ^^ الى عدة اسطر ... بل بالعكس , تجزئة الامر الى عدة سطور يسهل علينا الفهم اكثر ... سوف تلاحظ في الامثلة القادمة هذا الشيء .







- اريد ان اعرض جميع بيانات الموظف الذي يدعى بـ KING







اليك الامر :



Select * from emp

Where ename ='KING'

;



Where أي عندما يكون او الذي...














يعني اعرض لي بيانات جميع الحقول للموظف الذي اسمه = King







اضفنا الشرط .... where ename='KING'







سوف يعرض معلومات الموظف كنق فقط :






EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

------ ---------- --------- ---------- -------- ---------- ---------- ----------

7839 KING PRESIDENT 17/11/81 5000 10



ممممم جميل جدا ,,,
نستطيع التحكم في عدد الاعمدة , وفي السجلات التي نريد عرضها .

اذا اردنا عرض راتب الموظف King مالذي نعمله ؟



Select sal from emp

Where ename='KING' ;



سوف يعرض :









SAL

-----

5000










اوبس ... أين اسم الموظف KING ؟؟ لقد كتبنا اسمه في الامر ..!! لماذا لم يعرض اسمه ؟؟

في الأمر السابق .. نحن قلنا اعرض الراتب فقط ... عندما يكون اسم الموظف King






بدأت الأمور تتعقد ... وبدأ في وجهك احمرار الغضب والغيظ مني ,,


اعذرني ... أنا سادي قليلا في شرح الأمور (سادي = هو الذي يتلذذ بالتعذيب )






سوف اعقد لكالآنالأمورأكثروأكثر ....







الان مارأيك في الامر التالي :




Select * from emp

Where ename ='king';



مالذي تتوقع من هذا الامر ... تخيل انك الان ضغطت Enter ... فسوف يعرض لك هذه النتيجة :










no rows selected






ومعناها ... لاتوجد صفوف مختارة ؟؟


أي لا توجد سجلات للعرض ؟؟

أي لا توجد بيانات للموظف الذي يدعى بـ king






أي لايوجد اصلا موظف يدعى بـ king







قبل قليل ... عرفنا انه يوجد موظف يدعى KING







ونحن قلنا انه KING او king لا مشكلة ...


لماذا ظهرت هنا مشكلة ؟؟

الم نقل ان لغة SQL ليست حساسة لحالة الاحرف ؟















في الحقيقة ان لغة الـ SQL ليست حساسة لحالة الاحرف .. ولكن في قواعد البيانات ... في جدول الموظفين تحديدا خزنا اسم الموظف بـ KING ... وليس king !!







فرق بين البيانات المخزنة في الجدول وبين اوامر الـ SQL فهذه في وادي والاخرى في وادي اخر ...


ان الحاسب جهاز غبي جدا ... ولا يملك الحس الانساني طبعا , ولا يعرف ان KING هو نفسه king






طيب ... هذه تعتبر مشكلة .. بل مصيبة ...


سوف تعرف حلها لاحقا

- اريد ان اعرض الراتب الاساسي ورقم واسم الموظف KING مارأيك ؟؟


Select empno , ename , sal from emp

Where ename = 'KING' ;


سوف يعرض لنا هذا الناتج

EMPNO ENAME SAL

------ ---------- ----------

7839 KING 5000










جميل جدا ...
الان .. مارأيك بالامر التالي :


select * from emp

where ename="KING";



مالذي سوف يحدث ؟؟ سوف تعرض لك مشكلة ...



ORA-00904: "KING": invalid identifier










لماذا ؟؟ مالمشكلة ؟؟ هل لاحظت تغيرا عن الأوامر السابقة ؟؟

بدل 'KING' وضعنا "KING"






ممممم .. يعني انه يجب ان تكون علامة تنصيص الاحادية...







هيا ... لنجرب معا هذه العلامة التنصيص الاحادية ...


اريد ان اعرض الان بيانات الموظف الذي رقمه 7521 ... الامر كالتالي :


Select * from emp

Where empno ='7521'

;


والناتج سوف يكون ..



EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

------ ---------- --------- ---------- -------- ---------- ---------- ----------

7521 WARD SALESMAN 7698 22/02/81 1250 500 30






طيب .. جرب هذا الامر :



Select * from emp

Where empno = 7521

;



لقد حذفنا علامة التنصيص الاحادية ... وسوف يعرض لنا نفس النتيجة السابقة ...
لماذا نستخدم علامة التنصيص اذن ؟؟

جرب هذا الامر ... بعد نزع علامة التنصيص الاحادية :



Select * from emp

Where ename=KING

;


سوف يعرض لك هذا الخطأ


ORA-00904: "KING": invalid identifier



ممممم ..






استنتاج : يجب استخدام علامة التنصيص الاحادية مع الحقول (حقول=أعمدة=صفات) التي من نوع الاحرف ....ولا يوجد أي خطأ اذا استخدمناها مع الأرقامأو حذفناها .... ^^ وصلت ؟؟

The Coder
18-12-2005, 10:37 AM
- عرض الحقول باسماء مستعارة :






مممم .. المدير حمزة (نفس ذاك المدير) يريد تعقيد الامور على الموظف احمد (نفس ذاك الموظف المسكين)

يريد عرض هذه النتيجة .... ويريد من احمد استنتاج الامر ..

النتيجة :


SALARY THE_NAME

------- --------

1250 WARD

1250 MARTIN





من الجدول Emp !!!



احمد يقول انه لا توجد حقول بالمسميات SALARY و THE_NAME ؟؟


كيف ظهرت هذه المسميات ؟؟؟؟

احمد يعرف جيدا انه انعرض رواتب و اسماء الموظفين والذين رواتبهم = 1250

ولكن لا يعرف هذه المسميات من الحقول

اليك الحل يا احمد ....

بامكانك يا احمد ... ان تسمي الحقول ما شئت في العرض فقط ... لم تفهم ؟؟

طيب ...


select sal SALARY , ename THE_NAME from emp

where sal = 1250;


مارأيك ؟؟
قلنا اعرض الحقل sal وسميه salary (لاحظ المسافة بين sal و salary)






واعرض الحقل ename وسميه the_name (لاحظ المسافة بين اسم الحقل وتسميته)


برافو يا احمد ... حللتها يا احمد ...

مطط المدير شعره .. حقدن وحنقن على احمد ... يريد تعجيزه باي طريقة ..

يقول المدير انه يريد اسم الحقل sal بهذا الاسم "salary" .. وليس "SALARY"






ويريد ename بـهذا الاسم "the_name" ... وليس "THE_NAME"







واحمد ماشاء الله عليه .... ذكي وفهمها على الطاير واقترح الامر التالي :





select sal salary , ename the_name from emp

where sal = 1250;



وظهرت النتيجة التالية :


SALARY THE_NAME

------ --------

1250 WARD

1250 MARTIN










اوبس .. لم يجدي نفعا ؟؟
مالعمل ؟ كل شيء يتحول الى احرف كبيرة (Capital) ؟؟

اليك الحل يا سيدي ,,


select sal "salary" , ename "the_name" from emp

where sal = 1250;



والناتج :



salary the_name

------- ---------

1250 WARD

1250 MARTIN










يعني بوضع علامتي تنصيص ثنائية للعنوان (العنوان الخاص بالحقل).. سوف تعرض لنا كما نريدها ...

لما كنت ادرسها منذ زمن ...كان اكثر شيء يعقدني ... علامات التنصيص ..

فمرة اقول ان علامة التنصيص الاحادية للعناوين .. والثنائية للمتغيرات الحرفية (القيم النصية كما فعلنا في اسم الموظف KING)....






ومرة اقول العكس ...








انتبه جيدا ... الثنائية للعناوين .. والاحادية للقيم النصية






انظر جيدا ... لهذا المثال :


select sal "SaLaRy Of ThIs eMpLoYeE" from emp

where sal=1250;



شكلنا من الحروف الكبيرة والصغيرة ... ووضعناها في علامة التنصيص باسم مستعار للعمود sal



سوف يكون الناتج مايلي :



SaLaRy Of ThIs eMpLoYeE

-----------------------

1250

1250


كما توقعنا ... ظهر بنفس الصيغة التي اردناها ,,, لاحظ وجود مسافات ... وهي لم تضر بشيء .. ولا مشكلة فيها .. انما المشكلة لو لم يكن هناك علامة التنصيص .. فيجب ان لا تضع مسافات في التسمية ,,
انظر هذا المثال الاخير :


Select ename as "Name" , sal as salary , deptno department_number

From emp

Where deptno=30;






Name SALARY DEPARTMENT_NUMBER
---------- ---------- -----------------

ALLEN 1600 30

WARD 1250 30

MARTIN 1250 30

BLAKE 2850 30

TURNER 1500 30

JAMES 950 30










ممممم ... زدنا كلمة as ... وهي كلمة زائدة في عرض الأسماء المستعارة ... سواء وضعناها .. او لم نضعها .. لا فرق ....( لماذا عرضتها في هذا المثال )؟؟ لكي لا تتفاجأ اذا شاهدتها في احد الكتب .. وتقول أنني لم أطلعك عليها ^^ .. بس




- عرض العمليات الحسابية :


انتبه !!! توجد نقاط مهمة جدا ..... يجب عدم اغفالها ,,,

نريد عرض رواتب الموظفين الشهرية بالقسم رقم 30 ... ونريد عرض رواتبهم السنوية .... مالذي نعمله ؟

اولا كيف نوجد الرواتب السنوية ؟

12 * الراتب الشهري = الراتب السنوي(annual salary ) ...


معادلة بسيطة ....

نحن نملك حقل خاص بالرواتب الشهرية .. صح ؟ وهو الحقل sal


ولكن لا نملك حقل خاص بالرواتب السنوية ...

هل تذكر في تصميم نموذج ER .. الصفات المشتقة ؟

وهي الصفات التي يمكننا ان نوجدها من صفات أخرى للكيان ...

مثل المعدل , او الربح السنوي ... او ماشابه ,,

قلنا ان لا تضع الصفات المشتقة كحقل في الجدول صح ؟

في القاعدة رقم واحد والتي تنص على "على حسب المتطلبات نعمل النظام او نبرمجه او حتى نصممه "


لو كانت المتطلبات في نظام الموظفين .. إيجاد الراتب السنوي (وهو صفة مشتقة.. ونوجدها من الصفة "الراتب") ... مالذي سوف يحصل ؟

لدينا خيارين لا ثالث لهما ..

اما ان نجعله حقل في الجدول بالرغم انه صفة مشتقة ...

أو اما ان نهمله , ولا نجعله حقل في الجدول , وفي الاستفسار نوجده ...

لماذا الخيار الأول .. ولماذا الخيار الثاني ؟؟

الخيار الاول ... وهو ان نجعل هذه الصفة المشتقة (الراتب السنوي ) كحقل في الجدول .. ويكون جاهز ..

تخيل معي هذا الامر .. اعرف انه لا يوجد حقل باسم الراتب السنوي (annual salary ) ولكن تخيل انه يوجد هذا الحقل ,,,



Select annual_sal ,sal from emp where ename='KING';


والناتج :




SAL ANNUAL_SAL

---- ----------

5000 60000


كل ما حصل هو اننا حصلنا على معلومة ثابتة من جدول الموظفين ...
لو ان راتب الموظف king زاد ... مثلا صار 5500 دولار .. فما العمل .. هل يبقى الراتب السنوي 60000 ؟؟

سوف نضطر الى تعديله هو الاخر .. وندخل القيمة 66000 ...


هذا اذا وضعناه كحقل جاهز في الجدول ...


اذا لم نضعه حقل ... كيف نوجده ..؟؟؟ أنا أخبرك الآن ..



select sal , 12*sal from emp ;

وسوف يكون الناتج .. ما يلي :


SAL 12*SAL

------ ----------

800 9600

1600 19200

1250 15000

2975 35700

1250 15000

2850 34200

2450 29400

3000 36000

5000 60000

1500 18000

1100 13200

950 11400

3000 36000

1300 15600




لاحظ العملية الحسابية .... أين عملناها ؟ في نفس الاستعلام ,,,

يا سلام .. لغة مرنة بشكل كبير , سواء اضفنا ضرب .. قسمة .. جمع .. طرح .. فسوف تنفذها ,,,

كل ما عملناه هو ... اننا قلنا sal*12 فقط .. وهو بشكل أوتوماتيكي .. عرف انها عملية حسابية ,,

الان دعنا نتفنن قليلا ونغير مسمى الحقل باسم مستعار ..



select sal , 12*sal as "Annual_Salary" from emp ;

انظر الى الناتج الان ,,


SAL Annual_Salary

----- -------------

800 9600

1600 19200

1250 15000

2975 35700

1250 15000

2850 34200

2450 29400

3000 36000

5000 60000

1500 18000

1100 13200

950 11400

3000 36000

1300 15600



هل تذكر الحقل comm ؟؟؟ وهو الخاص بالرواتب الاضافية ... بعض الموظفين لديهم رواتب اضافية والبعض الاخر لا يملك رواتب اضافية .. الموظف MARTIN .. لديه زيادة 1400 دولار .. مارأيك لو نحسب راتبه الاجمالي .. والراتب السنوي الاجمالي ؟؟ هل تعرف ؟؟


Select sal+comm "salary" , (sal+comm)*12 "annual_sal"

from emp

where ename='MARTIN' ;



سوف ينتج لدينا ...



salary annual_sal

------- ----------

2650 31800



معقدة قليلا هاه ؟؟ لماذا اضفنا الاقوس ؟؟ انسى امر الاقواس الان .. وركز في sal+comm ... وهي اضافة الراتب الشهري مع الراتب الاضافي للموظف MARTIN



- الأولويات الحسابية :

اولويات ؟؟ ما قصدنا بهذا ؟ اليك درس بسيط في الرياضيات ولكن مهم جدا في التطبيقات البرمجية .. لا يستحب ان تعرفه .. ولا يفضل ان تعرفه .. بل يجب ان تعرف هذا الدرس ...


لاحظ (لاحظ = فعل امر.. وهو اجباري) المعادلتين الحسابيتين التاليتين :

10+20*5 = ؟؟؟؟

لو قلنا 10+20 = 30

ثم ..


30*5 = 150


اذن الجواب هو 150

طيب ...

انا اعرف ان احدكم حسبها بهذه الطريقة ..


5*20=100

100 + 10 = 110


أي الطريقين اصح ؟؟ هل 150 .. او 110 ؟؟

لماذا بدأنا بالجمع ثم الضرب ...

ولماذا بدأنا الضرب ثم الجمع ؟؟؟

لماذا حصلنا على قيم مختلفة ؟؟

اريدك ان تحفظ الاولويات التالية الان ...

1- الاقواس

2- الاسس

3- الضرب او القسمة ..

4- الجمع او الطرح

احفظها صم ... يالله دقيقة حفظ ثم ارجع واقرأ ....





اليك المسألة التالية ...



(1+2)*3=???


هل الجواب هنا 9 ... او 7 ؟؟؟
الاولوية تقول الاقواس اولا ... يعني 1+2 = 3 ... ثم .... 3*3=9 ....

مسئلة اخرى



1+2*3=??


هل 7 ام 9 ؟؟
الاولوية تقول .. الاقواس .. ولكن لا يوجد اقواس .. اذن الاسس .. لا توجد اسس .. اذن ... الضرب او القسمة ..


3*2=6 ..


ثم الجمع او الطرح .. 6+1=7


مسئلة ثالثة ..



2*8/4 =??


لا اقواس ... لا اسس .. فقط الضرب و القسمة .. ايهما نبدأ ؟؟
لاحظ اننا كتبناها بالانجليزي ... ومسائلنا بالانجليزي ..

خذ اول عملية تواجهك عندما تقرأ من اليسار الى اليمين (لو عربي .. فاننا نقرأ من اليمين الى اليسار طبعا ,,)

اقرأ ... 2 ..... ثم ... ضرب ..... ثم 8 ... اذن الضرب له الاولوية ..


2*8 = 16

16/4 = 4


المسئلة ما قبل الاخيرة ..



(3*4)+5*(4-2)/2


هيا .. حلها في ورقة .. او في رأسك اذا كنت كألبرت انشتاين ...
الان حلها ...


,,,

,,

,


انتهيت ؟؟؟







الحل كالتالي ...



= (12 ) + 5 * (2 ) / 2

= (12) + 10 / 2

= (12) + 5

= 17









المسئلة الاخيرة :


1+2-3*5/5



مارأيك لو جربت ^^ ؟؟

....

...

..

.


الحل :




= 1+2-15/5

= 1+2-3

= 3-3

0=




اليك اول تحدي .. صعب لدرجة تجعلك تقف مشدوقا ... مستغربا مني .. لماذا أحب ان أعقدك ,,



((1+2)*(5-3) + 2 )/(1+2/2) = ???


وهو التحدي الاول في الدرس ,,, سواء حللت ام لم تحل التحديات... لن ينقص مني شيء ..
اذا تجاهلت التحديات .. فانت تتجاهل نفسك لا اكثر ولا اقل .. ولا اهتم ما اذا كنت حللت ام لا ,, كل شيء لمصلحتك انت ...

اذا لم تعرف راسلني . اطرح مشاركتك ... افعل أي شي .. وانا تحت خدمتك ,,

The Coder
18-12-2005, 11:12 AM
الان ... اريد عرض الرواتب للموظفين السنوية .. مضاف اليها 100 دولار اعاشة سنوية لجميع الموظفين ...

هل هذا الامر صحيح ؟








Select sal*12+100 from emp ;










هل تعتقد ان هذا الامر صحيح ؟








Select (sal*12)+100 from emp ;










وهل تعتقد ان هذا الامر صحيح ؟







Select sal * (12+100) from emp ;


أي الاومر اصح ؟؟


























الامر الاول والثاني هما الصحيحان ...



اعتقد ان الاولويات بسيطة جدا ,, سوف تحتاجها كثيرا فيما بعد ... لذا لا تنسى ,,



























- اداة ضم الحقول :



مارأيك بهذه النتيجة ... هل تستطيع ان تعمل مثلها ؟؟



ename and sal

---------------

SMITH800

ALLEN1600

WARD1250

JONES2975

MARTIN1250

BLAKE2850

CLARK2450

SCOTT3000

KING5000

TURNER1500

ADAMS1100

JAMES950

FORD3000

MILLER1300
















هل تستطيع ان تجعل عمود اسم الموظف مدموج مع عمود الرواتب ؟



اليك الامر ...













select ename||sal as "ename and sal" from emp ;



سوف تعرض النتيجة السابقة ..
لاحظ هذه العلامة ||

وهي الخاصة بعملية ضم اكثر من حقل .. وعرضها بشكل مضموم ....

اليك مثال اخر













select ename||' and '||sal from emp ;



اضفنا نص ..
يعني ضمينا ename مع النص ' and ' مع sal












وسوف تظهر هذه النتيجة ...






ENAME||'AND'||SAL

------------------

SMITH and 800

ALLEN and 1600

WARD and 1250

JONES and 2975

MARTIN and 1250

BLAKE and 2850

CLARK and 2450

SCOTT and 3000

KING and 5000

TURNER and 1500

ADAMS and 1100

JAMES and 950

FORD and 3000

MILLER and 1300
























هل لاحظت كيف عرض العمود ؟؟


لاحظ عنوان العمود ... عنوانه هو : ENAME||'AND'||SAL






صحيح ؟



طيب .. اريد ان اعرض عمود بهذا الشكل ...

" الموظف KING يأخذ راتب 5000 "












"الموظف SMITH يأخذ راتب 800 "














..... الخخخخخ



يعني اريد النتيجة مثل هذه النتيجة ....





The_Information

--------------------------------------------------

the emp_name is : SMITH and his salary is =800

the emp_name is : ALLEN and his salary is =1600

the emp_name is : WARD and his salary is =1250

the emp_name is : JONES and his salary is =2975

the emp_name is : MARTIN and his salary is =1250

the emp_name is : BLAKE and his salary is =2850

the emp_name is : CLARK and his salary is =2450

the emp_name is : SCOTT and his salary is =3000

the emp_name is : KING and his salary is =5000

the emp_name is : TURNER and his salary is =1500

the emp_name is : ADAMS and his salary is =1100

the emp_name is : JAMES and his salary is =950

the emp_name is : FORD and his salary is =3000

the emp_name is : MILLER and his salary is =1300



كنت اريد ان اجعله تحدي ولكن .... تراجعت ...
وكلي ثقة انك سوف تفكر فيه قبل ان تشاهد الاجابة ...

ممممممم ... خذ راحتك ... دقيقتين .. ثلاث ... خمس ... اعتقد انه يستحق خمس دقائق بالكثير ...

لا تريد ان تفكر فيه ...

طيب .....

انت حر .... اليك الامر ...




select 'the emp_name is : '||ename||' and his salary is ='||sal as "The_Information" from emp ;



معقد قليلا ... ولكن بسيط ,,,


























- الغاء التكرار :



لو طلبت منك ان تعرض لي ارقام الاقسام الموجودة في جدول الموظفين ...

فسوف تقول ...













Select deptno from emp ;



وسوف يعرض هذه النتيجة ...



DEPTNO

-------

20

30

30

20

30

30

10

20

10

30

20

30

20

10



لو سألتك ما هي الاقسام الموجودة لدينا ؟؟
فستجيب ... مممم ... 20 ... و 30 ..... و 30... و 20 .... و 10 .....

بالله عليك .. فيه قسم له الرقم 10 .. وقسم له الرقم 10 ؟؟

ام انه هنالك قسم واحد يدعى 10 .. ولكن تكرر لاكثر من موظف ؟؟؟

لو نظرت في النتيجة السابقة ... لوجدت انها 14 سجل فقط ...

فكر لو كانو 14 مليار سجل .. وانه لا يوجد الا القسم 10 .. و 20 ... و 30 .... هل ستعرف ان عدد الاقسام قليل ؟؟

طبعا شبه مستحيل ...

نريد في هذه الحالة ان نلغي التكرار ...

اليك الامر ...














select distinct deptno from emp ;










كلمة distinct هي المسؤولة عن الغاء التكرار ,,


وكأني اقول .. اعرض لي ارقام القسم الموجودة بجدول الموظفين ... وبدون تكرار ,,

النتيجة ستكون ....


DEPTNO

-------

10

20

30


بدون تكرار ...
لا تقل انها غير مفيدة ... لو ان لدينا جداول كثيرة ومعلومات وبيانات ضخمة ... فسوف تعرف فائدتها ...

طبعا هذه الكلمة .. الخاصة بإلغاء التكرار .. لا تصلح إلا لـعمود واحد ...

ولا تصلح لاكثر من عمود ... نادرا ما تحدث .. واعتقد انها صدفة انها ستصلح لاكثر من عمود ,,

هل تريد ان تعرف مالذي سيحدث لو الغيت تكرار عمودين ؟؟

تخيل اننا نريد ان نلغي تكرار الرواتب و ارقام الاقسام .. اليك الامر ..











select distinct sal , deptno from emp ;

واليك النتيجة :


SAL DEPTNO

----- ----------

800 20

950 30

1100 20

1250 30

1300 10

1500 30

1600 30

2450 10

2850 30

2975 20

3000 20

5000 10


ستلاحظ ان الرواتب التغى تكرارها ... ولكن هل التغى تكرار ارقام الاقسام ؟
سوف تحدث مشاكل نحن بغنى عنها وعن شرحها ... ,,,, لذا ... استخدمها الان لعمود واحد ,,



























- ماهي القيمة NULL














هي قيمة خالية ...














لا قيمة لها ...



ليست بصفر ...

وليست برقم ...

وليست مسافة ..

ولا حتى بشيء ...

لا احد يعلم ما قيمتها ... غير انها مجرد .. خالية ...

هي فراغ .... ولا شيء غير الفراغ ,,

هل تذكر العمود comm. من جدول الموظفين emp ؟؟؟؟













select sal , comm from emp;



النتيجة المتوقعة ... هي ...





SAL COMM

----- ----------

800

1600 300

1250 500

2975

1250 1400

2850

2450

3000

5000

1500 0

1100

950

3000

1300
























هل شاهدت فراغات في العمود comm. ؟؟ اعرف انك لم تشاهدها , ولكن نكمل


بعض الموظفين لا توجد لديه بدلات (بدلات رواتب اضافية ..)

لاحظ ان احدهم لديه القيمة صفر والصفر ليست القيمة الخالية NULL .. ولاحظ ان بعضهم لديه القيمة الخالية NULL






والبعض الاخر يوجد عنده رواتب اضافية ,,



القيمة الخالية ... تسبب بعض الاحيان مشاكل ... و امراض معدية .. من تلبك معدي .. الى انفيولنزا ..

من هذه المشاكل مايلي ..

نريد حساب الراتب الكامل وهو يساوي .. الراتب الاساسي sal + الراتب الاضافي comm.




select ename , sal+comm from emp ;

والنتيجة هي :





ENAME SAL+COMM

---------- ----------

SMITH

ALLEN 1900

WARD 1750

JONES

MARTIN 2650

BLAKE

CLARK

SCOTT

KING

TURNER 1500

ADAMS

JAMES

FORD

MILLER



اوبس .. سميث راتبه 800 دولار ... ولا يملك أي رواتب اضافية .. أي قيمة الرواتب الاضافية هي NULL











بالله عليك .. قلي ..














800 + NULL = ؟؟؟



تساوي كم ؟؟

هل 800 ؟؟

قلنا ان NULL قيمة لا نستطيع تحديدها .. وهي خالية ,, وليست صفرا ...

اذن .. فناتج المعادلة ..












800+NULL=NULL














قاعدة اساسية ... يجب ان لا تغفلها .....














" اذا ضربنا ... جمعنا .. قسمنا ... طرحنا .. من القيمة NULL .. فالناتج هو NULL "
















طيب ... مالعمل اذا اردنا ان نعرف الراتب الكامل ... لسميث المسكين ؟؟



سوف نحل هذه المشكلة فيما بعد ... ترقب ^^
















* جملة الشرط where :












سوف ندرس جملة الشرط هذه بتوسع اكثر ..



سأقوم بتغطية هذه الجملة من جهتين ... من عمليات (معاملات) المقارنة ... ومن عمليات اخرى ,,



























- اولا : عمليات المقارنة في جملة الشرط :





























اخذت في السنة الاولى ابتدائي .. في الرياضيات ... المقارنة .. (اكبر من .. اصغر من .. يساوي )














... أصعب درس رياضيات ^^"














ممممم ... مثلا ,,



ايهما اكبر 1 او 1000 ؟؟

اعرف انك لا تستطيع التفكير ,,, او بالأحرى لا تعرف الاجابة لذا ..

ال 1000 اكبر من 1












يعني تنكتب 1000 > 1



وطبعا الـ 1 اصغر من 1000

طيب ... نعقد الأمور اكثر ...

ونقول ..

س اكبر من عشرة ... ما قيمة س ؟

س ممكن ان تكون سالب مليون ... ممكن تكون واحد ... ممكن اثنين .. ممكن ان تكون تسعة .. ولكن لا يمكن ان تكون عشرة ...

هي اصغر من العشرة ولو بشعرة ....

ممكن ان تكون 9.99999999

يعني باختصار ...س .... من سالب مالا نهاية .. الى التسعة

س= {- مالا نهاية ........... 9 }












طيب .. نعقد أكثروأكثر ,,



- س اكبر من او تساوي عشرة ...

يعني س من سالب مالا نهاية ... الى العشرة ,,

طيب ماقبل اخر مسألة بهذا الخصوص ...

- س اصغر من او تساوي ثلاثة ... واكبر من واحد ..

ما قيم س الحقيقية ؟ (حقيقية = هي أرقام بدون كسور ...)

س={2 , 3}

طيب اخر مسألة :












- س اصغر من 3 ... واكبر من او تساوي 3



قيم س الحقيقية هي ....

مممممممم ...

س= {-مالا نهاية .......... + مالا نهاية }












يعني جميع الأعدادبما فيهم الثلاثة ,,



الان انظر الصورة 36 :















http://img7.picsplace.to/img7/4/36_004.jpg








....




مممم ...
انتظرني ,,,

The Coder
18-12-2005, 11:18 AM
- مثال :



اريد عرض اسماء ورواتب جميع من رواتبهم اقل من او تساوي 1250 دولار ,,

يعني النتيجة تكون هكذا :


ENAME SAL

---------- ----------

SMITH 800

WARD 1250

MARTIN 1250

ADAMS 1100

JAMES 950
























ماهي الجملة ؟


فكر ....

الحل :



select ename,sal

from emp

where sal <= 1250 ;



- مثال :
اريد عرض اسماء ورواتب الموظفين الذين لهم رواتب اكبر من او تساوي 1250 واصغر من او تساوي 3000

؟؟؟ كيف هذه ؟

ستعرف لها طريقين .. تذكرها جيدا .... احد هذه الطرق ... تجده في معاملات جملة الشرط where الاخرى ,





















ثانيا : معاملات اخرى لجملة الشرط where














عرفنا المقارنة ..



الان تعرف بعض المعاملات الاخرى والتي يجب ان نتعمق فيها جيدا ..



1) المعامل Between






اذا كنت تشكو من اللغة الانجليزية مثلي .. فـكلمة "between" معناها "بين"


- مثال :

اريد عرض اسماء ورواتب الموظفين الذين لهم رواتب اكبر من او تساوي 1250 واصغر من او تساوي 3000

؟؟؟ كيف هذه ؟

اليك الجملة :


select ename , sal from emp

where sal between 1250 and 3000 ;















ومعنى الجملة السابقة ..


اعرض لي اسماء ورواتب .. الموظفين والذين رواتبهم ... مابين 1250 و 3000 دولار ,,













هل لاحظت تركيب المعامل between ؟؟ وهل لاحظت زيادة كلمة 'and' ؟


انا متأكد انك ذكي .. ولاحظت ان معنى الجملة السابقة ... مايلي :







اعرض لي اسماء ورواتب .. الموظفين والذين رواتبهم ...اكبر من او تساوي 1250 و اقل من او تساوي 3000 دولار ,,






ممممم ,,,,

انا شخصيا لم اكتفي .. اريد تجربة شيء ...

لو قلبنا القيمة الصغرى مع القيمة الكبرى ؟؟ يعني كتبنا الجملة كما يلي :


select ename , sal from emp

where sal between 3000 and 1250 ;












لاحظ انني بدأت بالكبير ثم الصغير ... هل تتوقع ان المعامل between ذكي ؟؟ ام لا ؟؟


ستكون النتيجة ..





no rows selected


... كما توقعت ... هذا المعامل غبي جدا .... يجب ان تبدأ من الصغير الى الكبير ..
لو وضعنا .... مابين 3000 .. و 3000 ؟؟؟


select ename , sal from emp

where sal between 3000 and 3000 ;















لقد جربت .. ونجح المعامل .... أي عرض لي من لهم رواتب 3000 دولار ,,




ENAME SAL

---------- ----------

SCOTT 3000

FORD 3000



جميل جدا ... معامل بسيط ... ولا داعي لشرحه اكثر من هذا ,,












2) المعامل IN








لماذا هذا المعامل ؟


لـ .... ممممم ... اعطيك مثال ,,

لو طلبت منك ان تعرض لي من رواتبهم 1100 ... و 1250 ... و 3000 ... فقط ..

مالذي تعمله ؟؟

هل تستطيع بالمعامل between ؟؟ لماذا ؟

طبعا لا .. لا تستطيع ..

لانه وبكل بساطة هنا اكثر من قيمتين .. هذا سبب ..







اسمع احدكم يقول لي ... طيب .... سوف اعرض من رواتبهم ما بين 1100 و 3000


واقول له ... برافو يا ذكي ...

غغغغغغغغغغلطططططططططططط !! ... مع مرتبة الشرف ,,,,







يوجد سبب.. ماهو ؟؟ فكر قليلا ...








...


..

.







فكرت ؟؟ لا اعتقد .... نكمل ,,,


انا اخبرك ... لو كتبنا هذه الجملة ..


select ename , sal from emp

where sal between 1100 and 3000 ;


انظر النتيجة ...


ENAME SAL

---------- ----------

ALLEN 1600

WARD 1250

JONES 2975

MARTIN 1250

BLAKE 2850

CLARK 2450

SCOTT 3000

TURNER 1500

ADAMS 1100

FORD 3000

MILLER 1300















لا تعليق !!!


لن اشرحها ...






اذن .... لاحظنا المشكلة السابقة ...


انا اريد فقط ثلاث قيم ... اريد من هم رواتبهم تساوي ... 1100 او 1250 او 3000 دولار ..

لا اريد غيرهم ... هل استطيع بالمعامل between ؟؟ لا طبعا ..

اليك الحل :


select ename , sal from emp

where sal in (1100,1250,3000) ;















وهذه النتيجة ..






ENAME SAL

---------- ----------

WARD 1250

MARTIN 1250

SCOTT 3000

ADAMS 1100

FORD 3000












هل لاحظت المعامل IN ؟؟؟


الان سوف اخبرك سرا .... اريدك ان تتذكره جيدا .. سوف اذكرك فيما بعد ...

هل قلت في السوال " اريد عرض الذين رواتبهم تساوي 1100 او 1250 او 3000 "




أو قلت "اريد عرض الذين رواتبهم تساوي 1100 و 1250 و 3000" ؟؟


ركز .. هناك فرق بين "و" ... وبين "أو"

ركز جيدا ... هل من المعقول ان نقول .. 1100 و 1250 و 3000 ؟؟

بالله عليك .. قلي أي موظف على مر العصور ... من عصر المكاتب والشركات الحجرية .. الى عصر المكاتب والشركات الحديثة ... هل يوجد موظف من الممكن ان يكون راتبه 1250 .. و 3000 .. و 1100 في نفس الوقت ؟؟؟

بالله كيف تجي ؟؟ لا عقل يقبل .. ولا منطق ,,

طيب ... الموظف احمد من الممكن ان يكون راتبه 1250 او 3000 او 1100 .... بالعقل تفهم ان الجملة صحيحة .... ممكن 1100 ... أو ......... 3000 ؟؟ أو 1250 ؟؟؟؟







يعني معقولة ومنطقية ,,,

















طيب ..


- اريد ان اعرض رواتب وأسماء و أرقام كل من اسمه سميث أو كنق أو سكوت ...

ماهي الجملة ؟؟

بسيطة ... تستطيع ذلك ,,







....


...

..

.







هذه الجملة ..








select empno , ename , sal from emp

where ename in ('KING' , 'SMITH' , 'SCOTT' ) ;




انتهينا ..
لن اعرض النتائج ,,
ولكن ...
سوف نتطرق الى المعاملات االاخرى ...
توقع ان الدرس السابع .... من اصعب الدروس التي ستواجهك ...
وسوف اضع كل طاقاتي فيه .. لكي تفهمه ان شاء الله
وسوف تتعلم فيه كل شيء ... عن هذه اللغة ..
يوجد احتمال انني سوف اضع الدرس الثامن ايضا عن لغة الـSQL
ترقبو .. وحلو التحدي ,,,
الى اللقاء ,,,

The Coder
24-12-2005, 01:16 PM
بسم الله الرحمن الرحيم



الدرس السابع








اسم الدرس :جملة الاستعلام select ومعاملات الجملة الشرطية (الجزء الثاني)

نوع الدرس : تطبيقي

صعوبة الدرس : *** من *****

اهميــة الدرس : ****** من ***** (Over)






درجة احتراف لغة الـ SQL المتوقعة بعد هذا الدرس : * من ***** (مبتدئ)



الوقت المتوقع منك لفهم الدرس : 10 ساعة (ساعتين فهم و 8 ساعات تطبيق )

متطلبات تتوفر فيك : التطبيق



























المتوقع منك في هذا الدرس :



- اتقان جزء من هذه اللغة 100 % .












- معرفة جميع معاملات الجملة الشرطية Where .



- تقوية منطقك .












هيا لنؤركل ^^



السلام عليكم ,,






اخذنا معاملات جملة الشرط where في الدرس السابق ,,

واريد ان اوضح مسألتين مهمتين جدا جدا جدا !! نسيت ذكرهما في الدرس السابق

الأولى :

لما قلنا جملة الاستعلام التالية :







select * from emp

where ename='KING' ;







سوف يعرض لي بيانات الموظف KING




لو هناك موظف اخر يدعى بـ King فهل ستعرض بياناته ؟؟ طبعا لا .... لان البيانات الموجودة في الجدول ثابتة الشكل كما عرفت من قبل ..
يعني بإلإمكان ان يكون هناك الموظفين التاليين :




KING , King,KiNg,KiNG,KinG , KINg,KInG,KIng
kING , king,kiNg,kiNG,kinG , kINg,kInG,kIng




هل شاهدت انه نفس الحروف ولكن تتغير حالة الاحرف من احرف كبيرة واحرف صغيرة ؟؟انت تعرف انه موظف واحد ويدعى بـ كنق ... لا يهم .. حروف كبيرة حروف صغيرة ..
ولكن الحاسب الذي يعتقد معظم البشر انه اذكى من البشر ... لن يكتشف هذا الشيء ..
ذلك الشيء الغبي (الحاسب) .. لا يعرف ان يفرق ... بينهم .. سوف يعتبرهم 16 موظف مختلف عن الاخر ..
لو اردت البحث عن KING وكتبت king فسوف تعرض بيانات king وليس KING الذي انت اردته !!
سوف نتطرق إن شاء الله لطرق كثيرة ومحددة لذاك الشيء الغبي ... كي يفهم ما نريده تماما ..

الثانية :
قلنا انه توجد معاملات المقارنة ... ومعاملات اخرى ,,
انا اخطأت في قولي اننا سوف ندرس معاملات جملة الشرط where



وقلت انها من جهتين فقط ... جهة عمليات او معاملات المقارنة ...
ومعاملات اخرى ..
والحقيقة انه يوجد عمليات ثالثة مهمة جدا ..وهي العمليات المنطقية !!

المعاملات الاخرى التي غطيناها هي ..


- المعامل Between



- المعامل IN





اخر امر وضعناه هو :









select empno , ename , sal from emp

where ename in ('KING' , 'SMITH' , 'SCOTT' ) ;








والناتج كان :


















EMPNO ENAME SAL



------ ---------- ----------


7369 SMITH 800

7788 SCOTT 3000

7839 KING 5000







اعرف ان العرض سيء .. ولكن .. افهموها >< .....

The Coder
24-12-2005, 01:30 PM
الان اليك المعامل الثالث :
3) المعامل LIKE

وكالعادة ... الذي يجد صعوبة في لغة الانجليزي (مثلي طبعا ^^) فكلمة like تعني ... "تشبه" او تعني ..."مثل"
This Man is Like Me
ومعنى الجملة السابقة .. هذا الرجل يشبهني ... او هذا الرجل مثلي ,,
خلينا نتفلسف قليلا ...
طبعا الشبه ليس مثل نفس ... يعني هذا الرجل يشبهني .. وهو مثلي .. ولكنه ليس انا .. اذ انه يشبهني جزئيا وليس كليا ....
اعتقد انها وصلت ,,
المهم المهم
هذا المعامل خاص بالنصوص والتواريخ ... تواريخ ؟؟ لم نتطرق الى التواريخ ..
سوف اخصص درس كامل عن التواريخ ... لا تقلق ,,
اشير الى ان التواريخ تشبه النصوص ..... قليلا ^^
أي ان :
The dates is like the text
اوكيه .. ملينا من درس الانجليزي ...
نبدأ في الدرس الاساسي ^^
اريد منك حفظ هذان الرمزان ... ولا تسألني لماذا .. الان احفظهما عن ظهر قلب ,
العلامة %
من منا لا يعرف العلامة الخاصة بالنسبة المئوية ؟؟؟... ومعناها هنا صفر حرف او اكثر ... بمعنى اخر .. ممكن ان تكون ولا حرف .. وممكن ان تكون حرف .. حرفين .... مليون حرف ... يعني أي عدد من الاحرف.. حتى الصفر ,,
العلامة _
وهي العلامة الشرطة التحتية .. هل عرفتها ,,
معناه حرف واحد فقط .... ليس حرفين ولا ثلاثة .. بل حرف واحد فقط ...

بينما كنت تتمتع باحلام اليقظة في مكتبك ....
جاءك احدهم وقال لك .. اريد ان اعرف كم موظف لدينا اسمه يبدأ بحرف الS
مالعمل ؟؟؟
جاءك اخر .. وقال اريد كل الموظفين الذين أسمائهم مكونة من أربعة أحرف ...
مالحل ؟؟
جاءك ثالث .. وقال اريد ان اعرف الموظفين الذين يوجد حرفين t في اسمه
مالذي يجب فعله ؟؟
جاءك رابع ... وقال اريد ان اعرف اسماء الموظفين والتي حرفها الثاني M
ماذا تفعل ؟؟
جاءك الذي ارسل الاربعة السابقين (المدير)لتعجيزك .. واراد منك كل الموظفين الذين توظفوا في الشركة في اليوم الثالث من أي شهر ,,
مالذي سوف تستخدمه ؟؟
اليك بعض الحلول والامثلة للمعامل like ,,
- اريد اسماء الموظفين والتي تبدأ بحرف الـ S


select ename from emp
where ename like 'S%' ;


والناتج هو اسماء الموظفين والتي تبدأ بحرف الـ S



ENAME
------
SMITH
SCOTT


هل شاهدت المعامل like ؟؟
كأنه يساوي . ولكنه ليس كاليساوي ...
يقول اعرض اسماء الموظفين الذين اسمائهم كأنها على الشكل التالي :
اول حرف هو S ... وثاني الحروف (وهي العلامة %) هو ... أي حرف واي عدد من الاحرف ... حتى لو لم يكن هناك احرف
انتبه ... ركز ....
لو كان هناك موظف اسمه S ,,, وكتبنا الكود السابق ... هل يعرضه ؟؟ ام لا ؟؟
طبعا سوف يعرضه .. لانه اول حرف من اسمه هو الـS وبعدها صفر حرف .. هل فهمت ؟؟

طيب لو كان هناك موظف اسمه OSAMA هل تعتقد انه سوف يعرضه ؟؟
طبعا لا .. ليييييش ؟؟؟؟
لان حرف الـS ثاني حرف وليس اول حرف ...

طيب اليك هذا الامر ... واخبرني مالناتج ؟؟




select * from emp
where ename like 's%' ;


مالناتج ؟؟
ولماذا ؟؟
صح ,, الناتج هو نفس الناتج السابق ^^ .,,,
سوف يعرض هذه النتيجة .. ^^



ENAME
------
SMITH
SCOTT


بالله عليك .. هل s هي نفسها S ؟؟؟
قلنا اعرض اسماء الاشخاص التي تبدأ بحرف الـ s وليس الـ S !!
يعني اذا كان الامر السابق /



select * from emp
where ename like 's%' ;


فالنتيجة تقول ...


no rows selected


لانه لا يوجد احد يبدأ اسمه بحرف الـ s (small s not capital S!!)

يعني ان النتيجة :



ENAME
------
SMITH
SCOTT

خاطئة ...
يجب التنبه على حالة الاحرف !
يجب ان تتنبه جيدا لهذا الامر !!

الان نريد ان نعرف اسماء الموظفين والتي حرفها الثاني M

اليك الامر ...



select ename from emp
where ename like '_M%' ;


والناتج هو اسماء الموظفين التي ثاني حرف فيها هو الحرف M


ENAME
-------
SMITH


ظهرت لنا هذه العلامة _ (الناقص التحتية )
ومعناها أي حرف لكنه حرف واحد فقط ...
ما معنى الامر السابق ؟؟
معناه اعرض لي اسماء الموظفين من جدول الموطفين ...
والذين اسمائهم تشبه مايلي :
أي حرف .. ثم حرف الـ M .... ثم أي عدد من الحروف .. ايا كانت هذه الحروف ,,

الان نحل مسألة المدير ....
ولكن اولا .. هل تعرف تركيبة الشهر في هذا الجدول ؟؟
لو ادخلنا الامر التالي ...


select hiredate from emp ;


فسوف يكون الناتج .... مايلي :



HIREDATE
--------
17/12/80
20/02/81
22/02/81
02/04/81
28/09/81
01/05/81
09/06/81
19/04/87
17/11/81
08/09/81
23/05/87
03/12/81
03/12/81
23/01/82


هل شاهدت تركيب التاريخ في الجدول ... غريبة !!
خانتين يوم / خانتين شهر/خانتين سنة
مثلا
23/01/82
أي انه توظف في يوم 23 .. شهر واحد في السنة 1982
تم تجاهل الـ 19 .....
الان اراد منك المدير كل الموظفين الذين توظفوا في الشركة في اليوم الثالث من أي شهر ومن أي سنة .. لا يهم الشهر ولا السنة .. المهم هو اليوم ,,
اليوم الثالث ... يعني بهذا الشكل .. "03" وليس "3" فقط !!
انتبه جيدا لهذا الشكل ...
يعني
03/؟؟/؟؟
ممممم ... كيف نكتبها هذه ؟؟
نجرب ..


select ename , hiredate from emp
where hiredate like '03%' ;


و النتيجة هي كل الموظفين الذين توظفوا في اليوم الثالث .. من أي شهر .. ومن أي سنة :



ENAME HIREDATE
---------- --------
JAMES 03/12/81
FORD 03/12/81


اريد الان كل الموظفين الذين اسمائهم مكونة من اربعة احرف مالعمل ؟؟...
هذه العلامة _ .... للحرف الواحد .. ايا كان هذا الحرف ...
طيب .. هذه العلامتين __ ... معناه حرفين اثنين .. ايا كانا هذان الحرفان ,,
اليك الامر يا فتى ...


select ename from emp
where ename like '____' ;


مع مراعاة انها اربع علامات خطوط تحتية هكذا ____
والنتيجة هي اسماء كل الموظفين التي تحتوي على اربع احرف ..


ENAME
-----
WARD
KING
FORD


الآن أريد عرض كل أسماء الموظفين التي تحتوي على حرف الـ T مرتين .. يعني لو أن احدهم يدعى بـ SCOTT فسوف يعرض ... فهو اسم يحتوي على الحرف T مرتين ..
ولو ان احدهم يدعى TRRRRRRRRT فسوف يعرض أيضا لأنه يحتوي على الحرف T مرتين وهكذا ,,,,,,
ممممم ... انا اعتمدت طريقة الاحتمالات في تدريسك الدورة ....
يعني باختصار أنت لا تفكر ... سوف أجعلك تواجه هذه المشكلة .. أتحداك ان تحلها ... وهذا هو التحدي الاول ,,
...
ذاهب وراجع ^^

The Coder
24-12-2005, 01:37 PM
4) المعامل الاخير في المعاملات الاخرى ..الخاصة بجملة الشرط .. وهو المعامل IS NULL


هل تذكر الحقل comm. ؟؟

وهو الخاص بالرواتب الإضافية ...اعرف إني أقلقتك بهالحقل .... بس التذكير جميل ^^

بعض الموظفين ليس لديهم رواتب اضافية .. لذا وضعنا القيمة NULL صح ؟

طيب ... اريد ان اعرض اسماء كل الموظفين الذين لا يملكون رواتب اضافية ... كيف ؟

بهذا الامر ..





select ename from emp

where comm =NULL ;




صح ؟

صح ^^ ... اذن النتيجة هي ...





no rows selected




اوبس ...

لا احد ؟؟

يعني كلهم يأخذون رواتب اضافية ؟ مستحيل ...

اكيد الامر السابق خطأ ...

مالعمل ؟مالحل؟؟؟

انه المعامل IS NULL


يقول لك خطأ ياسيدي ان تقول comm=null


عملية المساواة مع الـقيمة الخالية مستحيلة ..

وشيء اكيد عمليات "اكبر من" و "اصغر من" و "اكبر من او تساوي "... و "اصغر من او تساوي "... "ولا تساوي "

هي ايضا لا تعمل مع القيمة الخالية null


هل ما زلت تريد عرض جميع من ليس لديهم رواتب اضافية .؟؟ طيـــــــــــــــب ... الحل هو :









select ename from emp

where comm is null ;




والنتيجة









ENAME

-------

SMITH

JONES

BLAKE

CLARK

SCOTT

KING

ADAMS

JAMES

FORD

MILLER




هؤلاء هم الذين لا يملكون رواتب اضافية ,,

اذا لم تصدق ,, تأكد بنفسك وسوف تجدهم هم ^^

بسيط صح ^^ ؟؟

سوف اصعب عليك واعقد الموضوع اكثر .... لاني بكل بساطة ^^ ..... سادي في هذه الامور ,,





ثالثا : المعاملات المنطقية ...


- المنطق :

مالمنطق ؟؟

اهم موضوع في البرمجة اعتبره المنطق ... اليك درس قواعد ^^


احب ان احذرك ... ان السطور القادمة مملة مملة مملة لدرجة الموت ... لذا ...

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

واذا لم تقرأها ... فأنت حر .. وحتفوت عليك فرصة ^^

المشكلة انك اذا قرأتها لا تعرف هل تحسنت ام لا ...

فلا تستغرب اذا انتهيت منها .. انك تقول في نفسك ... "لقد كذب علي حمزة وقال انني سوف اتحسن .. لم اتحسن"

انا اقول لك وبكل ثقة .. سوف تتحسن كثيــــــــــــــرا (لاحظ كثيرا )

اليك الدرس :

ذهب احمد و محمد الى السوق ...

لن اعرب الجملة السابقة ولكن .. اريد تحليلها منطقيا ...

اولا .... مين ذهب ؟؟ احمد + محمد صح ؟؟ يعني احمد و محمد ذهبا ,,

هل ذهب احمد ولم يذهب محمد ؟؟ لا

هل لم يذهب احمد وذهب محمد ؟؟ لا

هل لم يذهب محمد ولم يذهب احمد ؟؟ لا

هل ذهب احمد وذهب محمد ؟؟ نعــــــــم




طيب ما رأيك في الجملة التالية ؟؟

ذهب احمد او محمد الى السوق ....

ممم

من الذي ذهب ؟؟ يا احمد ؟؟ او محمد ؟؟ لا احد يعرف ...

كل ما نعرفه ان حمزة قال لنا "احمد او محمد ... ذهب احدهما او كلاهما السوق ..."

كأن حمزة هذا .. لايعرف أي منهما ذهب .. ولكن هو متأكد انه ذهب احدهما او كلاهما !

هل ذهب احمد وذهب محمد الى السوق ؟؟ نعم

هل ذهب احمد ولم يذهب محمد الى السوق ؟؟ نعم

هل لم يذهب احمد وذهب محمد الى السوق ؟؟ نعم

هل لم يذهب احمد ولم يذهب محمد الى السوق ؟؟ لا .... مستحيل .. يعني مين راح ؟؟ الجني الأزرق ؟؟؟





لاحظنا في الجملتين الاثنتين .. اختلاف بسيط وهو .. "و" ... "او"

اذا لم تفهم المغزى ... فتابع .,,


اولا ... ( و ):

تخيل لو فيه اختبار من سؤالين ... وضعهما لك رجل معقد يدعى حمزة ... لن ينجحك الا اذا حللت السؤالين الاثنين بشكل صحيح ... يعني كأن حمزة هذا يقول ...

اذا حللت السؤال الأول صح .. و (لاحظ الحرف و).... حللت السؤال الثاني صح ... فسوف تنجح ... وتكون إنسان صحيح

طيب نأتي للاحتمالات التي من الممكن ان تقع انت فيها

السؤال الاول صحيح و السؤال الثاني صحيح ... أنت صحيح

السؤال الاول صحيح و السؤال الثاني خاطئ .. أنت خاطئ

السؤال الاول خاطئ و السؤال الثاني صحيح .. أنت خاطئ

السؤال الاول خاطئ و السؤال الثاني خاطئ .. أنت خاطئ


الملخص هو ...

صح و صح .. صح

صح و خطأ .. خطأ

خطأ وصح .. خطأ

خطأ وخطأ .. خطأ





يا سلام ... على المنطق الرائع .. هل تصدق ان منطقك الان قوي جدا وسليم ؟؟ اعرف ان هذه الحقائق موجودة في رأسك .. لكن بعضكم لم يعلم عن وجودها .. وأولكم محدثكم (انا ^^" )









ثانيا ( أو ) :

تخيل لو فيه اختبار من سؤالين ... وضعهما لك رجل لين ... طيب .. حنون ... يقبل بأي اجابة صحيحة ... لكنه لا يدعى حمزة ... ينجحك اذا حللت احد السؤالين الاثنين بشكل صحيح (السوال الاول او السوال الثاني ... احد السوالين )... يعني كأن الذي ليس اسمه حمزة يقول ...

اذا حللت السؤال الأول صح .. أو (لاحظ الحرف و).... حللت السؤال الثاني صح ... فسوف تنجح ... وتكون إنسان صحيح

طيب نأتي للاحتمالات التي من الممكن ان تقع أنت فيها في هذا الاختبار

السؤال الاول صحيح أو السؤال الثاني صحيح ... أنت صحيح (لاحظ انها أو وليست و)

السؤال الاول صحيح أو السؤال الثاني خاطئ .. أنت صحيح


السؤال الاول خاطئ أو السؤال الثاني صحيح .. أنت صحيح


السؤال الاول خاطئ أو السؤال الثاني خاطئ .. أنت خاطئ .. وللأسف (لاحظ وللأسف ..شفت كيف الليونة ؟)

الملخص هو ...


صح أو صح .. صح (لاحظ انها أو وليست و)

صح أو خطأ .. صح


خطأ أو صح .. صح


خطأ أو خطأ .. خطأ





يا سلام ... على المنطق الرائع الان منطقك 90% سليم ...

لا تسألني اين الـ 10% المتبقية ...

لانها من الصعب جدا الحصول عليها ...

اذا اردت الحصول عليها فركز جيــــــــــــدا ..


هناك شيء يدعى النفي .. يعني عكس الشيء ..

يلعب .. نفيها لا يلعب

جوع .. نفيها لا جوع ...

جوع ... نفيها ايضا الشبع ...

الآن تخيل اختبار غريب جدا ...

من مختبر ومعلم غريب جدا ..

يدعى بحمزة ..

يقول لك هذا الغريب ..

اذا حللت السؤال الاول ولم تحل السؤال الثاني ... فانت ناجح .. يعني انت صحيح !!!


غريب ؟؟ هل لاحظت "لم" ؟؟؟ هل لاحظت حرف الواو ... في "و لم تحل السؤال الثاني" ؟؟؟

ركز!! .... هنا يوجد نفي ... يعني لا تحل السؤال الثاني ...

انت سوف تقع في هذه الاحتمالات ...

السؤال الاول صحيح و السؤال الثاني صحيح ... أنت خاطئ !!!

السؤال الاول صحيح و السؤال الثاني خاطئ .. أنت صحيح !!!

السؤال الاول خاطئ و السؤال الثاني صحيح .. أنت خاطئ

السؤال الاول خاطئ و السؤال الثاني خاطئ .. أنت خاطئ

واو ... معقد بعض الشيء هاه ؟؟

اليك الاحتمالات بشكلها المحسن ..

اذا السؤال الاول الذي يجيب ان يكون صحيح حليته صح و السؤال الثاني الذي يجيب ان يكون خاطيء حليته صح ... أنت خاطئ !!!

اذا السؤال الاول الذي يجيب ان يكون صحيح حليته صح و السؤال الثاني الذي يجيب ان يكون خاطيء حليته خطأ ... أنت صحيح !!!

اذا السؤال الاول الذي يجيب ان يكون صحيح حليته خطأ و السؤال الثاني الذي يجيب ان يكون خاطيء حليته صح ... أنت خاطئ !!!

اذا السؤال الاول الذي يجيب ان يكون صحيح حليته خطأ و السؤال الثاني الذي يجيب ان يكون خاطيء حليته صح ... أنت خاطئ !!!

اليك الاحتمالات بشكل ملخص .. لكي تتفهم الوضع سريعا





صح و صح الخطأ .. خطأ

صح و خطأ الخطأ .. صح

خطأ و صح الخطأ .. خطأ

خطأ و خطأ الخطأ .. خطأ

واو .. المسئلة تعقدت اكثر واكثر للبعض .. وصارت بسيطة للبعض الاخر

نفس المنوال مع أو .. ولكن بهذه النتائج :

صح أو صح الخطأ .. صح

صح أو خطأ الخطأ .. صح

خطأ أو صح الخطأ .. خطأ


خطأ أو خطأ الخطأ .. صح





... لا تنتف شعرك يا هذا .. ولا تتعقد ... قلت لك انها صعبة .. قليلا .. وممكن ان تكون كثيرا ...

ركز واقرأ ثانية ..,,,




اذا لم تعرف بالمرة.. او انك طفشت ولا تريد ان تفهم ..


سوف تفهمها فيما بعد ... لا تخف .. سوف اجد الطريقة التي تناسبك ان شاء الله ,,

الان ..

عرفنا "و" ..."أو" ... واخيرا النفي .. اذا لم تفهمها احفظها الان .... اليك تلخصيها ...





الـ "و"

صح و صح = صح

صح و خطأ = خطأ

خطأ وصح = خطأ

خطأ وخطأ = خطأ





الـ"أو"

صح أو صح = صح

صح أو خطأ = صح

خطأ أو صح = صح

خطأ أو خطأ = خطأ





الـنفي

نفي الصح = خطأ

نفي الخطأ = صح





اشير الى نقطة مهمة جدا جدا جدا ... من الممكن ان تكون اكثر من قيمتين فمثلا ...

صح أو صح = صح

طيب ..

صح أو صح أو صح = صح ....

صح أو خطأ أو خطأ = صح ...

يعني في النهاية نستنتج ان الـ "أو" ... يجب ان يكون فيها على الاقل .. قيمة واحدة صحيحة لكي تكون صحيحة.


طيب ...

صح و صح و صح = صح ...

صح و صح و خطأ = خطأ ...

يعني في النهاية نستنتج ان الـ "و" ... يجب ان يكون فيها على الاقل .. قيمة واحدة خاطئة لكي تكون خاطئة .

طيب ...

نفي نفي الصح = صح

نفي نفي الخطأ = خطأ

نفي نفي نفي الصح = خطأ

اعرف الآن انك تقول دعك من الفلسفة الزائدة .. ولكن ,,, اليك تحدي ...


صح و صح و صح و صح و خطأ = ؟؟؟

خطأ أو صح أو خطأ أو صح = ؟؟؟

نفي نفي نفي نفي نفي الخطأ = ؟؟؟





وهو التحدي الثاني ,,,





لنكمل المعاملات ,,

The Coder
24-12-2005, 01:42 PM
1) المعامل المنطقي AND


للمتعسر في فهم الانجليزي .. مثلي ...


And معناها "و"

نريد عرض اسماء ورواتب الموظفين الذين راتبهم فوق الـ 1000 دولار .. و لا يملكون راتب اضافي ..

لاحظ "و"

اليك الحل ...





select ename,sal from emp

where sal>1000 and comm is null ;






ياسلام .. هل شاهدت كيف تعمل and ؟؟





اليك النتيجة .. وهي اسماء ورواتب الذين يأخذون راتب اكثر من 1000 دولار .. و لا يملكون راتب اضافي :





ENAME SAL

---------- ----------

JONES 2975

BLAKE 2850

CLARK 2450

SCOTT 3000

KING 5000

ADAMS 1100

FORD 3000

MILLER 1300




لماذا النتيجة هذه ؟؟

لا اريد ان أخبرك الآن ... اريدك ان تقول لنفسك لماذا ؟؟WHY ؟؟ ليش ؟؟

اريد ان اعقد الامور اكثر ... وأقول ..


اريد ان اعرض اسماء ورواتب الموظفين الذين راتبهم فوق الـ1000 دولار .. و لا يملكون راتب اضافي .. والذين أسمائهم أربع حروف فقط ...







select ename,sal from emp

where sal>1000

and comm is null

and ename like'____' ;






واو ... لاحظ كم and أضفناها ... وكأننا نقول

اعرض الحقول اسماء ورواتب من جدول الموظفين

اذا كان الراتب اكبر من 1000

و الراتب الإضافي قيمة خالية

والاسم مكون من اربع احرف

استخدمنا بعض المعاملات الاخرى في هذا الامر ... رائع ..

سوف يعرض لي اسماء ورواتب كل من اسمه مكون من اربع احرف ويأخذ فوق 1000 دولار ولا يملك راتب اضافي :







ENAME SAL

---------- ----------

KING 5000

FORD 3000




لماذا هذه النتيجة ؟؟


KING رجل عملي .. ويحب الحياة ... ولكنه يكره التخاذل في العمل ,,

لاحظ ان اسمه مكون من 4 احرف .. في نفس الوقت .. راتبه اكثر من 1000 ... في نفس الوقت راتبه الإضافي فارغ أي لا يملك راتب اضافي ,,

يا سلام ...

نفس الشيء مع فورد FORD




هنالك موظف مسكين .. يدعى SCOTT يتقاضى راتب 3000 دولار و لا يملك راتب إضافي , رجال طيب وفيه خير ..

لم يعرض اسمه هنا لماذا ؟


لأننا قلنا راتب فوق 1000 و (لاحظ الـ "و") راتبه الإضافي قيمة خالية و اسمه مكون من أربع أحرف

سكوت راتبه فوق 1000 (صحيح) و راتبه الإضافي خالي (صحيح) و لكن اسمه ليس من اربع احرف (خاطئ)

اذن ...

صحيح و صحيح و خاطئ = خاطئ ,,


إذن من الخطأ عرضه ...

اذا لم تفهم .. اليك مثال اخر ...

اذا كتبنا الامر التالي وهو عرض اسماء الموظفين الذين رواتبهم اقل من 1600 :






select ename from emp

where sal < 1600 ;






فسيكون الناتج







ENAME

-------

SMITH

WARD

MARTIN

TURNER

ADAMS

JAMES

MILLER






امر الخاص بعرض اسماء الموظفين الذين يملكون راتب اضافي ....





select ename from emp

where comm is not null ;






وهم ...







ENAME

-------

ALLEN

WARD

MARTIN

TURNER






انظر الصورة 17


http://img6.picsplace.to/img6/10/17.jpg



في الصورة ...

تخيل أن المربع الأيمن هو الشرط الخاص بمن هم رواتبهم اقل من 1600

والمربع الأيسر هو شرط من يملكون رواتب إضافية ,,




لو قلنا إننا نريد عرض أسماء الذين رواتبهم اقل من 1600 ويملكون رواتب إضافية ..


بالله عليك ... ركز في الصورة السابقة ... من في الموظفين الذي راتبه اقل من 1600 وفي نفس الوقت لديه راتب إضافي ؟؟

من من الموظفين تتوفر فيه الشرطين الاثنين في نفس الوقت ؟؟

هل تريد الحل ؟؟

اليك الامر .. التالي والذي يقول .. اعرض الموظفين الذين رواتبهم اقل من 1600 و لديهم راتب اضافي :





select ename from emp

where comm is not null

and sal <1600 ;






هذا هو الناتج ...





ENAME

-------

WARD

MARTIN

TURNER






اذا لم تفهم لماذا الناتج هذا ,, انظر الصورة 27



http://img6.picsplace.to/img6/10/27.jpg






هل تشاهد اين تقاطع الشرطين ؟؟ انا اقصد بالتقاطع يعني .. التشابه ... الشرطين متشابهين في ثلاث موظفين ..

هل عرفت الان فكرة and ؟؟

وهي ناتج تقاطع الشروط ... يعني هنا شرطين ... تقاطعهما يعني بينهما and






2) المعامل المنطقي OR


اذا كنت متعقد من الانجليزية .. مثلي فإن OR تعني "أو"

الان اريد عرض اسماء كل الذين راتبهم اصغر من 1600 ... أو عرض من لديهم راتب اضافي ...

من الصورة السابقة 17 .... ستشاهد الشرط الاول من هم .. والشرط الثاني من هم ...

اليك الامر الذي يبين كل اسماء من هم اصغر من 1600 أو من لديهم رواتب اضافية :







select ename from emp

where comm is not null

or sal <1600 ;






النتيجة هم ....





ENAME

-------

SMITH

ALLEN

WARD

MARTIN

TURNER

ADAMS

JAMES

MILLER




اذا قلنا ان الـ and هي ناتج تقاطع الشروط ... فما رأيك في الـ or ؟؟

هو جمع النواتج جميعها بدون تكرار ... هل فهمت ؟ لم تفهم ؟؟ اذن انظر الصورة 37



http://img6.picsplace.to/img6/10/37_000.jpg



هل تشاهد جميع الاسماء ؟؟

اجمعهم جميعا ... والغي أي تكرار .. فسوف تحصل على ناتج الشرط ,, وهذا معنى OR الحقيقي ,,, كأنه الجمع ...

نعقد المسئلة .. قليلا ..

اريد عرض اسماء ورواتب كل من رواتبهم فوق الـ 3000 دولار .. أو .. عرض اسماء ورواتب كل من لا يملكون راتب اضافي أو أسمائهم مكونة من اربع احرف ..


اليك جملة الاستعلام التالية :






select ename,sal from emp

where sal>3000

or comm is null

or ename like '____' ;






وهذه هي النتيجة :







ENAME SAL

---------- ----------

SMITH 800

WARD 1250

JONES 2975

BLAKE 2850

CLARK 2450

SCOTT 3000

KING 5000

ADAMS 1100

JAMES 950

FORD 3000

MILLER 1300






لا تحتاج لعقل مدمر حتى تفهم مالذي حدث .. صح ؟

اذا لم تفهم لماذا عرضت هذه النتيجة .. افهم الآن جيــــدا ...

أولا ... اسأل نفسك ما معنى أن نعرض من هم ذو راتب اكثر من 3000 أو لا يملكون اضافي أو حروف اسمائهم 4 حروف ؟

طبعا الجواب هو عرض أي شخص فيه الخصائص الثلاث جميعها .. او خاصيتين منها .. او خاصية واحدة منها

الموظف الطيب سكوت الذي يتقاضى راتب 3000 دولار ولا يملك راتب اضافي... عرضناه هنا في النتيجة السابقة لماذا ؟

اختل الشرط الاول..... لان راتبه 3000 ... وليس اكثر من 3000

لم يختل الشرط الثاني .. لانه لا يملك راتب اضافي

اختل الشرط الثالث .. لان اسمه من خمس احرف وليس اربع احرف !!

الشرط الاول خاطئ ... الشرط الثاني صحيح .... الشرط الثالث خاطئ

خاطئ أو صحيح أو خاطئ = صحيح ... ممممم الجواب صحيح ؟؟ إذن اعرضه





هناك موظف يدعى TURNER


ويتقاضى راتب 1500 ... ولديه راتب اضافي ..

بالله عليك هل نعرض هذا ؟؟

اختل الشرط الاول فيه ... أي ان راتبه اقل من 3000

اختل الشرط الثاني فيه ... أي انه يملك راتب اضافي ....

اختل الشرط الثالث فيه ... أي ان اسمه ليست اربع احرف .. بل ست احرف ,,,

الشرط الاول خاطئ .. الشرط الثاني خاطئ ... الشرط الثالث خاطئ ..

خاطئ أو خاطئ أو خاطئ = خاطئ ... ممممم الجواب خاطئ ؟؟ اذن لا تعرضه

هل فهمت ؟؟

لا تخجل .. المسألة تلخبط في البداية ... اذا لم تفهم .. راسلني واعرض لي مالذي فهمته و مالذي لم تفهمه ,,

وأنا بكل رحابة صدر .. سوف اشرح لك مرة ومرتين وثلاث .... وألف ,,, لا تخف لن أأكلك ^^


سنعود بعد قليل ,,,

The Coder
24-12-2005, 01:47 PM
الان في رأسي بعض التحديات :

اليك التحدي الثالث :

اريد عرض اسماء ورواتب الموظفين الذين راتبهم اكبر من 1000 واقل من 5000 بدون استخدام Between


التحدي الرابع :

اريد عرض اسماء ورواتب الموظفين الذين اسمائهم KING أو SCOTT أو TIGER بدون استخدام IN


التحدي الخامس :

هل تشاهد الصورة 47 ؟؟ وهي ثلاث شروط ... برأيك مالناتج اذا كان بينهم OR ؟؟ وما الناتج اذا كان بينهم AND


(الصورة 47)



http://img6.picsplace.to/img6/10/47.jpg










قبل ان ابدأ في المعامل الاخير ... للمنطق اريد تذكيرك ببعض الامور .

صح أو خطأ = صح

بالانجليزي تكتب هكذا :


True OR False = True


اوكيه .. اتفقنا !!






3) المعامل المنطقي الاخير NOT :


ضعيف بالانجليزي ؟؟؟ يعني مثلي ...

طيب NOT تعني "لا" وتعني نفي الشيء .. وفي درسنا هذا تعني عكس الشيء .. هل فهمت ؟

هذا المعامل ... غريب بعض الشيء ...

لا يستخدم مباشرة ..بل يجب ان يعمل مع معاملات اخرى وهي اربع معاملات :


المعامل Between


المعامل IN


المعامل IS NULL


المعامل LIKE




نأخذها وحدة وحدة ..





- استخدام not مع المعامل Between


مثال عليها ... نريد عرض رواتب واسماء الموظفين الذين راتبهم ليس (لاحظ ليس) بين الـ 1000 و 3000

اليك الجملة :




select ename,sal from emp

where sal not between 1000 and 3000 ;






والناتج هو كل الموظفين الذين راتبهم فوق الـ3000 وتحت الـ 1000





ENAME SAL

---------- ----------

SMITH 800

KING 5000

JAMES 950






فهمت ؟





- استخدام not مع المعامل IN


اعرض اسماء من هم ليسو(لاحظ كلمة ليسو) في هذه القائمة :


(KING , SCOTT , CLARK , ADAMS)


اليك الأمر (دائما اقصد بالأمر هو جملة الاستعلام ) :




select ename from emp

where ename not in ('KING' , 'SCOTT' , 'ADAMS' , 'CLARK');






واليك النتيجة





ENAME

---------

SMITH

ALLEN

WARD

JONES

MARTIN

BLAKE

TURNER

JAMES

FORD

MILLER








- استخدام not مع المعامل IS NULL


ابسط مثال هو الحقل comm هل تذكره ؟؟ وهو الخاص بالرواتب الاضافية (احب ان اذكر كثيرا ^^.. اعذرني)


اريد عرض اسماء و الرواتب الاضافية الخاصة بكل من هم ليسو من الذين لا يملكون راتب اضافي ...

يعني اريد عرض كل من هم ليس راتبهم الإضافي يساوي null


هل فهمت ؟؟

اليك الامر :





select ename,comm from emp

where comm is not null ;




لاحظ ان عكس is null هي is not null


والنتيجة هي كل من لهم راتب اضافي ,,





ENAME COMM

---------- ----------

ALLEN 300

WARD 500

MARTIN 1400

TURNER 0






- استخدام not مع المعامل LIKE


اعرض لي اسماء الموظفين التي لا تبدأ بحرف الـ S


جملة الاستعلام :





select ename from emp

where ename not like 'S%';




النتيجـــــــــــة :







ENAME

-------

ALLEN

WARD

JONES

MARTIN

BLAKE

CLARK

KING

TURNER

ADAMS

JAMES

FORD

MILLER






انتهينا من المعاملات جميعها ,,

بقي ان أغوص بك في وحل المنطق مرة ثانية .. لأني أريدك أن تكون محترفا , ولأني أريدك ان تكون مبرمجا , ولأني أريدك ان تدعي لي (وليس علي ) اذا واجهت مصائبها فيما بعد ..





الآن ركز جيــــــــدا في المطلوب !! التركيز التركيز ,, ولا شيء غير التركيز ,

اريد عرض اسماء و رواتب أساسية وإضافية للموظفين الذين اسمائهم مكونة من أربع احرف و لديهم رواتب اضافية أو رواتبهم اكبر من 2000 دولار ...




انا في رأيي الشخصي البحت .. والذي اعتقد انه 1000000% صحيح ..... ان السؤال السابق.. غامض .. ولا اعلم مالذي يقصده بالضبط اليك صيغتين :

الصيغة الاولى :

هل يريد الذين اسمائهم مكونة من اربع احرف ولديهم راتب اضافي ؟؟.....

او

الذين راتبهم اكبر من 2000 دولار ؟؟؟





الصيغة الثانية :

هل يريد الذين اسمائهم مكونة من اربع احرف ؟؟

و

لديهم رواتب اضافية او راتبهم اكبر من 2000 دولار ؟؟؟





هل لاحظت لماذا وضعت انا هذه الصيغتين ؟ اذا لم تلاحظ بعد ... فجرب ان تفهم مايلي :

الصيغة الاولى : (اسمائهم أربع حروف) و (لديهم راتب اضافي أو راتبهم اكبر من 2000 دولار )

الصيغة الثانية : (اسمائهم اربع حروف و لديهم راتب اضافي ) أو ( راتبهم اكبر من 2000 دولار )


يعني الصيغة الاولى .. ان تتم عملية الـOR اولا ثم AND


وفي الصيغة الثانية .... ان تتم عملية الـ AND اولا ثم OR


من البلاهة المغولية ان تقول ... "كلاهما نفس المعنى "... اذا كان تفكيرك بهذه الصيغة ... وبدون تفكير عميق ..

أنصحك بالانسحاب من القراءة .. واذهب لاحتراف كرة القدم أفضل لك وتدر عليك أموال أكثر ,,,

اذا لم تفهم بعد مالذي يحدث هنا ... فجرب ان تفهم الان :





هل تذكر الاولويات الحسابية ؟ والتي قلنا انها على هذا الترتيب :

الأقواس

الأسس

الضرب او القسمة

الجمع او الطرح

هل تذكرها ؟؟

هنا توجد اولويات ايضا !! اقصد بالأولويات يعني شيء قبل شيء .....

يعني اولويات حسابية .. وأولويات منطقية !!

الاولويات الحسابية ذكرناها ...

اما الاولويات المنطقية فسوف نكتشفها الان ..

هل AND اولا ثم OR ؟؟

او OR اولا ثم AND ؟؟؟

ام الذي نواجهه اولا .. هو الذي يكون اولا ؟؟ مثل ما شاهدنا في الضرب والقسمة ..

الضرب او القسمة لهما نفس الاولوية .. صح ؟ أي منهما اولا اذا جاءا سوية ؟؟ هل تذكر ؟؟

طبعا الذي يوجهنا اولا ... يكون هو الاول ...

من الممكن ان تكون AND و OR لهما نفس الاولوية , لا نعرف .....

ممممم نجرب ... (لا تلومني .. انا لا اريد أعطيك معلومات جاهزة ... لان المعلومات الساخنة والطازجة تلتهم وتختفي بسرعة... ولأني بنفسي لا اعرف الحل ... وبالتالي دعنا نعيش المشكلة سوية ونوجهها سوية .. )


الان .. انا شخصيا اريد الصيغة الاولى ...


يعني

اريد عرض اسماء الموظفين الذين اسمائهم أربع حروف

و

الذين لديهم راتب اضافي أو راتبهم اكبر من 2000 دولار





بمعنى اخر اريد

اسم مكون من أربع احرف ... و ... احد الأمرين او كلاهما.. 1- يا راتب فوق 2000 او 2- لديه راتب اضافي





لاحظ انني استخدمت الصيغة الاولى .. أي انني اريد ان تتم عملية الـ OR اولا ....

اذن ... نجرب هذا الأمر ...






select ename ,sal,comm from emp

where ename like '____'

and comm is not null or sal >2000 ;






انظر الناتج :







ENAME SAL COMM

---------- ---------- ----------

WARD 1250 500

JONES 2975

BLAKE 2850

CLARK 2450

SCOTT 3000

KING 5000

FORD 3000






لو دققت ...

و تمحصت ..

وركزت ...

وتتبعت ...

و انا اعرف انك لم تعمل أي منها ...

ولكن الذي حدث هو ان and بدأت اولا ....

هل لأنها أتت اولا ؟؟

يمكن !!

نجرب لو وضعنا الـ OR اولا .. مالذي سيحدث ... اليك جملة الاستعلام التالية







select ename ,sal,comm from emp

where sal >2000 or comm is not null

and ename like '____';




سوف تكون نفس النتيجة .. هل تصدق !

لاحظ كيف قلبت الترتيب .. لكي اضمن نفس المفهوم ...

يعني

اريد عرض اسماء الموظفين الذين اسمائهم أربع حروف

و

الذين لديهم راتب اضافي أو راتبهم اكبر من 2000 دولار





هي نفسها





اريد عرض اسماء الموظفين راتبهم اكبر من 2000 دولار أو الذين لديهم راتب اضافي

و

الذين اسمائهم أربع حروف





اذا لم تصدق ... ركز فيها .. واذا لم تفهم بالمرة مالذي حدث ... تجاهل الموضوع ...


قلنا انها نفس النتيجة .. يعني بدأ بالـAND !!


اذن الـAND هي اولا ... ثم الـ OR


طيب فكر لو ... انه يوجد And مرتين .. ايهما اولا .. ؟؟؟

هذا هو التحدي السادس .... التحدي هو ان تشرح لي بمثال .. من عندك .. لو هناك AND و OR و AND ... مالذي سوف يحدث اولا ؟؟ ولماذا ؟؟





قلنا قبل قليل انه الـ AND اولا ثم الـ OR ....


لكن انا اريد الـ OR اولا .. مالعمل ؟؟





يا سيدي ... الاقواس هي الحل ,,

من الان وصاعدا .. تعود ان تضع الاقواس ... بسبب او بدون ’,’,’,’,


اليك الحل .... جملة الاستعلام هي :





select ename ,sal,comm from emp

where (ename like '____' )

and (comm is not null or sal > 2000 ) ;




هل شاهدت الاقواس ؟؟

هل شاهدت اقواس زائدة والتي تضم الجملة (ename like '____' ) ؟؟

بإمكاننا ان ننزعها ... لكن تعود وتمرس الان ان تضعها ... لماذا ؟ لكي تسهل عليك القراءة .. ولكي تفهم المطلوب من الكود .. ولكي تكون مرتاح البال .... ولأني أأمرك بذلك ,,,





والنتيجة هي :





ENAME SAL COMM

---------- ---------- ----------

WARD 1250 500

KING 5000

FORD 3000






هذا ما أردته بالضبط ... يا سلام ,, اسم مكون من أربع احرف ... و ... (احد الأمرين او كلاهما..راتب فوق 2000 او لديه راتب إضافي )


اذا لم تفهم مالذي يدور هنا ... لا تخف .. اقرأ مرة ومرتين .. وثلاث ..


( اذا مازلت تعاني ... فأنت من النوع الذي لا يحب القراءة .. او انك تحب أمثلة كثيرة .. او انك لا تريد ان تفهم او ان شرحي لا يناسب عقليتك وخبرتك وطريقة تفكيرك ,, )


سوف أجرب طريقة أخرى ,,


انظر السؤالين التاليين

السؤال الأول :

اريد عرض اسماء و رواتب أساسية وإضافية للموظفين الذين اسمائهم مكونة من أربع احرف و لديهم رواتب اضافية

أو ان يتم عرض اسماء ورواتب اساسية وإضافية للموظفين الذين رواتبهم اكبر من 3000 دولار ... وليس لديهم رواتب اضافية





هل شاهدت السؤال الأول وركزت في طريقة عرضه ... أنا لم اقل سؤال غامض كهذا :

السؤال الثاني

اريد عرض اسماء و رواتب أساسية وإضافية للموظفين الذين اسمائهم مكونة من أربع احرف و لديهم رواتب اضافية

أو الذين رواتبهم اكبر من 3000 دولار ... وليس لديهم رواتب اضافية





لو شاهدت مثل السؤال الثاني ... فأعرف انه من الخطأ عرضه كهذا !!


من السؤال الأول نستنتج شكل السؤال كما يلي

(اسماء مكونة من اربع احرف و لديهم رواتب اضافية ) أو (رواتبهم اكبر من 3000 و ليس لديهم رواتب اضافية)





يا سلام على المنطق ,’,’


اليك جملة الاستعلام يا فتى ,,





select ename , sal , comm from emp

where

(ename like '____' and comm is not null ) or ( sal>3000 and comm is null ) ;






والنتيجة هي :







ENAME SAL COMM

---------- ---------- ----------

WARD 1250 500

KING 5000






التحدي السابع ....


لماذا ظهرت النتيجة السابقة ؟؟ لماذا KING و WARD هما اللذان عرضا فقط ؟؟

اتحداك ان تقنعني لماذا .. أقنعني بطريقتك .. وسوف أحاول فهمك !!

ممممم .. نفسي في كوباتشينو ^^ .... عن اذنك

The Coder
24-12-2005, 01:53 PM
قبل ان ينتهي هذا الدرس ..

اريد ان تشاهد الصورة التالية ... وهي تلخيص للمعاملات بشكل سلس وبشكل مفهوم لك لكي لا تنساها .. احتفظ بها .. فهي مفيدة كثيرا !! صدقني (الصورة 57)






http://img4.picsplace.to/img4/16/57.jpg






انتهى الدرس السابع ...





اليك المهام :

- جهز برنامج الاوراكل .. سوف اشرح جزء من تنزيله .... وسأفكر في شرحه كله ... اذا استطعت

- اقرأ الموضوع هذا اكثر من مرة .. واذا كنت تملك برنامج الاوراكل .. طبق ... ولا شيء غير التطبيق ...





اليك التحديات :

ستجد التحديات التالية بين السطور ... وهي :





التحدي الأول :

أريد عرض كل أسماء الموظفين التي تحتوي على حرف الـ T مرتين .. يعني لو أن احدهم يدعى بـ SCOTT فسوف يعرض ... فهو اسم يحتوي على الحرف T مرتين ..

ولو ان احدهم يدعى TRRRRRRRRT فسوف يعرض أيضا لأنه يحتوي على الحرف T مرتين وهكذا ,,,,,,





التحدي الثاني :

ما الناتج من العمليات التالية ؟

صح و صح و صح و صح و خطأ = ؟؟؟

خطأ أو صح أو خطأ أو صح = ؟؟؟

نفي نفي نفي نفي نفي الخطأ = ؟؟؟








التحدي الثالث :

اريد عرض اسماء ورواتب الموظفين الذين راتبهم اكبر من 1000 واقل من 5000 بدون استخدام Between




التحدي الرابع :

اريد عرض اسماء ورواتب الموظفين الذين اسمائهم KING أو SCOTT أو TIGER بدون استخدام IN




التحدي الخامس :

هل تشاهد الصورة 47 ؟؟ وهي ثلاث شروط ... برأيك مالناتج اذا كان بينهم OR ؟؟ وما الناتج اذا كان بينهم AND


(الصورة 47)



http://img6.picsplace.to/img6/10/47.jpg





التحدي السادس :

.... التحدي هو ان تشرح لي بمثال .. من عندك .. لو هناك AND و OR و AND ... مالذي سوف يحدث اولا ؟؟ ولماذا ؟





التحدي السابع ....

لماذا ظهرت النتيجة السابقة ؟؟ لماذا KING و WARD هما اللذان عرضا فقط ؟؟

أتحداك ان تقنعني لماذا .. أقنعني بطريقتك .. وسوف أحاول فهمك !!


انتهى الدرس ...
استعدوووو ... الى الشغل العنيف ..
توقعو الدرسين التاليين .. دسمين .. لدرجة الموت ,,,
سوف تخوصون لدرجة الاحتراف ان شاء الله
وحتى تاريخه ..
دعواتكم يا ناس ... ياخي ادعي من قلبك ولمدة 60 ثانية .... يعني وش بينقص منك ^^ ؟؟؟
شكرا لكم ^^

yasean
27-12-2005, 06:45 AM
..
السلام عليكم ورحمة الله وبركاته ..

أحببت التنبيه فقط إلى أن الصور في الصفحة الثانية
الكثير منها لا يظهر ..

على سبيل المثال .. الصور رقم 143 و 153 و 163

وجزاكم الله خيراً .. تحياتي ..

yasean
27-12-2005, 07:28 AM
..
السلام عليكم ..

أعتذر أخوي ..

أخيراً ظهرت الصور .. شكراً لك ..

تحياتي ..

The Coder
28-12-2005, 09:36 PM
..
السلام عليكم ..

أعتذر أخوي ..

أخيراً ظهرت الصور .. شكراً لك ..

تحياتي ..


وعليكم السلام ^^
شكرا لتنبيهك .... واصبر عليها لكي تظهر ^^&
حياك الله يا ياسين ,.,,

The Coder
29-12-2005, 10:30 PM
بسم الله الرحمن الرحيم


الدرس الثامن





اسم الدرس : جملة الاستعلام select والدوال

نوع الدرس : تطبيقي

صعوبة الدرس : *** من *****

اهميــة الدرس : ****** من ***** (Over)




درجة احتراف لغةSQL المتوقعة بعد هذا الدرس : ** من ***** (مبتدئ متقدم )


الوقت المتوقع منك لفهم الدرس : 10 ساعة (ساعتين فهم و 8 ساعات تطبيق )

متطلبات تتوفر فيك : التطبيق
















المتوقع منك في هذا الدرس :








- التأكد من تركيب الأوراكل ,,


- اتقان جزء من هذه اللغة 100 %

- معرفة ترتيب النتائج تصاعديا وتنازليا .

- اتقان الدوال الاحادية .

- اتقان الدوال المتعددة .







هيا لنؤركل ^^

















السلام عليكم


قبل البدء أريدك ان تعرف ان هناك جدول وهمي .. يدعى dual له أغراض كثيرة ..

منها التجريب عليه ..... وله مأرب اخرى ,,,

لو جربنا جملة الاستعلام هذه :

















select * from dual ;

















فسوف يعطيك نتيجة غريبة !! ....








انظر النتيجة :


















D


-

X

























انا شخصيا لا اعرف لماذا هذه النتيجة بالذات..


ولكن اعرف لماذا يعطينا نتائج مبهمة ..

قلنا ان الجدول له أغراض .... فسوف تجدني في هذا الدرس وفي دروس اخرى .. أتطرق لهذا الجدول ....

الان لو اريد التاريخ الحالي ... يعني لو ما عندي تقويم.. كيف اعرف التاريخ الحالي ؟؟

اليك الامر !!

















select sysdate from dual;




































SYSDATE


--------

23/12/05
















واو .... صدقت النتيجة !!


هل رأيت ذلك ؟؟







- بعض الحماقات !!








مممممم .. اريد ان احسب 1+4 = ؟؟؟


















select 1+4 from dual ;

















النتيجة :


















1+4


---

5
















ههههههه ... غريب جدا ^^ .. لدينا آلة حاسبة



























select 'haaaaahaaaaaaahaaaaaaaaaaaa!!!' from dual ;

















والنتيجة ....


















'HAAAAAHAAAAAAAHAAAAAAAAAAAA!!


------------------------------

haaaaahaaaaaaahaaaaaaaaaaaa!!!
















ممممم ... الغريب ان الجدول .. لا يوجد به حقول و.... سجلات عادية !!


والاغرب انني جربت هذا الشيء في جدول emp المعروف ... وظهرت نتائج غريبة !!

اليك بعض منها ...

















select 'what is wrong ?' from emp ;

















النتيجة ....


















'WHATISWRONG?'


---------------

what is wrong ?

what is wrong ?

what is wrong ?

what is wrong ?

what is wrong ?

what is wrong ?

what is wrong ?

what is wrong ?

what is wrong ?

what is wrong ?

what is wrong ?

what is wrong ?

what is wrong ?

what is wrong ?
















واو ... بعدد السجلات الموجودة .. ظهر النص الذي اردت عرضه ؟؟ 14 سجل !! بعدد السجلات الموجودة في جدول الـموظفين !!


اوكيه .. اليك التاريخ !!


























select sysdate from emp ;

















واو ... نتيجة مبهرة .. انظر اليها !!


















SYSDATE


--------

23/12/05

23/12/05

23/12/05

23/12/05

23/12/05

23/12/05

23/12/05

23/12/05

23/12/05

23/12/05

23/12/05

23/12/05

23/12/05

23/12/05
















.. نفس النتائج ولكن بعدد السجلات !!


اذن ما فائدة جدول dual ؟؟؟؟؟؟

















select 2*10+(11-7) from emp ;

















النتيجة ...


















2*10+(11-7)


-----------

24

24

24

24

24

24

24

24

24

24

24

24

24

24
















واو ... يوجد في جدول الـموظفين 14 سجل ... وبعددها عرض لنا تلك النتائج ....


ممممم .. اعتقد إنني اكتشفت في هذه اللحظة .. استنتاج غبي ...

جدول dual به سجل واحد فقط .... لذا فهو يعرض لي النتيجة مرة واحدة ....

فهمت الان لماذا به سجل واحد ؟؟ لأني اطلب منه نتيجة واحدة .. وليست 14 نتيجة مشابهة !!

وانا شخصيا استنتجت شيء آخر .. وسأقوله لكم فيما بعد ,, ان شاء الله ^^
















و اريد ان اشير الى انني اكتشفت شيء غريب قليلا .... لعل وعسى انها غلطة من البرنامج ...


وهي كالتالي :


























select ename as "The_Name_Of_Employee" from emp


where ename ='KING' ;

























يعني وضعت عنوان مستعار للعمود ename .... وجعلته طويل قليلا ..


فسوف يكون الناتج :











The_Name_O

----------

KING









هل لاحظت الاسم المستعار كيف عرض منه عشرة احرف فقط ؟؟


لا ادري لماذا ولكن أتوقع انه سوف يعرض على حسب عدد خانات العمود نفسه !!

يعني ان العمود ename عدد خاناته هي 10 خانات .. او 10 احرف !!

وبالتالي اعتقد أنها غلطة في نفس برمجة البرنامج ... لذا .. لا يهم ولكن أردت التنويه ,,,

المهم المهم .. اترك هذه الحماقات ... و حاول تركيب الأوراكل ....




سنعود بعد شوية ... ^^ << تطوير لسبيس تون

The Coder
29-12-2005, 10:46 PM
- جزء من تركيب الأوراكل 10G:


في بداية وضعك للCD سوف تظهر لك بعض الخيارات ..تابع حتى تظهر لك الصورة التالية (صورة 01 ):


http://img6.picsplace.to/img6/10/01_062.jpg




رقم واحد : اجعله هذا الخيار بالضغط عليه

رقم اثنين : سوف يعرض لك بشكل اوتوماتيكي .. وهو مسار البرنامج ...

طبعا هو في العادة يظهر في C:\ لكن انا وضعته في H:\


رقم ثلاثة :اجعل الخيار Enterprise Edition


رقم اربعة : اجعل علامة الصح في المربع

رقم خمسة : هذا مهم جدا ان تجعله اسم تتذكره ... للتسهيل اجعله مثل ما جعلته انا … الا وهو "ora"


رقم ستة وسبعة : اضف كلمة سر ... لا تنسى هذه الكلمة .. اذا نسيتها .. فأرجو تحميل الاوراكل مرة اخرى ,,

رقم ثمانية : اضغط التالي NEXT


اكمل التحميل ... اذا واجهتك أخطاء في التنزيل اضغط "تجاهل" ignore" "


بعد التحميل .. انظر الصورة 06


http://img6.picsplace.to/img6/10/06_018.jpg





اختر البرنامج الذي يدعى بـ SQL Plus


وهو برنامج خاص بتنفيذ أوامر الـ SQL





سوف يظهر لك النافذة التالية الصورة 066:


http://img5.picsplace.to/img5/16/066.jpg





هل تذكر كلمة السر ؟؟

هل تذكر كلمة ora ؟؟

اكتب المعلومات كما هي موضحة .. ثم اضغط اوكيه ,,

ان معنى system هو مجرد مستخدم افتراضي ... له الصلاحية العظمى في الوصول الى قاعدة البيانات اوراكل ...

سوف نتكلم فيما بعد عن الصلاحيات .. وعن المستخدمين ان شاء الله تعالى .,,,

اذا واجهت مشكلة ... راسلنا ,,,

سوف يظهر لك البرنامج .. اكتب ما يلي : الصورة 0661


http://img6.picsplace.to/img6/10/0661.jpg


1 اكتب الامر الموضح كما هو عليه ..

2 اكتب كلمة سر و احفظها جيدا .. يفضل ان تكون نفس كلمة السر التي وضعتها ...

3 تأكيد كلمة السر

4 اكتب الامر كما هو عليه

5 اكتب كلمة السر

اذا لم يعطيك كلمة connected او أعطاك مشاكل غيرها فراسلنا

6 اكتب الامر كما هو عليه

7 اكتب الامر كما هو عليه

اذا عرضت هذه النتيجة .. فهذا يعني ان جدول emp موجود لديك ,, وهو جدول جاهز يأتي مع الأوراكل ,,

الان ... أغلق البرنامج .. وافتحه مرة ثانية .. واكتب هذه المرة مايلي :

الصورة 067


http://img5.picsplace.to/img5/16/067_000.jpg




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


اسكوت Scott هو مستخدم افتراضي اخر .. لديه بعض الجداول التي نحن ندرسها في منهجنا ..

الجداول هي emp و dept لا عليك في الجداول الباقية ,,,

بعد الضغط على اوكيه ... سوف تظهر لك المؤشر الخاص بالكتابة ... بهذا الشكل "SQL>"


يعني يا حبيبي اكتب ما شئت من جمل الـ SQL


كل ما شغلت هذا البرنامج ... اكتب الامر التالي ...

انظر الصورة 068


http://img6.picsplace.to/img6/10/068.jpg





لو لم تكتبه ... فسوف تعرض الجداول بشكل غير مرتب ....

المهم .. اليك بعض الاختصارات لهذا البرنامج ..... والتي أرى أنها ليست مهمة بالمرة ,,,





لتنفيذ اخر امر كتبته ... اكتب R ثم اضغط Enter




لاستعراض اخر امر كتبته .. اكتب L ثم اضغط Enter




لكي تستعرض اخر امر كتبته في مذكرة للتعديل عليه ... اكتب ed ثم اضغط Enter


سوف يعرض لك برنامج المذكرة .. وبه الامر مكتوب .. عدل ما شئت فيه .. ثم اغلقه مع الحفظ ..

بعدها سيعرض لك نتائج الامر الذي عدلته ,,,





لحفظ اخر امر كتبته ... اكتبه بهذه الصيغة






save C:\a.sql ;








طبعا اكتب المسار الذي تريده ... انا كتبته في المسار c:\


وانا سميت الملف باسم a


انت بامكانك تسميته ماشئت .. مثلا سميه ABC


وتريده في المسار D:\ ... اكتبه كما يلي :






save c:\ABC.sql;








تريد استرجاعه ؟؟

اكتب الامر التالي /






get c:\ABC.sql ;








هناك اوامر اخرى لكن ... اتركها في وقتها ^^

الان نرجع للدرس الرئيسي لهذا اليوم ,,,

The Coder
29-12-2005, 11:27 PM
- ما معنى دالة Function؟؟


هو شيء يأخذ شيء معين .. ويعمل عمل ما ... ثم يعطيني ناتج معين !


فكر في صندوق .. له مدخل ومخرج ... انت او غيرك تدخلون شيء في المدخل.. ويخرج بنتيجة من المخرج

مثلا .. آلة تغليف علب .. تخيل شكلها مثل الصندوق ... لها مدخل ولها مخرج .. ولا تعرف ما بداخلها !!

ادخل علبة بمقاس 1 م مكعب ... تخرج من الجهة الثانية علبة بمقاس 1 م مكعب ولكنها مغلفة بشكل جميل ...


ادخل رأسك ..... يخرج مطرزا من الجهة الأخرى وبشكل غير مقبول

وإذا كانت الآلة ذكية .. سوف تعطي خطأ .. وتقول ان حجم رأسك ليس ا م مكعب .. وليس بالشكل المطلوب وهو على شكل مكعب

اذن الآلة هي دالة تغليف .... دالة عملها التغليف .. (اعرف انه من الخطأ قول ذلك ولكن .. تخيل !!)

الدالة هي مثل الآلة .. ولكنها دالة برمجية .... لا نعرف ما بداخلها .. نعرف ان لها مدخل او مداخل ... ولها مخرج او مخارج ... كالصندوق الأسود ... غامضة ....





لماذا الدالة في منهجنا ؟

توجد في لغة الـ SQL دوال برمجية .. قد بناها مطورو هذه اللغة .. وهي للاستخدام فقط ... لا نعرف كيف عملوها

لا نعرف ما بداخلها .. من الممكن ان نتوقع كيف عملت .. ولكن لا نعرف بالضبط كيف عملت ...

لماذا عملوها ؟ للتسهيل علينا ...ونستخدمها ..

لماذا نستخدمها ؟ لانها مفيدة وتعمل لنا أعمال تختصر علينا الوقت ...

مثلا ...

توجد دالة اسمها .. دالة الإلصاق .. يعني تلصق شيء بشيء ....

ادخل في هذه الدالة نص ... وادخل نص آخر ... وسوف تعرض لك الناتج ... النصين ملتصقين في نص واحد... يا سلام .. شيء جاهز ...

دالة تحويل الحروف الى حروف كبيرة CAPITAL


ادخل الكلمة abcd من مدخل الدالة (مدخل الصندوق) .. وسوف تعمل اعمال لا تعلم انت ماهي .. واذا بها .. تخرج لك من مخرج الدالة (مخرج الصندوق ) هذه النتيجة ABCD


يا سلام ... شيء اخر .. جاهز .. لا نعرف مالذي فعلته الدالة بالداخل .. ولكن يهمنا النتيجة ..

,’,’,’,’,’لكي تستطيع تخيل الدالة ,’,’,’,’,’

اريدك ان تقرأ الدرس هذا من البداية ... ثم تكمل ..


....

...

..

.


هل قرأته مرة ثانية ؟؟ احلف !!! ... اوكيه .. نكمل ,,

الفنكشن (فنكشن = Function = دالة ... شكلها جميل بالعربي هاه ^^) لها مدخل أو اكثر ... ولها مخرج أو اكثر صح ؟؟

في لغة الـ SQL يوجد نوعين من الفنكشن (لاحظ النطق للـ Function)...


الدوال احادية الصف Single-Row Function


الدوال متعددة الصف Multi-Row Function


هذه النوعين .... لهما اكثر من مدخل ... ولكن لهما مخرج واحد !!

افهم جيدا !! .. اكثر من مدخل .. ومخرج واحد .... لكلا النوعين .. الاحادية والمتعددة

اذا أردت معرفة كيف شكل مداخل ومخارج هذه الآلة ... ااااقصد ... هذه الدالة ... فإليك شكلها المعتاد

المخرج اسم الدالة ( المدخل الأول , المدخل الثاني ,..... , مدخل لانهائي )

اذا لم تفهم هذا الشكل .. لا تهتم ... سوف تفهما في المستقبل البعيد ^^


لكن اريد ان انوه الى نقاط مهمة جدا جدا جدا ,,

- مداخل الدالة تسمى بعوامل الدالة .. أي Parameters ومفردها parameter لا تنسى ذلك ..

- مخرج الدالة .. هو ما ترجع به الدالة ... يعني اذا قلنا الدالة ترجع قيمة كذا وكذا .. معناه ان الدالة تخرج كذا وكذا !!

- ان المداخل متعددة .. ولكن المخرج واحد في دوال الـ SQL


- اذا كانت الدالة ثلاث مداخل .. يعني ثلاث مداخل ... لو ان لها مدخل واحد ... يعني مدخل واحد !! ...

لو أدخلت ست قيم والدالة أصلا مدخلين اثنين مثلا !! .. فهذه والله اكبر فضيحة ,,


- بعض الدوال تقول "انت !! .. ادخل نص فقط ... لا تدخل رقم !!" والبعض الاخر .. لها مدخل نصي .. ومدخل تاريخ .. ومدخل رقمي .. وبعض الدوال كل مداخلها أرقام ... وهكذا .. فتنبه لذلك!!

- توضع الدوال عادة بعد select أي كعمود .. او بعد where ... وتوضع في مداخلها عادة اسم عمود أو أي جملة ... واقصد بالجملة هنا أي نص .. أي حرف .. أي رقم .. أي تاريخ !!

يعني في المدخل يا جملة .. يا عمود !! فقط لا غير ,,

لانك لو أخطأت .. في بعض الأحيان حتصير مشاكل .. واذا كانت الدالة ذكية ومتفهمة لغباء مستخدمها .. فسوف تتجاهل الأمر ,,







مفهوم !! لا تنسى ذلك ... سأقتلك !!

الان انسى امر الدوال المتعددة ... ونبدأ بالدوال الاحادية ,,,,,


1) الدوال الاحادية الصفوف Single-Row Function


وهي اربع أنواع ..( تفيدنا في اربع أغراض .. لاتنسى حفظ الانجليزي )..


أ- دوال لأغراض النصوص Character Functions


ب- دوال لأغراض الأرقام Number Functions


ج- دوال لأغراض التواريخ Date Functions


د- دوال لأغراض التحويل Conversion Functions


الان ... ابدأ بالتحمية ....وتوكل على الله ,,,





أ- دوال لأغراض النصوص Character Functions


لاحظ دوال ... وليست دالة ..


- دالة LOWER (lower = معناها اصغر أو أوطأ .. او أسفل )


العمل :تحويل النصوص الى حروف صغيرة small


المثال :






Select LOWER('GOOD by') from dual ;





النتيجة هي ...






LOWER('

-------


good by





يعني .. أدخلنا كلمة GOOD by , وهي كلمة بها حروف كبيرة وحروف صغيرة .. هل لاحظت ذلك ؟؟


سوف تتحول جميع الحروف الى small ... لتصبح good by


لاحظ ان الحروف الكبيرة .. تحولت صغيرة .. وان الحروف الصغيرة .. كما هي عليه !!

يعني لو أدخلنا GOOD BY سوف تتحول الى good by


ولو أدخلنا good by فسوف تكون كما هي عليه good by




الان مثال آخر ...


اريد عرض أسماء جميع الموظفين بالحالة العادية (أي كما هي عليه في الجدول)... والحالة بالحروف الصغيرة









select lower(ename) "Lower" , ename "Normal" from emp ;





والنتيجة ....






Lower Normal


---------- -------


smith SMITH

allen ALLEN

ward WARD

jones JONES

martin MARTIN

blake BLAKE

clark CLARK

scott SCOTT

king KING

turner TURNER

adams ADAMS

james JAMES

ford FORD

miller MILLER








لو ان احدهم اسمه King سوف يعرض king في العمود lower وسوف يعرض King في العمود Normal ....


لماذا هذه الدالة ؟؟ ومتى نستخدمها ؟؟

سوف اعرض لك استخدام قوي جدا .. لها ,,

لو عرفنا ان احدهم يدعى بـ كنق ...

لا نعرف هل ادخل مدخل البيانات اسمه هكذا KING ام هكذا King ام كيف ؟؟

بما اننا لا نعرف كيف ... فسوف نكتشف هذا الشيء عبر المثال التالي :








select ename from emp

where lower(ename) ='king';




هل لاحظت مالذي عملته ؟؟

أجبرت الاسم ان يكون بالشكل الحروف الصغيرة !!

اعرف ان معظمكم لم تصل إليه الرسالة والفكرة .. لكن بالله عليكم ركزوا جيدا ...

لماذا انا قلت 'king' بالذات ؟؟ الم اقل لكم أنني لا اعرف حالة الحروف الخاصة بكنق ؟؟

لماذا يا ترى؟


النتيجة ....





ENAME

------

KING









- دالة UPPER (upper = اكبر أو أعلى ..)


العمل :تحويل أي نص الى حروف كبيرة CAPITAL


الأمثلة :





Select UPPER('GOOD by') from dual ;




النتيجة ....





UPPER('

-------

GOOD BY






أدخلنا كلمة GOOD by .. وتحولت الى GOOD BY


هذه الدالة .. شبيهة التركيب للدالة lower .. وتنطبق عليها ما ينطبق على الدالة lower


لذا ... فجرب نفس امثلة الـ Lower على هذه الدالة ,,,

الجدير بالذكر ان هذه الدالة .. تدخل نص .. تدخل ارقام ... فلا يوجد مشاكل بها ,,,

جرب لو وضعنا هذه الجملة ... مالذي يحدث ؟





select upper(sal) from emp ;

The Coder
29-12-2005, 11:30 PM
- دالة INITCAP


العمل : تحويل أي نص الى ( الحرف الأول كبير .. وبقية الحروف صغيرة )


الأمثلة :





Select INITCAP('GOOD by mY FrIeNd') from dual ;




النتيجة كما يلي





INITCAP('GOODBYMY

-----------------

Good By My Friend




هل لاحظت مالذي حدث ؟؟





كلمة GOOD تحولت الى Good


كلمة by تحولت الى By


كلمة mY تحولت الى My


كلمة FrIeNd تحولت الى Friend


يعني أي كلمة ... سوف تتحول الى أولها حرف كبير .. والبقية احرف صغيرة

ينطبق على هذه الدالة ما ينطبق على Lower و Upper




اليك التحدي الأول !!


لو كتبنا الأمر التالي ....





select initcap(upper(lower('HI My friends ^^'))) from dual ;




مالذي سوف ينتج ؟؟؟؟

ولماذا نتج ما نتج ؟؟ مع تفصيل شرحك ,,,,

ارجو منك عدم استخدام البرنامج لمعرفة النتيجة ...

انت اجلس مع نفسك .. وتوقع النتيجة على الورق ,,

وأنا لم اشرح هذا الجزء المهم من الدوال لغرض ما في نفسي ,,

-دالة CONCAT


العمل : ضم كلمتين او نصين وجعلهما كلمة واحدة

الأمثلة :





Select CONCAT('GOOD ' , 'BY') from dual;




لاحظ انه توجد مسافة بعد كلمة GOOD !! انا وضعتها عمدا لكي تصبح النتيجة ..





CONCAT(

-------

GOOD BY




هل شاهدت النتيجة !!

الكلمة الاولى + الكلمة الثانية = الكلمتين مضمومة !!

... الان بدأت اتأسف يا عرب ...

سوف اضطر الى تصعيب المنهج اكثر واكثر .. فتحملوني يا عرب ,’,’,’

اريد عرض أسماء الموظفين بحالة الحروف الكبيرة Capital في عمود .. وبحالة الحروف الصغيرة small في عمود اخر .. وأريدهم مضمومتين في عمود ثالث ....

يجب ان تعرض فقط اسماء الموظفين الذين يعملون تحت القسم 30 ,,,





اليك النتيجة التي انا اريدها بالضبط ,,







allen ALLEN allenALLEN

ward WARD wardWARD

martin MARTIN martinMARTIN

blake BLAKE blakeBLAKE

turner TURNER turnerTURNER

james JAMES jamesJAMES






لماذا لا تفكر قليلا قبل رؤية الحل ؟؟؟

فكر فكر فكر فكر

فكر فكر فكر

فكر فكر

فكر

حللتها ؟؟؟

ممتاز ... اليك الحل ...








select lower(ename), upper(ename) , concat(lower(ename) ,upper(ename)) from emp

where deptno = 30 ;






مسلية وبسيطة ^^ ....

النتيجة كما اسلفنا بهذه الصورة ....








LOWER(ENAM UPPER(ENAM CONCAT(LOWER(ENAME),

---------- ---------- --------------------

allen ALLEN allenALLEN

ward WARD wardWARD

martin MARTIN martinMARTIN

blake BLAKE blakeBLAKE

turner TURNER turnerTURNER

james JAMES jamesJAMES







- دالة SUBSTR


العمل : تأخذ جزء من الكلمة او النص ... أي تقص منه

الأمثلة :





Select SUBSTR('GOOD BY',2,3) from dual;




لاحظ انها ثلاث مداخل !! أي ثلاث Parameters


المدخل الأول يفترض بأن يكون نص (لقد جربتها مع الأرقام والتواريخ ونجحت ^^ .. لكن فائدتها الحقيقية في النصوص والتواريخ فقط ...), و المدخل الثاني والثالث يفترض بأن يكونا رقمين .

اليك الناتج ...





SUB

---

OOD







لماذا هذه النتيجة ؟؟


قلنا ان هذه الدالة تأخذ جزء من النص .. وتقصه لكي يتم عرضه كما نريد ....

أدخلنا نص .. وهو GOOD BY .. لاحظ ان المسافة تعامل وكأنها حرف !!

وأدخلنا عددين وهما 2 و 3 ...

ثاني مدخل خاص برقم الحرف الذي يبدأ منه القص ... بالله عليك ثاني حرف في كلمة GOOD BY ماهو ؟؟

حرف الـO الأول صح ؟؟

ثالث مدخل خاص بعدد الأحرف التي يجب ان تعرض ...

عد ثلاث حروف بالبدء من الحرف O

O

O

D


وتبقى الكلمة النهائية OOD


اذا لم تفهم .... اليك مثال اخر ,,,

اريد عرض تواريخ توظيف الموظفين مقصوصة من الحرف الأول الى الحرف الرابع..

وأريد عرض تواريخ توظيف الموظفين مرة اخرى مقصوصة من الحرف الخامس الى الحرف السادس

وأريد نفس الشيء ولكن مقصوصة من الحرف الأول فقط !!

وأريد عرض التواريخ بنفس صيغتها

وأريد عرض ثاني رقم وثالث رقم من الرواتب فقط ....(مقصوص منها الرقم الثاني والثالث )

وعرض الرواتب بنفس صيغتها ..

يعني بهذه الصورة






A B C D E F

-------- ---- -- - ---------- -

17/12/80 17/1 2/ 1 800 0

20/02/81 20/0 2/ 2 1600 6

22/02/81 22/0 2/ 2 1250 2

02/04/81 02/0 4/ 0 2975 9

28/09/81 28/0 9/ 2 1250 2

01/05/81 01/0 5/ 0 2850 8

09/06/81 09/0 6/ 0 2450 4

19/04/87 19/0 4/ 1 3000 0

17/11/81 17/1 1/ 1 5000 0

08/09/81 08/0 9/ 0 1500 5

23/05/87 23/0 5/ 2 1100 1

03/12/81 03/1 2/ 0 950 5

03/12/81 03/1 2/ 0 3000 0

23/01/82 23/0 1/ 2 1300 3







فكر فكر فكر فكر .............

The Coder
29-12-2005, 11:32 PM
لا تعرف ؟؟ انك تعرف انني اعرف انك لا تعرف ذلك ,,,,


خذ الحل ..












Select hiredate A, SUBSTR(hiredate,0,4) B, SUBSTR(hiredate,5,2)C

, SUBSTR(hiredate,0,1) D,sal E ,SUBSTR(sal,2,1) F from emp ;




لاحظ انني سميت الأعمدة بالحروفA B C D ....

A هو التاريخ كما هو عليه


B التاريخ مقصوص منه اول اربع حروف .. لاحظ بإمكاننا ان نضع الرقم 1 بدلا من 0 ... جربتها وستجدها نفس النتيجة


C مقصوص من الحرف الخامس الى السادس ... يعني ابدأ من الخامس .. واعرض حرفين الخامس والسادس....


D عرض اول حرف من التاريخ .. لاحظ اننا لو وضعنا 1 بدلا من 0 .. فستأتي نفس النتيجة ....


E عرض الراتب كما هو عليه ...


F عرض الرقم الثاني من اليسار .. للراتب .. لاحظ اننا لا نحتاج هذه الدالة مع الأرقام .. في اغلب الأحيان

ولكن وضعتها انا هنا لكي ترى ان الدالة ذكية قليلا .. وغبية قليلا ... وبنت حلال ... ولم تعمل مشاكل ,,,





الان اريد ان اعرض اسماء الموظفين بالحالة الاحرف الصغيرة .. ومقصوص من الحرف الأول الى الثالث ...

ماذا اعمل ؟؟

فكر فكر فكر فكر ....

اليك الحل ....


...

..

.







select SUBSTR(lower(ename),1,3) , ename from emp ;




لاحظ .... اننا استخدمنا الدالتين ...

وهذه حلاوة استخدام الدوال ... بإمكانك مزج احدها مع الأخرى ... بالطريقة التي تعجبك ,,,

اليك الناتج ....





SUB ENAME

--- ------

smi SMITH

all ALLEN

war WARD

jon JONES

mar MARTIN

bla BLAKE

cla CLARK

sco SCOTT

kin KING

tur TURNER

ada ADAMS



SUB ENAME

--- ------

jam JAMES

for FORD

mil MILLER









- دالة LENGTH (Length = الطول !!)


العمل : توجد عدد احرف الكلمة ... او النص (طول النص ^^)

الأمثلة :








Select LENGTH('GOOD By') from dual;




كم تتوقع يوجد حرف ؟؟

اذا قلت 6 حروف .. فقد أخطأت!! .. لماذا لا تحسب المسافة ؟؟

المسافة تعتبر حرف كما أسلفنا

الناتج هو :





LENGTH('GOODBY')

----------------

7




هل فهمت ؟؟

لا أرى فيها صعوبة ...

لكن لو جربناها مع الراتب مثلا ....وهو رقم .. فمالذي يحدث ؟؟








Select LENGTH ( sal ) from emp ;




مالناتج ؟؟ ولماذا ؟؟





LENGTH(SAL) SAL

----------- ----------

3 800

4 1600

4 1250

4 2975

4 1250

4 2850

4 2450

4 3000

4 5000

4 1500

4 1100

3 950

4 3000

4 1300




عرض عدد الخانات للأرقام ؟

اعتقد انه في جملة Select .. سوف تحول الأرقام والتواريخ الى نصوص للعرض ...

لا اعتقد .. بل اجزم بذلك ...

اذا لم تفهم ما معنى تحويل الأرقام لحروف .. فسأشرح لك الان بعض الأمور ...


يوجد هناك نوعين من الأرقام ...

رقم رقمي

ورقم حرفي ..


الرقم الرقمي .. يستخدم للعمليات الحسابية كالضرب والجذر وغيرها ....


والرقم الحرفي .. للعرض عادة ... فمثلا اسم ملف ما .. ABC123 .... الارقام 1 و 2 و 3 ... هي احرف شكلها أرقام !! ..


اذا كنت تعرف شيء اسمه الأعداد الثنائية ... فهذا جميل ...

الأعداد الثنائية هي 0 و 1 .. وهي التي يفهمها الحاسب ..

والأعداد العشرية هي 0 و 1 و 2 و.......9 والتي نستخدمها نحن كبشر عادة ...

العدد الثنائي = ما يناسبه بالعشري


1 =1

10 =2

11 =3

100= 4

101=5


وهلم جر ,,,

سوف نغطي هذه الدروس فيما بعد ان شاء الله ....

المهم هذه الأرقام هي ارقام رقمية .. تستخدم للحسابات كما اسلفنا ..

الأرقام الحرفية .. هي حروف على شكل ارقام .. تستخدم للعرض ...

فمثلا ... في نظام الحروف .. وليس الأرقام ... لاحظ!! نظام الحروف وليس الأرقام !!


0010000 = 1

0010001 = 2

0010010 = 3

......

......

1000001 = A

1000010 = B

....


وهكذا ...

طبعا الثلاثة الرقمي والذي شكله (11) غير الثلاثة الحرفي والذي شكله (0010010 )

فأنا كنت أقول ان جملة الاستعلام select تعمل العمليات الحسابية والمنطقية وكل شيء ..

وفي النهاية تحول الناتج ... الى حروف (حروف=نصوص)

فائدة هذا التحويل هي العرض فقط على الشاشة ,,


لم تفهم ؟؟

سوف تفهم بشكل منطقي ومرتب اكثر في المستقبل البعيد ان شاء الله ,,,





محترف ؟؟ ذكي ؟؟ عبقري ؟؟ تحب التحديات ؟؟

تحدي للمحترفين فقط !! اكرر للمحترفين ,,...


اريد ان اعرض أسماء الموظفين في عمود

وأريد عرض أسماء الموظفين ماعدا الحرف الأخير مقصوص منه في عمود اخر

وأريد عرض الحرف الأخير من أسماء الموظفين في عمود ثالث !!

يعني اريد الناتج بهذه الصورة :







A B C

---------- - -------

SMIT H SMITH

ALLE N ALLEN

WAR D WARD

JONE S JONES

MARTI N MARTIN

BLAK E BLAKE

CLAR K CLARK

SCOT T SCOTT

KIN G KING

TURNE R TURNER

ADAM S ADAMS

JAME S JAMES

FOR D FORD

MILLE R MILLER




صعب هاه ؟؟

اريد تصعيبه اكثر وأكثر ..


اريد عرضه بهذا الشكل !! :









ALL_OF_THEM

--------------------

SMIT + H = SMITH

ALLE + N = ALLEN

WAR + D = WARD

JONE + S = JONES

MARTI + N = MARTIN

BLAK + E = BLAKE

CLAR + K = CLARK

SCOT + T = SCOTT

KIN + G = KING

TURNE + R = TURNER

ADAM + S = ADAMS

JAME + S = JAMES

FOR + D = FORD

MILLE + R = MILLER




في عمود واحد يدعى all_of_them !! وهو التحدي الثاني


.. انا شخصيا .. لا اعتقد ان أحدكم سيحله اصلا ..

ولا اعتقد ان احدكم سيفكر اصلا ان يقرأ كل سطر ,, هل تعرف لماذا ؟

لأنه لا يوجد إلا واحد فقط الان .. يحل التحديات أول بأول !! ما شاء الله عليه ,,

كانوا 25 .. وصاروا 7 ... و قبل أيام 2 ... والآن واحد فقط .. يحل معي ,,

انا صراحة اعتبرها مصيبة ,, لو ما بتعرف مش مشكلة ...

لان التحديات عادة صعبة ولم اشرحها وتحتاج لاستنتاج منك ...

لذا .. فليكن ما يكن ,,





- الدالة INSTR


العمل : تحدد مكان حرف .. في أي نص ... أي تدخل نص .. وتدخل الحرف الذي تريد معرفة مكانه ..


وفي النهاية سوف ترجع (ترجع=تخرج) الدالة رقم وهو ترتيب الحرف في النص ,,

الأمثلة :









Select INSTR('GOOD GOOD','D') from dual ;




ومعناه .. في النص GOOD GOOD ماهو ترتيب اول D يواجهنا ؟؟

سوف يكون الحرف الرابع صحيح ؟؟





INSTR('GOODGOOD','D')

---------------------

4




لو وضعنا مثلا النص GOOD , ثم وضعنا حرف S مثلا ..

بالله عليك اين الحرف S ؟؟ هي يوجد حرف S في النص GOOD ؟؟؟

طبعا لا ,, لذا فسوف يكون الناتج .... صفر ’,’,’,’,’,’

اريد تعقيد الأمور اكثر و اكثر ,, اريد ان أتفنن في كل ما أخذناه !! مع العلم انني اعقد الأمور من رأسي , ولا يوجد منهج في العالم يعلمني كيف اعقد الأمور على نفسي , فأتوقع منك ان تعقد الأمور انت اكثر وذلك بالتمرس والتجريب , طبعا اذا لم تتمرس كثيرا وتجرب كثيرا , فلن تتعلم بشكل قوي , انا لا اريد تعقيد الأمور اكثر , ولكن اريد ان افهم فهم عميق لماذا مطورو لغة الـ SQL وضعوا هذه الدوال ؟؟ لماذا فكروا في وضعها اصلا ؟

الان لدي سؤال غبي , اريد ان تعرض لي أسماء الموظفين بحالة الحروف الصغيرة , ومقصوصة عند حد الحرف a


فمثلا blake يحتوي على الحرف a يعني نقص حده فيصبح bla


ومثلا allene فيكون اسمه a


ومثلا king فيكون فارغ , لانه لا يحتوي على الحرف a


اليك الناتج الذي اقصده








ENAME B

---------- ---

SMITH

ALLEN a

WARD wa

JONES

MARTIN ma

BLAKE bla

CLARK cla

SCOTT

KING

TURNER

ADAMS a



ENAME B

---------- ---

JAMES ja

FORD

MILLER







طبعا لا اعتقد انك تحتاج لمثل هذا الغباء , ولكن اريدك ان تفكر فقط ,

سواء فكرت ام لم تفكر , اليك الناتج :





select ename , substr(lower(ename),1,instr(lower(ename),'a')) B from emp ;






استخدمت instr داخل دالة القص substr ,


لو كان اسم الموظف blake ..


يعني قص لي من اول حرف (الرقم واحد) , وعدد الحروف اللازمة هي ثلاثة .. لماذا ثلاثة ؟؟

لان ترتيب الحرف a هو الثالث من الاسم blake , يعني الدالة instr ترجع الرقم ثلاثة فتبدو الجملة هكذا :


Substr(lower(ename) , 1 , 3 )


لم تفهم ؟؟

طيب اليك ذلك لاحظ الحل بالتدرج ,’,’,’,’,’

Substr(lower('BLAKE'),1,instr(lower('BLAKE'),'a') )

Substr(lower('BLAKE'),1,instr('blake','a') )

Substr(lower('BLAKE') , 1 , 3 )

Substr('blake' , 1 , 3 )

bla


وهو الناتج الاساسي

لم تفهم ؟ ممممم اعتقد أنها صعبة عليك في هذا الوقت , لذا اتركها الان وراسلني لو عندك استفسار .




- الدالة LPAD


العمل : تنظيم من اليسار .


الأمثلة :





Select LPAD('AHMED',10,'*') from dual ;




كأن لسان حال هذه الدالة يقول :

"حدد المدخل الأول(المدخل الأول=AHMED في مثالنا هذا) بعدد المدخل الثاني( عشرة ) حروف ... اذا زاد .. قص منه الزائد , اذا نقص اكمل الحروف المتبقية بالمدخل الثالث (علامة النجمة) "

انظر الناتج :





LPAD('AHME

----------

*****AHMED




لم تفهم ؟

ادخلنا الحد 10 حروف صح ؟؟

ادخلنا حرف * صح ؟

لو ادخلنا في المدخل الأول ABC , فسوف يكون الناتج *******ABC (عشر حروف لاحظ من أي جهة النجوم)


لو ادخلنا المدخل الأول ABCDEFGHI فسوف يكون الناتج *ABCDEFGHI (عشر حروف لاحظ من أي جهة النجوم )


لو ادخلنا THE_ORACLE_COURSE فسوف يكون الناتج مقصوص لانه اطول من عشر , يعني هكذا : THE_ORACLE (عشر حروف)

لو كان المدخل لا شيء ؟؟ فسوف يكون الناتج **********

لماذا هذه الدالة ؟ للتنظيم فقط لا غير ,

اسم الدالة LPAD , وحرف الـ L يعني Left أي يسار (يعني وضع النجوم في اليسار في مثالنا )





تكره الشرح المفصل ؟؟

اليك مثال اخر ,,,








Select LPAD(ename,10,'-') from emp ;










LPAD(ENAME

----------

-----SMITH

-----ALLEN

------WARD

-----JONES

----MARTIN

-----BLAKE

-----CLARK

-----SCOTT

------KING

----TURNER

-----ADAMS

-----JAMES

------FORD

----MILLER







سوف تظهر لك النتائج بشكل منسق اكثر على برنامج SQL PLUS , لو طبقت الجملة السابقة طبعا !!

The Coder
29-12-2005, 11:38 PM
- الدالة RPAD


العمل : تنظيم من اليمين , نفس فكرة الدالة LPAD ولكن R تعني يمين Right




الأمثلة :





Select RPAD(ename,10,'!') , LPAD(ename,10,'?') from emp ;




لاحظ الناتج !! ولاحظ العلامتين ! و ؟

ولا تنسى ان تلاحظ اننا حددنا 10 حروف ,,

مرة باليمين ومرة باليسار :





RPAD(ENAME LPAD(ENAME

---------- ----------

SMITH!!!!! ?????SMITH

ALLEN!!!!! ?????ALLEN

WARD!!!!!! ??????WARD

JONES!!!!! ?????JONES

MARTIN!!!! ????MARTIN

BLAKE!!!!! ?????BLAKE

CLARK!!!!! ?????CLARK

SCOTT!!!!! ?????SCOTT

KING!!!!!! ??????KING

TURNER!!!! ????TURNER

ADAMS!!!!! ?????ADAMS

JAMES!!!!! ?????JAMES

FORD!!!!!! ??????FORD

MILLER!!!! ????MILLER









اليك مثال اخير ...

نريد تجربة تصغير الحد ... مالذي سوف يحدث ؟؟





Select ename , RPAD(ename,4,'*') from emp ;




والنتيجة هي :








ENAME RPAD

---------- ----

SMITH SMIT

ALLEN ALLE

WARD WARD

JONES JONE

MARTIN MART

BLAKE BLAK

CLARK CLAR

SCOTT SCOT

KING KING

TURNER TURN

ADAMS ADAM

JAMES JAME

FORD FORD

MILLER MILL




كأنها دالة القص substr , وليست هي طبعا ,,

وكما قلنا انها عملية تنظيمية ليست الا ,,,





- الدالة TRIM


العمل : اذا ادخلت حرف ما ... فسوف تحذفه من اول النص , ومن اخر النص اذا وجد هذا الحرف

دالة اعتبرها الوحيدة غبية جدا , ووجودها غريب فعلا ,,

اليك الأمثلة:





Select TRIM('S' FROM 'SAMI') as A from dual ;







والناتج ,,





A

---

AMI







ادخلنا الحرف S وادخلنا النص SAMI سيكون الناتج هكذا AMI


لو ادخلنا الحرف نفسه .. ثم ادخلنا النصوص التالية :


SAMIS الناتج AMI

SSSSAMISSSS الناتج AMI

Samis الناتج هو amis

SYSTEMS الناتج هو YSTEM


انا شخصيا لا اعرف لماذا هذه الدالة , ولماذا وجدت اصلا , اذا عرفت سر وجودها اخبرتكم فيما بعد ان شاء الله ,





اخيرا انتهينا من دوال النصوص ولله الحمد ,,, كثيرة هاه !!

اليك تلخيص مبسط للدوال الحرفية ... الصورة (18) احفظها جيدا ,,


http://img6.picsplace.to/img6/10/18_016.jpg





ب- دوال لأغراض الأرقام Number Functions


الدالة :ROUND


العمل :تقريب الأعداد ,’,’,’


الأمثلة :


اليك درس في الرياضيات !! درس ممل جدا جدا جدا .. تحمل على قراءة سطوره !!

تقريب الأعداد ..

اولا اريدك ان تعرف مايلي :

العدد 152 هو نفسه 0152


العدد 89 هو نفسه 000000089

العدد 189 هو نفسه 189.0000000 لأن الاصفار لا قيمة لها اذا كانت في يمين الفاصلة

العدد 754 ليس هو العدد 754.0001 ... العدد الثاني اكبر بمقدار ضئيل ,,,,

فرق بين المثالين الأخيرين !!


نبدأ الدرس ...

لماذا نقرب ؟؟؟ لكي يسهل علينا قراءة العدد ..

أيهما أسهل .. 1500145 مليون و خمس مئة ألف و مئة وخمس و أربعون ... أم 1500000 مليون ونصف ؟؟

طبعا هنا لا يهمنا الدقة .... يهمنا التقريب وسهولة العدد للتذكر ...

تشاهد الأخبار ؟؟ لو قتل في حرب ما لا سمح الله ... هذا العدد من الضحايا .... "15046 ضحية "..


ماذا يقولون ؟؟ يقولون "قتل ما يقارب 15000 ضحية ليلة أمس بـ......."

قتل ما يقارب !! .. تقريب .. صح ؟؟

يعني حذفوا 46 شخص !! لأجل التقريب ... الـ46 لا بأس بها .. بجانب 15046 ...


على حسب احتياجاتنا نقرب الأعداد .. فمثلا في الكيمياء الذرية ... لو احدهم قرب هذا العدد 0.00456 الى 0.0046

فنعتبرها مصيبة !! كارثة !!!! ... لماذا ؟؟ لأنه حذف عدد لا يغفر ,, ويهمنا بالدرجة الأولى ..


كأنه قال "قتل 10000 ضحية !! " هل فهمت النسبة والتناسب ؟؟

نبدأ في كيفية التقريب ...

لو هنالك طالب شاطر .. واخذ نسبة 98.8 نريد تقريب النسبة للعدد الصحيح (عدد صحيح = عدد بدون كسور) ... ما هو الناتج ؟؟

طبعا 99 ,,

لو هنالك طالب اخر حصل على نسبة 98.4 .. نريد التقريب الى العدد الصحيح .. ما هو الناتج ؟؟

طبعا 98 ,,

هل تعرف لماذا ؟؟

لأن 98.8 يوجد في الكسر 8 وهو اكبر من او يساوي الـ 5 ,, اذن نحذفه ونزيد الخانة التي بعده بواحد يعني هكذا


98

+

1

=

99


وكما لاحظنا في 98.4 ... تجاهلنا الـ 4 لأنه اصغر من الـ5 ,,,

لو مثلا احدهم حصل على 89.54 .. ما هو التقريب الى العدد الصحيح ؟؟ الكسر اكبر من او يساوي 5 ... اذن

89

+

1

=

90


هل فهمت الفكرة المبدئية ؟؟ تتوقف على الكسر هل اكبر من او تساوي الـ 5 او لا !!

الان دالة ROUND هي دالة تقريب معقدة بعض الشيء ..

اليك شكلها ... لو اردنا تقريب العدد 549.8874

ROUND(549.8874 , 1)= ???


هنالك مدخلان (2 Parameters ) في هذه الدالة .. المدخل الأول هو الرقم المراد تقريبه .. المدخل الثاني هو الخانة المراد اختبارها !! ... كيف ؟؟

The Coder
29-12-2005, 11:40 PM
اليك الصورة 28




http://img6.picsplace.to/img6/10/28_004.jpg




في الصورة اريدك ان تحفظ الخانات .. فالفاصلة العشرية لا تحسب .. يمين الفاصلة العدد واحد .. ثم اثنين ثم ... الخ

ويسار الفاصلة يوجد صفر , سالب واحد , سالب اثنين ...... الخ

احفظها جيدا .. يمين الفاصلة الأعداد الموجبة .. يسار الفاصلة الصفر والأعداد السالبة !!

انا وضعت الرقم واحد في المدخل الثاني في الدالة ROUND السابقة .. يعني اختبر الخانة بيمين الخانة واحد (اختبر الخانة رقم اثنين)...


سؤال خطير !! ما معنى اختبر ؟؟

يعني اذا كانت اكبر من او تساوي 5 ... اضف واحد للعدد الذي يليه واجعله صفر واجعل الارقام التي يمينه كلها اصفار ...


واذا كانت اصغر من 5 ... اجعله واجعل الارقام التي يمينه كلها اصفار فقط (بدون زيادة واحد للعدد الذي تليه),,


في الصورة الخانة رقم واحد يوجد بها الرقم 8 ....انظرالرقم في الخانة التي بيمينه (الخانة رقم اثنين) .. يوجد العدد 8 ايضا !! ..

هل العدد 8 اكبر من او يساوي الـ 5 ,,, اذن .. نحذف جميع الخانات التي يمين الخانة رقم واحد ... ونزيده بواحد ,,

لم تفهم ؟؟


ROUND(549.8874 , 1 ) = 549.9000=549.9


اختبرنا الخانة الثانية .. (لماذا نختبر الخانة الثانية ؟؟ لاننا ادخلنا واحد ...)

طبعا قلنا انه 549.9000 ثم حذفنا الاصفار في يمين الفاصلة لانها لا تساوي شيئا !!


ROUND(549.8874 , 3) = 549.8870 = 549.887


اختبرنا الخانة الرابعة .. (لماذا نختبر الخانة الرابعة ؟؟ لأننا ادخلنا ثلاثة ... )


ROUND(549.8874 , 0 ) = 550.0000=550


اختبرنا الخانة الأولى ...


كأن المدخل الخاص بالخانات يحدد عدد الكسور .. فمثلا ادخلنا رقم واحد يعني اريد كسر واحد يظهر .. كما في الناتج السابق 549.9


ثم أدخلنا رقم ثلاثة .. يعني اريد ثلاث كسور تظهر كما في الناتج السابق 549.887 !!

ثم أدخلنا رقم صفر .. يعني لا اريد أي كسر يظهر ,,

لو أدخلنا العدد سالب اثنين ؟؟ او سالب واحد ؟؟

اذا سالب اثنين .. نختبر الخانة رقم كم ؟؟ رقم سالب واحد صح ؟؟ لكن مالذي يحدث


ROUND(549.8874 , -2 ) = 500.0000=500

ROUND (549.8874 , -1 ) = 550.0000=550

ROUND(549.8874 , -3 ) = 1000.0000 = 1000


لاحظ في لماذا صارت 1000 ؟؟ الخانة -2 ... يوجد بها خمسة .. صح ؟ اذا اختبرناها فسوف نصفرها مع كل الأعداد بيمينها .. ثم نضيف واحد للعدد الذي يليها .. والذي يقطن في الخانة رقم -3

ماهو العدد في الخانة رقم -3 ؟؟ طبعا صفر ...

يعني كأن الرقم بهذه الصورة : 0549.8874

هل لاحظت الصفر ؟؟ لا قيمة له .. لذا فهو لا يكتب عادة ..

ROUND(549.8874 , -4 ) = 00000.0000 = 0


سالب اربعة ؟؟ نفس الفكرة ..

00549.8874 اختبر الخانة -3 ... وسيصبح الناتج 00000.0000 يعني 0 !!

ارجوا إعادة النظر في هذا الدرس مرة ثانية وثالثة حتى تفهمه ...

الان نريد استخدام الدالة كما ينبغي ...








select round (549.8874,-3) from dual ;




والناتج يصبح ...








ROUND(549.8874,-3)

------------------

1000







تخيل ان المدير (هو نفسه المدير السابق) .... يشكو من حساسية الأعداد في بعض الأحيان ... ,, ويريد ان يرى رواتب الموظفين بشكل سلس ومقبول , لا يهمه الدقة في الرواتب .. ولكن يريد ان يرى الشكل السهل ..

يعني يريدها بهذه النتيجة





ENAME SAL C

---------- ---------- ----------

SMITH 800 800

ALLEN 1600 1600

WARD 1250 1300

JONES 2975 3000

MARTIN 1250 1300

BLAKE 2850 2900

CLARK 2450 2500

SCOTT 3000 3000

KING 5000 5000

TURNER 1500 1500

ADAMS 1100 1100

JAMES 950 1000

FORD 3000 3000

MILLER 1300 1300




العمود C هو الراتب بعد التقريب ,,, (C = اسم مستعار )

هل تعرف مالجملة ؟؟؟


.....

...

.


انتهى الوقت ..

اليك الجملة :





select ename , sal , ROUND(sal,-2 ) C from emp ;




...


انتهت هذه الدالة المملة ...





الدالة :TRUNC


العمل :قص العدد ... مشابهة لـ ROUND


الأمثلة :


هل تذكر عملية التقريب في دالة ROUND؟

في دالة الـ ROUND اذا اختبرنا الخانة .. فنرى احد الاحتمالين :


1- اكبر من او تساوي الخمسة ؟؟ اذن اضف واحد للعدد التالي (التالي =الذي على اليسار) وصفر العدد وكل الاعداد في اليمين

2- اذا كان اصغر من الخمسة , صفر العدد وكل الاعداد في اليمين ...





في الدالة TRUNC .....


لا يوجد الا احتمال واحد .. وهو الاحتمال الثاني

سواء كان اكبر من او يساوي الخمسة .. أو حتى اصغر من الخمسة لا يهم ...

المهم صفر العدد الذي نختبره والاعداد التي في اليمين .. وبدون اضافة الواحد !!


TRUNC (549.8874 , 2 ) =549.88

TRUNC (549.8874 , 1) =549.8

TRUNC (549.8874 , 0) = 549

TRUNC (549.8874 , -1) = 540

TRUNC (549.8874 ,-2)=500

TRUNC (549.8874 , -3) =0

TRUNC (549.8874 , -4) =0

TRUNC (549.8874 , 5) = 549.8874




كأنها (لاحظ كلمة كأنها ) عملية قص للرقم ....

بعض الأحيان هذه الدالة ادق من الدالة السابقة ..

وبعض الأحيان تلك الدالة ادق من هذه ..








select TRUNC (549.8874 ,1) from dual ;




والناتج هو :





TRUNC(549.8874,1)

-----------------

549.8







الان نريد عرض الرواتب بالدالتين .. مرة بالسالب اثنين ومرة بالسالب ثلاثة





select sal , round(sal,-2) A , round(sal,-3) B

,trunc(sal,-2) C , trunc(sal,-3) D from emp ;







انظر الناتج ولاحظ الفروق ,,,








SAL A B C D

---- ---------- ---------- ---------- ----------

800 800 1000 800 0

1600 1600 2000 1600 1000

1250 1300 1000 1200 1000

2975 3000 3000 2900 2000

1250 1300 1000 1200 1000

2850 2900 3000 2800 2000

2450 2500 2000 2400 2000

3000 3000 3000 3000 3000

5000 5000 5000 5000 5000

1500 1500 2000 1500 1000

1100 1100 1000 1100 1000

950 1000 1000 900 0

3000 3000 3000 3000 3000

1300 1300 1000 1300 1000









الدالة :MOD


العمل :دالة باقي القسمة ... من اهم الدوال البرمجية الحسابية ,,,


الأمثلة :


تعلمت في صغرك عملية القسمة ,


1000 قسمة 500 = 2

كبرت قليلا ... وعرفت ان :

1000 قسمة 502 = 1 والباقي 498 ..

وكبرت كثيرا .. وعلمت ان :

1000 قسمة 502 = 1.99203187


ولما وصلت الى هذا السطر .. نسيت مالذي حدث من قبل !! دعني أذكرك ...


لماذا يلزمنا باقي القسمة ؟؟ سوف تعرف ذلك فيما بعد ... وخاصة في البرمجة ,,

اريدك الان ان تعرف ما هو باقي القسمة ....

1000 باقي القسمة على 50 = صفر

50 باقي القسمة على 5 = صفر

50 باقي القسمة على 6 = 2


5 باقي القسمة على 1000 = 5

5 باقي القسمة على 6 = 5

5 باقي القسمة على 5= صفر

0 باقي القسمة على 5 = صفر

هل تذكرت الان ؟

دالة MOD هي دالة باقي القسمة ..

جرب باقي القسمة للـ 6 على الـ 5








select MOD(6,5) from dual ;







لاحظ المدخل الأول والثاني ... اولا الست ثم الخمس ,,





MOD(6,5)

---------

1




نريد باقي قسمة الراتب الاساسي على الراتب الاضافي لكل موظف يملك راتب اضافي ...








select sal,comm,mod(sal,comm) from emp

where comm is not null ;




اليك النتيجة ... تتبعها جيدا ,,





SAL COMM MOD(SAL,COMM)

---- ---------- -------------

1600 300 100

1250 500 250

1250 1400 1250

1500 0 1500







انتهت الدوال الرقمية ...

لاحظ أنني لم أشدد على دالة باقي القسمة كثيرا رغم أهميتها ,’,’,’
.....
سنعود بعد شوية ,,

The Coder
29-12-2005, 11:47 PM
ج- دوال لأغراض التواريخ Date Functions


قبل البدء اريد ان اعرض عليك أسماء الأشهر الإفرنجية لأن أوراكل وللأسف لا تعرف لا شعبان رجب ولا رجب رمضان ,,

يناير , فبراير , مارس , ابريل , مايو , يونيو , يوليو ,أغسطس , سبتمبر , أكتوبر , نوفمبر , ديسمبر


January , February , March , April , May , June , July , August , September , October , November , December


طبعا بالانجليزي احفظهم ,’,’,





الدالة : SYSDATE


العمل :توجد التاريخ الحالي .. طبعا توجده من تاريخ النظام للحاسب الآلي المستخدم لهذه الدالة


الأمثلة :


أخذناها من قبل ... هل تذكر ؟؟

اليك مثال عليها ...





select sysdate from dual ;




وسوف تعرض التاريخ الحالي ... طبعا عرضت لي هذه النتيجة ... وانت ستعرض لك تاريخ يوم استخدامك لها ,,





SYSDATE

--------

29/12/05






الدالة :MONTHS_BETWEEN


العمل :توجد الفرق بين تاريخين ... يعني ندخل تاريخ ثم ندخل تاريخ اخر .. توجد لنا عدد الشهور بينهما !!


الأمثلة :


دالة قوية جدا لإيجاد عدد الشهور بين تاريخين ... يعني ندخل شهر .. ثم ندخل شهر اخر .. واترك الدالة تفرم وتعجن و تصلخ وتجزر ... وفي النهاية تعطينا الفرق بينهما ,,,

يعني مثلا .. ولد احدهم في التاريخ 10/10/1999 م ثم مات رحمة الله عليه في تاريخ 10/11/1999 م

بالله عليك كم شهر مضى من يوم ولادته ؟؟ كم ؟؟

أكيد شهر ,,

اليك المثال مع العلم ان أوراكل تعتبر هذا الشكل "10-10-99" تاريخ .. وتعتبر هذا الشكل "10-10-1999" ايضا تاريخ .. للتاريخ إشكال كثيرة سوف نغطيها .. فلا تقلق ... :







select months_between('10-11-1999','10-10-99') from dual ;




لاحظ في المدخلات Parameters الخاصة بالدالة ان الكبير اولا ثم الصغير ثانيا ... أي ان الأحدث وضعناه اولا ثم الأقدم ثانيا ...


ولاحظ ان احدها على الشكل DD/MM/YYYY (D=day , M=month , Y=year) و الآخر على شكل DD/MM/YY وفوق هذا لا يوجد مشكلة ... جميل جدا ...

اليك الناتج ....





MONTHS_BETWEEN('10-11-1999','10-10-99')

---------------------------------------

1




الناتج يساوي واحد ؟؟ واحد ماذا ؟؟ طبعا واحد شهر ... يعني الفرق بين التاريخين السابقين .. هو شهر واحد ..

نحن وضعنا التاريخ الأحدث اولا صح ؟؟

لو عكسناها ؟؟ هل تقبل الدالة ؟؟ هل ذكية لكي تعرف ذلك ؟؟ لنرى ...








select months_between('10-10-99','10-11-99') from dual ;










MONTHS_BETWEEN('10-10-99','10-11-99')

-------------------------------------

-1




سالب واحد ؟؟

يعني كأنه طرح الكبير من الصغير .... المهم نحن عادة نتجاهل السالب في وصف الفرق بين رقمين ...

يعني في النهاية الفرق شهر واحد ... لا يهمنا سالب .. موجب ... هل فهمت !! تجاهل السالب فقط في إيجاد أي فرق ,,,

طيب ... تعقيد الأمور اكثر واكثر ... احدهم (هو نفسه لكن حصل خطأ في التواريخ ) ولد في التاريخ 10/10/1999 م .. وتوفي رحمه الله في تاريخ 11/11/1999 م ... كم شهر مضى من يوم ولادته ؟؟

شهر ويوم ... صح ؟؟ هل تتوقع ان هذه الدالة ذكية جدا لكي تقول لك .. يا حبيب ألبي الفرق هو شهر ويوم ؟؟

لا .. وألف لا ... سوف تعرض أرقام وكسور

اليك المثال ....





select months_between('11-11-99','10-10-99') from dual ;




ماهي النتيجة ؟؟ ماهو المتوقع !!


نحن قلنا ان الدالة ترجع (ترجع = تخرج) فقط عدد .... وهذا العدد المفترض بأن يكون عدد الأيام !! صح ؟؟

غلط ... بل عدد الأشهر !!

الان كم الأشهر المتوقعة !! انظر الناتج





MONTHS_BETWEEN('11-11-99','10-10-99')

-------------------------------------

1.03225806




تحدي للمحترفين الأذكياء فقط !! .... بالله عليك .. كيف جاء هذا الكسر ؟؟؟


التحدي الثالث هو كيف جاء هذا الكسر ..؟؟ ولماذا جاء ؟؟وما هو هذا الكسر اصلا ؟؟؟؟؟ فسر !!


....


الان اريد عرض كم شهر مضى على الموظفين من تواريخ توظيفهم وحتى الان !!

حتى الان ؟؟ من أين نأتي بتاريخ الحالي ؟؟؟؟

اليك جملة الاستعلام !!





select ename ,months_between(sysdate,hiredate) A from emp ;




والناتج هو ...








ENAME A

---------- ----------

SMITH 300.414125

ALLEN 298.317351

WARD 298.252835

JONES 296.897996

MARTIN 291.059286

BLAKE 295.930254

CLARK 294.672189

SCOTT 224.349609

KING 289.414125

TURNER 291.704447

ADAMS 223.220576

JAMES 288.865738

FORD 288.865738

MILLER 287.220576




جاءك المدير ... (نفس ذلك المعقد ) وقرأ النتيجة السابقة ... وقال لك .. " ما هذا يا مهمل !! لا اعرف ان اقرأ هذه !!!.

لا اريد عدد الشهور ... اريد عدد السنوات !!"


ما العمل ؟؟؟ ما الذي نستطيع فعله في هذه الحالة ؟؟؟ هل تعرف ؟؟

فكر قبل ان تشاهد الحل !! ...


أحب ان أشير الى نقطة .. هو ان 99.99999% منكم ... حسب ما اعتقد... انه يقرأ فقط بدون تفكير ..

هل يجب علي ان أذكرك في كل مثال ان تفكر اولا ؟؟ اعرف انك تحك رأسك الان وسوف تفكر في الحل ...

جميل جدا .....

اليك الحل ..

عدد السنين = عدد الشهور / 12 !!

12 شهر = 1 سنة ... صح ؟؟

24 شهر = 2 سنة ... صح ؟؟

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

اخذنا مثلا 24 .. وقسمناها على 12 وصار الناتج 2 ,,





انظر ....





select ename , months_between(sysdate,hiredate)/12 A, hiredate B from emp ;




وانظر الناتج ....





ENAME A B

---------- ---------- --------

SMITH 25.0345137 17/12/80

ALLEN 24.8597825 20/02/81

WARD 24.8544061 22/02/81

JONES 24.7415029 02/04/81

MARTIN 24.2549438 28/09/81

BLAKE 24.6608578 01/05/81

CLARK 24.556019 09/06/81

SCOTT 18.695804 19/04/87

KING 24.117847 17/11/81

TURNER 24.3087072 08/09/81

ADAMS 18.601718 23/05/87

JAMES 24.0721481 03/12/81

FORD 24.0721481 03/12/81

MILLER 23.9350513 23/01/82







نظر المدير .. الى النتيجة ... ثم نظر اليك وكأنه يريد قتلك .... لماذا ؟؟ لأنها مازالت غير سهلة القراءة ..


لا يريد هذه الأرقام بالكسور .. يريدها هكذا .. 25 سنة .. 26 سنة ..... الخ ... مالعمل ؟ فكر فكر فكر فكر ......

خذ الحل ...





select ename, ROUND(months_between(sysdate,hiredate)/12,0)||' years' A from emp ;




النتيجة .... كما يلي ... سهلة القراءة ,,,





ENAME A

---------- ---------

SMITH 25 years

ALLEN 25 years

WARD 25 years

JONES 25 years

MARTIN 24 years

BLAKE 25 years

CLARK 25 years

SCOTT 19 years

KING 24 years

TURNER 24 years

ADAMS 19 years

JAMES 24 years

FORD 24 years

MILLER 24 years







اليك تحدي من نوع خاص جدا ...

بينما كنت اكتب هذه السطور .. واذا بعقلي يخبرني انه يريد عرض نتيجة كهذه !! (من جدول الموظفين ) :







YEARS MONTHS DAYS HIREDATE SYSDATE

----- ---------- ---------- -------- --------

25 0 12 17/12/80 29/12/05

24 10 9 20/02/81 29/12/05

24 10 7 22/02/81 29/12/05

24 8 27 02/04/81 29/12/05

24 3 1 28/09/81 29/12/05

24 7 28 01/05/81 29/12/05

24 6 20 09/06/81 29/12/05

18 8 10 19/04/87 29/12/05

24 1 12 17/11/81 29/12/05

24 3 21 08/09/81 29/12/05

18 7 6 23/05/87 29/12/05

24 0 26 03/12/81 29/12/05

24 0 26 03/12/81 29/12/05

23 11 6 23/01/82 29/12/05




جلست عشر دقائق (عشر دقائق كثيرة هاه ؟؟) في معرفة الحل .. أخيرا تمكنت ^^ ... هل تعرف لماذا تمكنت !!؟؟ لأني أردت ان اعرف ! الإرادة هي أهم شيء ,, والحاجة هي أم الاختراع ,,

طبعا عرض الفرق بعدد السنين ... ولكن بدون كسور هذه المرة ... بل بالشهور والأيام !! مثلا ....

10/10/2000 و 9/9/1999 بينهما سنة .. وشهر ... ويوم .. صح !! هل تعرف كيفية عمل جملة استعلام كهذه ؟؟

لا تتعب نفسك كثيرا .. ولا تحبط نفسك اذا رأيت الجملة ...

ان هذه الجملة ... لا يخرجها إلا ذوي الباع الطويل في البرمجة !! .. وستخرج اعقد منها يوما ما .. قريبا ان شاء الله .. فلا تخف ولا تحزن ,, وعلى فكرة ... من سيطلب منك ذلك غير مديرنا المعقد ؟؟؟ لا اعتقد احد سيفعل ذلك ,,

يعني اذا كنت مبتدأ .. او متوسط ... او حتى خبير في بعض الأحيان .. من الممكن ان لا تتمكن من عملها ..

انظر إليها ... وأريد من هذا التحدي شيء واحد .. تفسير الجملة .. بشكل منطقي ومعقول ,, هل تستطيع ؟؟


وهو التحدي الرابع !!







select TRUNC(months_between(sysdate,hiredate)/12) years

,TRUNC( months_between(sysdate,hiredate),0)-TRUNC(months_between(sysdate,hiredate)/12)*12 months

, TRUNC( MOD(months_between(sysdate,hiredate)*31,31),0) days

, hiredate ,sysdate from emp ;







اكثرت عليكم في هذه الدالة .. ولكن فيها تفكير كثير برمجيا .. لذا احببت ان تفكروا كثيرا ,,





الدالة :ADD_MONTHS


العمل :اضافة عدد من الشهور الى تاريخ ما ,,,


الأمثلة :


اذا اردت ان تعرف كم التاريخ بعد 100 شهر من الان .... مالذي عليك فعله ؟؟

اليك جملة الاستعلام التالية والتي تفيد الى اننا نضيف الى تاريخ توظيف الموظفين 100 شهر ....












select add_months(hiredate,100) , hiredate from emp ;







انظر الناتج





ADD_MONT HIREDATE

-------- --------

17/04/89 17/12/80

20/06/89 20/02/81

22/06/89 22/02/81

02/08/89 02/04/81

28/01/90 28/09/81

01/09/89 01/05/81

09/10/89 09/06/81

19/08/95 19/04/87

17/03/90 17/11/81

08/01/90 08/09/81

23/09/95 23/05/87

03/04/90 03/12/81

03/04/90 03/12/81

23/05/90 23/01/82







اعتقد انها سهلة .... وليست بتلك الصعوبة ...

نريد اضافة 5 سنوات ... مالذي يحدث ؟؟

فكر فكر فكر ....

نظيف 5 * 12 ... يعني 60 شهر .... فكر فيها قليلا ... وانظر الجملة ..





select add_months(hiredate,6*12) , hiredate from emp ;







النتيجة ...





ADD_MONT HIREDATE

-------- --------

17/12/86 17/12/80

20/02/87 20/02/81

22/02/87 22/02/81

02/04/87 02/04/81

28/09/87 28/09/81

01/05/87 01/05/81

09/06/87 09/06/81

19/04/93 19/04/87

17/11/87 17/11/81

08/09/87 08/09/81

23/05/93 23/05/87

03/12/87 03/12/81

03/12/87 03/12/81

23/01/88 23/01/82







سهلة !!





انتهى الدرس هنا .. ولم تنتهي جملة الدوال ....

في الدروس القادمة سنكمل الدوال الاحادية ... ان شاء الله ... ثم المتعددة ....

وسيكون بعدها دروس لدرجة الاحتراف ان شاء الله .. في لغة الSQL


اتوقع 5 دورس ان شاء الله وننتهي من الـ SQL


وحتى ذلك الموعد احفظ الدوال صم !!!

الى اللقاء

The Coder
30-12-2005, 10:20 PM
اوبس ... نسيت ..
التحديات .... اريدكم ان تضعوها في موضوع الاستفسارات ..
والذي لا يستطيع !!
يرسلها لي ,,,

اليك التحدي الأول !!


لو كتبنا الأمر التالي ....





select initcap(upper(lower('HI My friends ^^'))) from dual ;




مالذي سوف ينتج ؟؟؟؟

ولماذا نتج ما نتج ؟؟ مع تفصيل شرحك ,,,,

ارجو منك عدم استخدام البرنامج لمعرفة النتيجة ...

انت اجلس مع نفسك .. وتوقع النتيجة على الورق ,,

وأنا لم اشرح هذا الجزء المهم من الدوال لغرض ما في نفسي ,,





التحدي الثاني ... وهو تحدي للمحترفين فقط !! اكرر للمحترفين ,,...

اريد ان اعرض أسماء الموظفين في عمود

وأريد عرض أسماء الموظفين ماعدا الحرف الأخير مقصوص منه في عمود اخر

وأريد عرض الحرف الأخير من أسماء الموظفين في عمود ثالث !!

يعني اريد الناتج بهذه الصورة :







A B C

---------- - -------

SMIT H SMITH

ALLE N ALLEN

WAR D WARD

JONE S JONES

MARTI N MARTIN

BLAK E BLAKE

CLAR K CLARK

SCOT T SCOTT

KIN G KING

TURNE R TURNER

ADAM S ADAMS

JAME S JAMES

FOR D FORD

MILLE R MILLER




صعب هاه ؟؟

اريد تصعيبه اكثر وأكثر ..

اريد عرضه بهذا الشكل !! :









ALL_OF_THEM

--------------------

SMIT + H = SMITH

ALLE + N = ALLEN

WAR + D = WARD

JONE + S = JONES

MARTI + N = MARTIN

BLAK + E = BLAKE

CLAR + K = CLARK

SCOT + T = SCOTT

KIN + G = KING

TURNE + R = TURNER

ADAM + S = ADAMS

JAME + S = JAMES

FOR + D = FORD

MILLE + R = MILLER




في عمود واحد يدعى all_of_them !!




التحدي الثالث ...





select months_between('11-11-99','10-10-99') from dual ;




ماهي النتيجة ؟؟ ماهو المتوقع !!


نحن قلنا ان الدالة ترجع (ترجع = تخرج) فقط عدد .... وهذا العدد المفترض بأن يكون عدد الأيام !! صح ؟؟

غلط ... بل عدد الأشهر !!

الان كم الأشهر المتوقعة !! انظر الناتج





MONTHS_BETWEEN('11-11-99','10-10-99')

-------------------------------------

1.03225806




تحدي للمحترفين الأذكياء فقط !! .... بالله عليك .. كيف جاء هذا الكسر ؟؟؟


التحدي الثالث هو كيف جاء هذا الكسر ..؟؟ ولماذا جاء ؟؟وما هو هذا الكسر اصلا ؟؟؟؟؟ فسر !!




التحدي الرابع

.. تفسير الجملة .. بشكل منطقي ومعقول ,, هل تستطيع ؟؟









select TRUNC(months_between(sysdate,hiredate)/12) years

,TRUNC( months_between(sysdate,hiredate),0)-TRUNC(months_between(sysdate,hiredate)/12)*12 months

, TRUNC( MOD(months_between(sysdate,hiredate)*31,31),0) days

, hiredate ,sysdate from emp ;

The Coder
04-01-2006, 09:31 PM
بسم الله الرحمن الرحيم


الدرس التاسع


اسم الدرس : جملة الاستعلام select والدوال


نوع الدرس : تطبيقي


صعوبة الدرس : *** من *****


اهميــة الدرس : ****** من ***** (Over)


درجة احتراف لغةSQL المتوقعة بعد هذا الدرس : ** من ***** (مبتدئ متقدم )


الوقت المتوقع منك لفهم الدرس : 11 ساعة (ثلاث ساعات فهم و 8 ساعات تطبيق )


متطلبات تتوفر فيك : التطبيق





المتوقع منك في هذا الدرس :


- اتقان جزء من هذه اللغة 100 %


- اتقان الدوال الاحادية .


- اتقان الدوال المتعددة .


هيا لنؤركل ^^





السلام عليكم


قبل البدء اشير الى انه من الافضل ان تحل الواجبات والتحديات .. وان لا ترسلها لي .. بل اعرضها في موضوع استفسارات الاوراكل ...


لكي يتم المناقشة فيها ....


اخذنا الدوال الاحادية ووصلنا عند الدالة add_months ..


نكمل الدوال الاحادية الصف.... ونكمل بقية الدوال الخاصة بالتاريخ





الدالة :NEXT_DAY


العمل :لو أردت تاريخ الجمعة القادم ... هذه الدالة ستوجد ذلك التاريخ ,,,


الأمثلة :


اريد عرض تاريخ الجمعة القادم ... يعني اقرب يوم جمعة .. تخيل لو اليوم أربعاء .. وتاريخ اليوم 10/10/1960 م (اعرف ان التاريخ قديم) فإن تاريخ اقرب يوم جمعة هو تاريخ بعد بكرة ... يعني 12/10/1960 م .... هل فهمت معنى الجمعة القادم ؟؟


يوم كتابة هذه السطور .. هو يوم الجمعة ... تاريخ 30/12/2005 م ..... اوبس ... غدا سيكون هنالك سنة جديدة .. وانا لا اعلم ... لا يهم ,,,


المهم اريد يوم الجمعة القادم ... بتاريخ كم ؟؟ طبعا يا 6/1/2006 م او 7/1/2006 م ... ربما يكون الشهر الحالي 31 يوم ... المهم لنرى عبر الجملة التالية ..









select next_day (sysdate,'FRIDAY') from dual ;





والنتيجة هي ....






ERROR at line 1:


ORA-01846: not a valid day of the week





اوبس .. لماذا كلمة FRIDAY خاطئة ؟؟


قد تستغرب يا صاحبي .. ولكن النظام الخاص بكمبيوتري عربي !!


لذا .. فإن الجملة يجب ان تكون ...






select sysdate , next_day(sysdate,'الجمعة') from dual ;








والنتيجة هي ...






SYSDATE NEXT_DAY


-------- --------


30/12/05 06/01/06








هل فهمت ^^ ...





مثلا نريد عرض تاريخ الجمعة القادم لتاريخ التوظيف لكل موظف ... هل نشاهد ذلك ؟؟ هيا ..









select hiredate , next_day(hiredate,'الجمعة') from emp ;





والنتيجة ...









HIREDATE NEXT_DAY


-------- --------


17/12/80 19/12/80


20/02/81 27/02/81


22/02/81 27/02/81


02/04/81 03/04/81


28/09/81 02/10/81


01/05/81 08/05/81


09/06/81 12/06/81


19/04/87 24/04/87


17/11/81 20/11/81


08/09/81 11/09/81


23/05/87 29/05/87


03/12/81 04/12/81


03/12/81 04/12/81


23/01/82 29/01/82





ممممم .... الدالة التالية ...





الدالة :LAST_DAY


العمل :توجد تاريخ اخر يوم من شهر ما ,,


الأمثلة :


هل تذكر حينما قلت لك تاريخ الجمعة القادم وكان في 6/1/2006 ؟؟


لماذا لم يكن في 7/1/2006 ؟؟ لان الشهر الحالي .. كان 31 يوما ...


اريد ان اعرف كم عدد ايام الشهر الحالي .. هل صحيح 31 يوما ؟؟؟









select last_day(sysdate) from dual ;








اليك النتيجة






LAST_DAY


--------


31/12/05





.... صح ,,


ممممم .. لا توجد أمثلة في رأسي لهذه الدالة ... ولكن فكر انت لماذا عملت هذه الدالة ...





المهم اعتقد انه يوجد دالتين للتاريخ ... ولكن لما طبقتهم .. لم يستجيبوا معي .... لا اعرف لماذا ولكن ... اعتقد لأن المنهج قديم ؟؟ لا اعرف .. وكأنه يستخدم إصدار قديم للأوراكل ... انسى أمرهما الان ,,,,





د- دوال لأغراض التحويل Conversion Functions


انتهينا من الدوال الحرفية .. والدوال الرقمية .. ودوال التاريخ ...


والان نحن سنغطي دوال مهمة وهي دوال التحويل


وبعدها سوف ننتهي من الدوال الاحادية الصفوف ,,


اريدك ان تعرف الان جزئية مهمة جدا ...


كم نوع من البيانات موجودة في الأوراكل ؟؟ (ما معنى البيانات ؟؟ راجع الدرس الخامس !!)


الان وفي الوقت الحالي ... اريدك ان تعرف ثلاث ..


حرفية (أو نصية )..... و رقمية ..... و تواريخ ,,,


اريدك ان تعرف ان النص = مجموعة حروف .....


الان بالله عليك قلي ... هذا النوع (11/10/1999) ما هو ؟؟؟


تاريخ ؟؟ خطأ !!


نص ؟؟ خطأ !!!


رقم ؟؟؟ خطأ !!!


هذا يا حبيبي من الممكن يكون تاريخ ومن الممكن يكون نص !! لا احد يعرف !!


طبعا مستحيل يكون رقمي .. لأنه يوجد هذا الحرف / ,,


قلنا من قبل ان التواريخ تشبه النصوص .. ولكن النصوص لا تشبه التواريخ !! كيف ؟ انا أخبرك ,,


النص = حروف أبجدية + حروف اخرى + أرقام حرفية !!


لاحظ انه يوجد فرق بين الأرقام الحرفية والأرقام الرقمية ... الأرقام الحرفية للعرض فقط كنص !! اذا لم تفهم .. تجاهل الموضوع الان


المهم ... الحروف الأبجدية .. مثلا بالانجليزي ABC…..abcd….. .....الخ ..


الحروف الأخرى هي مثل / * - + _=)(>&<......... الخ


هل فهمت معنى النص !!


كيف يعرف برنامج الأوراكل ان هذا نص .. وهذا رقم .. وهذا تاريخ ؟؟


بسيطة .. مثلا هذا نص 'abc_545' ,,, كيف عرف ؟ من علامتي التنصيص الأحادية !!


ونفس الفكرة للتاريخ ولكن للتواريخ أشكال معينة ستعرفها الان ...





نرجع الى دوال التحويل ..


أي رقم في الدنيا ... بإمكاننا ان نحوله نص صح ؟؟


أي تاريخ في الدنيا ... بإمكاننا ان نحوله نص صح ؟؟؟


لكن ....


ليس كل نص يصبح رقم .. وليس كل نص يصبح تاريخ !!


سوف تشاهد الدوال وتعرف ما كنت اقصده !!

The Coder
04-01-2006, 09:54 PM
الدالة :TO_NUMBER


العمل :تحويل نص الى رقم ..... بمعنى اخر تحويل الأرقام الحرفية الى أرقام حسابية


الأمثلة :


قبل ان تستخدمها ... هل تتوقع لو ادخلنا النص التالي "SYUTYRE123" هل سيتحول الى رقم ؟

طبعا لا ...

لانه يوجد حروف ابجدية ......

لو ادخلنا النص التالي "7894" هل سيتحول هذا النص الى رقم ؟؟ نعم بالطبع .. سيتحول الى 7894 ,,


اذن يجب ان يكون النص المدخل حروفه ارقام حرفية فقط!!





هل تذكر EMPNO ؟؟ وهو رقم الموظف !!

هل هو نوع رقمي ام حرفي ؟؟

هو نوع رقمي !! يعني لو ادخلنا h456 كرقم للموظف .. فسيعطي خطأ !!

تخيل لو انه نوع حرفي ... هل يصح ؟؟؟ طبعا يصح ,, لأن النصوص بإمكانها ان تكون ارقام فقط !!

الان لو قلنا ...









select job+1 from emp ;








مع العلم ان الـ JOB نوع نصي وليس رقمي .. بالله عليك كم نتيجة عمل+1 = ؟؟؟

خطأ في خطأ !!

كيف نضيف الى العمل الرقم واحد ؟؟؟ النص للعرض وليس للحساب !!

هل عرفت ان هذه حركة غبية ؟؟

لو ان الحقل EMPNO نوع نصي ... تخيل ذلك ...

ونريد ان نعمل بعض الحسابات ... هل نستطيع ؟ طبعا لا ...

الان ..

تخيل لو ان EMPNO حقل نصي (بالخطأ صار حقل نصي )

اريد اعرض أرقام الموظفين جميعهم ولكن مضاف إليها 100 مثلا !! ماذا نعمل ؟؟

نحول حقل EMPNO النصي الى أرقام حسابية ... باستخدام الدالة TO_NUMBER


بدلا ان نقول ....






select empno+100 , empno from emp ;





والتي تعتبر خاطئة اذا ما اعتبرنا ان حقل EMPNO حقل نصي .... نقول ..






select TO_NUMBER(empno)+100 , empno from emp ;








والنتيجة ...








TO_NUMBER(EMPNO)+100 EMPNO

-------------------- ----------

7469 7369

7599 7499

7621 7521

7666 7566

7754 7654

7798 7698

7882 7782

7888 7788

7939 7839

7944 7844

7976 7876

8000 7900

8002 7902

8034 7934








مثلا

اريد ان اعرض معلومات صاحب الرقم 7782 + 6 .... مثلا ,,, ماهي الجملة ؟؟









select * from emp

where empno=7782+6 ;





تخيل لو ان EMPNO حقل نصي (بالخطأ صار حقل نصي ) .. .. هل جملة الاستعلام السابقة صحيحة ؟؟ طبعا لا .. ليست صحيحة !!

ماذا نعمل ؟؟

نحول حقل EMPNO النصي الى أرقام حسابية ... باستخدام الدالة TO_NUMBER






select * from emp

where TO_NUMBER(empno)=7782 + 6 ;





هل فهمت شيء ؟

يعني حول قيمة empno النصية الى قيمة رقمية !! هذا كل شيء ....

لا ارى تلك الأهمية لهذه الدالة ... ولا يوجد لدي في الوقت الراهن أي تطبيقات قوية لها ,,,





الدالة :TO_DATE


العمل :تحول نص الى وقت أو تاريخ ... مع العلم ان النص المدخل يجب ان يكون مكتوب بصيغة معينة


الأمثلة :


قبل البدء اريدك ان تعرف ان ...


Y تعني سنة ... اختصار لـ Year

M تعني شهر ... اختصار لـ Month

D تعني يوم ... اختصار لـ DAY

MI تعني دقيقة ... اختصار لـ Minute

H تعني ساعة ... اختصار لـ Hour

S تعني ثانية ... اختصار لـ Second




طيب ...

الموظف WARD ... لا اعرف متى ولد .. ولكن اعرف تاريخ تعيينه وهو 22 من شهر فبراير من عام 1981 م ....

اذا قلت لك اريد تاريخ الموظف WARD بهذا الشكل ... (اقرأ من اليسار الى اليمين)


DD-MM-YY .....


مالذي تتوقعه ؟؟ هل تعرف ؟؟

يعني هكذا


22-02-81


واذا قلت لك .... اريد تاريخه بهذا الشكل ... (اقرأ من اليسار الى اليمين)


DD/MM/YYYY


كيف نكتبها ؟

نكتبها هكذا :22/02/1981


لاحظ انه لا فرق بين / و بين - فكلاهما لهما غرض واحد ,,

لو اردنا تاريخه بهذه الصيغة ...


MM/SS/YY


فإن التاريخ يكتب هكذا ... 02/22/81


فهمت الفكرة ؟ يعني الفكرة هي التاريخ يجب ان يكون على الشكل المطلوب ....

يعني يجب ان يطابق التاريخ الشكل ... تذكر هذا جيدا !! يجب ان يطابق التاريخ الشكل !!!!

مثل الشكل .. DD/MM فإن التاريخ يكون 22/02


مثلا الشكل MM فإن التاريخ هكذا .. 02 ,,,




الان ... فكر كم شكل للتاريخ ؟؟ ثلاث أشكال ؟ خمس ؟ عشرون ؟؟

صراحة ... كثير ... وبالكيفية التي تريدها !!

تريد الايام ثم السنوات ثم الشهور ....

تريد شهور والسنوات فقط , جرب ما يحلوا لك ....

أحب ان أشير الى نقطة .. انه في بعض الأحيان ... نريد اسماء الشهور و الايام ...

مثلا اريد عرض معلومات الموظف الذي تم تعيينه في يوم الأحد في شهر فبراير في سنة 1981 م ....

أي التاريخ (من الشمال الى اليمين ):

SUNDAY FEBRUARY 1981


فإن الشكل ... هو(من الشمال الى اليمين ) :


DAY MONTH YYYY

DAY يعني يوم ... MONTH تعني شهر ,,,

هل رأيت كيف طابق التاريخ الشكل ؟؟؟

الان نبدأ مع هذه الدالة ...

تحول هذه الدالة نص على شكل معين .. الى تاريخ !!

وحتى الان لا ارى في هذه الدالة .. ودالة TO_NUMBER تلك الأهمية .. ولا اعرف لماذا عملوها اصلا ....

وجدت مثال واحد في منهجين مختلفين !! مثال غبي ...

الان اريد عرض معلومات الموظف الذي تاريخ تعيينه 22/02/1981








select * from emp

where hiredate=to_date('22/02/1981','dd/mm/yyyy') ;





وسوف تعرض نتيجة الموظف WARD الذي تحدثنا عنه قبل قليل ,,

الدالة تأخذ في المدخل الأول التاريخ بشكل نص , والمدخل الثاني شكل التاريخ , يجب ان يكون التاريخ مطابق للشكل ,,

اعتقد ان هذه الدالة .. تفي بالغرض عندما لا اعرف كيف تخزن التاريخ في قاعدة البيانات ..

يعني انا شخصيا .. التواريخ كتبت لي هكذا DD/MM/YY


وفي احد المناهج .. لاحظت ان التواريخ كتبت عنده هكذا DD/MM/YYYY


يعني مثلا اريد عرض معلومات الموظف الذي تعين في : فبراير 22/1981

ولا اعرف كيف تخزن .. فاجبر ان تكون النتيجة بشكل انا ارغبه ... ,,

مثلا الشكل MONTH , DD YYYY


ما جملة الاستعلام اللازمة ؟؟









select * from emp

where hiredate=to_date('February 22,1981' ,'month dd , yyyy') ;





وسوف تعرض معلومات الموظف WARD


وظهرت لي مشاكل .. متعلقة بالعربي والانجليزي ....

فجهازي عربي خالص ... بدل ان اقول February 22,1981 اقول "فبراير 22 , 1981"

وسوف تجد شكلها غبي جدا وغير مرتبة لان الاوراكل ببساطة انجليزي خالص ,,

المهم ... هل تصدق ان المثال السابق هو المثال الوحيد الذي وجدته !!

المشكلة لا تكمن هنا .. المصيبة انه ... بدلا من الجملة ...






select * from emp

where hiredate=to_date('22/02/1981','dd/mm/yyyy') ;







استطيع القول وبدون الدالة ...









select * from emp

where hiredate='22/02/1981';





لماذا هذه الدالة ؟؟؟

هل لأجل كتابة فبراير كاملة ... ام لأجل ماذا ؟؟

في دراستي الجامعية سابقا ... أتذكر ان دكتور مادتنا .. قال لنا "تجاهلوا موضوع التواريخ ... ليست في المقرر"

اعتقد انه رأى عدم أهمية أشكال التواريخ !! ... اعتقد ذلك ,

لذا ... فسوف أتجاهل هذه الدالة ,, وحتى إشعار اخر !!




الان اليك دالة قوية جدا !!


الدالة :TO_CHAR


العمل :تحويل الرقم الى نص .. وتحويل التاريخ الى نص !!


الأمثلة :


لماذا هذه الدالة ؟ لعرض التواريخ والارقام بالأشكال التي نرغبها ,,

لها مدخلان ....(2 Parameters)


المدخل الاول ... يفترض بأن يكون به .. يا رقم .. او تاريخ ...

المدخل الثاني ... يفترض بأن يكون نص !!

اذا كان المدخل الاول رقم .. فسوف يتم تحويله الى نص .....

اذا كان المدخل الاول تاريخ .. فسوف يتم تحويله الى نص ...





- اولا تحويل الرقم الى نص ....

اذا كان المدخل الاول رقم .. فسوف يتم تحويله الى نص .....


رواتب الموظفين على سبيل المثال ستعرض هكذا ...


1000

3500

90000

1000000


صح ؟

اريد عرضها هكذا ..


$1000

$3500

….


او ... اريد عرضها هكذا ...


1000.00

3500.00

…..


او اريدها هكذا ....


$1,000

$1,000,000

….


او هكذا ...


$1,000.00

$1,000,000.00


لاحظ الفرق بين الفاصلة العشرية (النقطة)والفاصلة الكتابية (التي شكلها هكذا , )

أو اريد اعقد شكل وهو ..


$00,001,000.00

$00,003,500.00

$01,000,000.00


هل شاهدت هذا التعقيد !!

بل اريدها اربع ارقام يمين الفاصلة العشرية !!


$00,001,000.0000

$00,003,500.0000

$01,000,000.0000




مالذي اعمله ؟؟

باستخدام دالة تحويل الارقام الى نص .. نستطيع ان نعمل هذه الاشكال ...

اسمعني جيدا .. في هذه الدالة لا تستطيع ان تضع الا ثلاث حروف ,’,’,’,’,’,’,’

النقطة وهي الفاصلة العشرية

والفاصلة الحرفية

و علامة الدولار $


فقط !!

اريد ان اعرض الرواتب على هذا الشكل ...


$1000

$3500

$10000


لاحظ الراتب الاخير .. زائد بخانة عن بقية الرواتب ...

وهو اكبر الرواتب صح ؟؟

بالله عليك توقع معي .. كم اكثر عدد للخانات ؟؟

5 خانات .. وهو يمثل عدد خانات اكبر راتب ... 10000

اذن انظر جيدا كيفية استعمال الدالة ...









select to_char(sal,'$9999') from emp ;





اوبس !! ... ماهذه التسعات ؟؟ ولماذا ؟؟

معنى $9999 أي اعرض لي الراتب sal على هذه الصيغة ...

يعني لو 1000 اجعلها $1000


طيب لو 500 اجعلها $500 كما هي

طيب لو 1 اجعلها $1 كما هي ,,,

طيب لو 10000 هنا يظهر خطأ .... ولن تعرض شيء .. لماذا ؟؟ لأننا وضعنا 4 تسعات .. أي اربع خانات فقط

والعشرة الاف خمس خانات !! فيجب الحذر ,,

اليك النتيجة ^^








TO_CHA

------

$800

$1600

$1250

$2975

$1250

$2850

$2450

$3000

$5000

$1500

$1100

$950

$3000

$1300

The Coder
04-01-2006, 09:58 PM
طيب ... اريد وضع ارقام كسرية ... ولتكن .. ثلاث خانات !!

يعني بهذا الشكل


$1000.000

$3500.000

$500.000


مالذي اعمله ؟؟

بسيطة ..








select to_char(sal,'$9999.999') from emp ;







هل رأيت الفاصلة العشرية ؟؟ هل رأيت كم تسعة وضعناها ؟؟

يعني لو الراتب 1 اجعلها بهذا الشكل $1.000 هل فهمت ؟؟






TO_CHAR(SAL, '$9999.999')

----------

$800.000

$1600.000

$1250.000

$2975.000

$1250.000

$2850.000

$2450.000

$3000.000

$5000.000

$1500.000

$1100.000

$950.000

$3000.000

$1300.000





لو كان لدينا شخصين .. راتبهما كما يلي ...


500.5 خمس مئة ونصف دولار


20.25 عشرون و ربع دولار ,,

كيف ستكون النتيجة ؟؟

ستكون هكذا !!


$500.5

$20.25


ستعرض عادي .. كما هي ,,,

اريد ان اعقد الامور كعادتي ..

النتيجة السابقة ليست مرتبة ....

النتيجة السابقة شكلها هكذا ..


$1000.000

$500.000

$1.000


انا لا اريدها هكذا ...

اريد على هذا الشكل ....


$1000.000

$0500.000

$0001.000




هنا ... نضع الأمر هكذا ...








select to_char(sal,'$0000.000') from emp ;





فبدلا من تلك التسعات .. وضعنا اصفار !!

ما معنى التسعات وما معنى الاصفار ؟؟

رأينا كيف يكون في التسعات لو ان الراتب 1000 فسوف يكون شكله هكذا 1000.000


ولو كان الراتب 1 فان شكله يكون هكذا 1.000


الاصفار لها رأي اخر ... ففي جملة الاستعلام السابقة (الاخيرة).... لو جائنا راتب 1000


فإن شكله يصبح 1000.000 ولو ان الراتب 1 فإن شكله 0001.000 هل فهمت !!

طيب ... لكي اتأكد من انك فهمت ..

لماذا 0001.000 ؟؟ لماذا لم تكن 00000001.000 ؟؟

هل تعرف ؟؟

لا تعرف !!!!

انا اخبرك .... لأننا وضعنا اربع اصفار كأني اقول ... اجعلها اربع خانات !! هل فهمت ؟؟

لو كان لدينا شخصين .. راتبهما كما يلي ...


500.5 خمس مئة ونصف دولار


20.25 عشرون و ربع دولار ,,

كيف ستكون النتيجة ؟؟

ستكون هكذا !!


0500.500$

0020.250$




اوه نسيت عرض النتيجة الخاصة باخر جملة استعلام






TO_CHAR(SA

----------

$0800.000

$1600.000

$1250.000

$2975.000

$1250.000

$2850.000

$2450.000

$3000.000

$5000.000

$1500.000

$1100.000

$0950.000

$3000.000

$1300.000







لا اعرف هل عرضت بشكل متساوي ام لا , ولكن اذا كنت من النوع الذي يطبق معي .. فسوف يشاهدها بوضوح مع برنامج SQL PLUS !!




هل عرفت الان الفرق بين الاصفار والتسعات ؟؟ اعتقد واضحة !!

اريد عرض النتيجة التالية وهي اعقد جملة على الاطلاق !!!!!


$1,000,000.00

$0,001,000.00

$0,000,500.00


هل تعرف هذه الفواصل !! فرق بينها وبين الفواصل العشرية ,,

هذه الفواصل نشاهدها في المبالغ الكبيرة في البنوك ,,,


نريد ان نعرض رواتب الموظفين كما في النتيجة السابقة ... ماذا نعمل ؟؟

عادي ...






select to_char(sal,'$0,000,000.00') from emp ;







انظر انظر ... عادي جدا ...






TO_CHAR(SAL,'$

--------------

$0,000,800.00

$0,001,600.00

$0,001,250.00

$0,002,975.00

$0,001,250.00

$0,002,850.00

$0,002,450.00

$0,003,000.00

$0,005,000.00

$0,001,500.00

$0,001,100.00

$0,000,950.00

$0,003,000.00

$0,001,300.00







تحدي .... تحب التحديات ؟؟

لا تحبها ؟؟؟

سواء احببتها ام لم تحببها .. اليك اول تحدي !!


التحدي الاول ...

تخيل انه يوجد موظفين ارصدتهم في البنك مايلي ..


10.25 عشرة دولارات وربع ...


20.5 عشرون دولار ونصف ...


1000000.945 مليون دولار وتسع مئة وخمسة واربعون من العشرة ...

يوجد جدول يدعى بـ BANK مثلا .....

اريد عرض النتائج بهذه الصورة

$0,00,00,10.25

$0,00,00,20.5

$1,00,00,00.945




وهلم جر !!

ركز !! ... لماذا تركت هذا تحدي ؟؟ فكر جيدا ,,





-ثانيا .. تحويل التواريخ الى نصوص ,,


اذا كان المدخل الاول تاريخ .. فسوف يتم تحويله الى نص ...

المدخل الثاني ... له بعض الكلمات المحجوزة ... كلمات محجوزة يعني ... كلمات محددة لو وضعتها فهي صحيحة ..

اذا وضعت غيرها ... فسوف يأتيك خطأ !!

لذا ... تذكر الكلمات المحجوزة ,,,, وهي كثيرة ...

منها النقطة ومنها الفاصلة ومنها النقطتين : ومنها الـ /

ومنها الخاصة بالايام والشهور والسنوات والساعة والثانية والدقيقة ... وغيرها ,,,

اتينا الى دوخة قصص التواريخ ,,

اريد عرض تاريخ التعيين للموظفين .. بهذا الشكل .. :


TEUSDAY OF NOVEMBER 1981 IN 12:00:00 AM


يعني ...

الثلاثاء من شهر نوفمبر في عام 1981 في الساعة 12:00:00 صباحا !!

لم ندقق في الوقت .. بالرغم من أهميته !!


في الحقول التي من نوع تاريخ ... يجب ان يحتوي هذا التاريخ على وقت مصاحب له !!

يعني .. الحقل hiredate من نوع تاريخ ..... وليس من نوع نصي !!

نتوقع من الحقل hiredate ان يحتوي على وقت !! .... هل فهمت ؟؟

الان اريد عرض أوقات تعيين الموظفين .... اريد الساعات:الدقائق:الثواني ....

تذكر ان H يعني ساعة و MI يعني دقيقة .... و S تعني ثانية !!

و أريدها بنظام 12 ساعة وليس 24 ساعة !!





اليك جملة الاستعلام ...









select to_char(hiredate,'HH:MI:SS') from emp;





لا تسأل لماذا HH وليست H !!


وهي تعني خانتين للساعات .!!! ونفس الشيء للثواني والدقائق ..


هنا في هذا المثال ... الكلمات المحجوزة .. هي HH و : و MI و SS





TO_CHAR(

--------

12:00:00

12:00:00

12:00:00

12:00:00

12:00:00

12:00:00

12:00:00

12:00:00

12:00:00

12:00:00

12:00:00

12:00:00

12:00:00

12:00:00







هل شاهدت ذلك !! ...

عمود hiredate والذي كنا نعتقد انه للتاريخ ... يحتوي على وقت ايضا !!

طيب .... حل اخر ... بنفس الفكرة ...






select to_char(hiredate,'HH12:MI:SS') from emp;







مالفرق بينه وبين السابق ؟

وجود 12 بجانب الـ HH وهو يشير الى نظام الـ12 !!

صراحة كلاهما نفس المعنى .. ويشيران الى نظام الـ12 ساعة !!

الدالة هذه ... لها مدخلين .. تأتي وتنظر الى المدخل الاول ... ياسلام .. هل رقم ام تاريخ ؟؟

اذا رقم .... تنظر الى المدخل الثاني .. ويجب ان يحتوي على 0 او 9 او فاصلة عشرية او فاصلة عادية او الـ$ فقط !!

اذا تاريخ .. تنظر الى المدخل الثاني ... يجب ان يحتوي على احد رموز السنوات او الايام او الساعات او أي رمز !!

اذا اردنا عرض نظام الـ 24 ساعة !! ,,, ماذا نعمل ؟؟

الذي لا يفهم في هذه النظامين أقول له ..

يا سيدي .... اتق الله في نفسك .. وحاول ان تفهم الان ....

نظام الـ12 ساعة .... هو من 1 الى 12 ... وتعيد الكرة .... من 1 الى 12 !!

يعني توجد الساعة واحدة صباحا ... وتوجد الساعة واحدة ليلا !!

اما في نظام الـ24 ساعة .. فهي من 1 الى 24 !!

يعني توجد في نظام الـ24 ..... الساعة 13 (نفس الساعة الواحدة صباحا بنظام الـ12).... وتوجد الساعة 1 ليلا !!

طيب .. الساعة التاسعة ليلا .. كم ؟؟؟ أي الساعة 21 !!

طيب التاسعة نهارا ؟؟ أي الساعة 9 !!

الساعة الحادية عشر ليلا .. كم ؟؟ أي الساعة 23 !!

الساعة الثانية عشر ليلا .. كم بالنظام 24 ؟؟ أي الساعة 00:00:00

أي الساعة صفر ..... هل فهمت !! لم تفهم ؟؟؟ اركب الطائرات كثيرا ... فسوف تجدهم يستخدمونها !! او اشتري ساعة الكترونية (كما اشتريتها انا حينما كنت طفلا !! ... فهمت هذا النظام وقتها !! ).... وستفهمها .. صدقني !!

على فكرة ...في نظام الـ12 ساعة ....

الساعة الثانية عشر ليلا ... يقولون عنها انها الثانية عشر صباحا !! ... والساعة الواحدة صباحا

هل تذكر قديما .. قبل سنين ... اخر جملة استعلام كتبناها ؟؟؟

انظر اليها ؟؟ وانظر الى نتيجتها .....

كانت النتائج هكذا ...


12:00:00

...

..

.


الخخخخ ....


بالله عليك .. هل 12 صباحا ام مساء ؟؟

وما أدرى مديرك .... لما يرى النتيجة .. هل بنظام الـ24 ساعة ام بنظام الـ 12 ساعة ؟؟

لا احد يعلم ....

هل تريد الحل ؟؟ لا تعرضها 12:00:00 وحسب !!

اعرضها هكذا


12:00:00 AM


او


12:00:00 PM


يعني بالعربي ... 12:00:00 ص أو 12:00:00 م

ماذا نعمل ؟

اليك جملة الاستعلام هذه ..








select to_char(hiredate,'HH:MI:SS AM') from emp;





هل شاهدت الـ AM لا تعني AM فقط ... بل تعني اعرض لي ... ما اذا كان صباحا ام مساءا (AM OR PM)


طبعا النتيجة المتوقعة هي ...


12:00:00 AM


او


12:00:00 PM




على حسب ....

وبما ان ساعة النظام الخاصة بجهازي ... عربي .... فسوف تعرض لي انا ... ومن هم على شاكلتي .. هذه النتيجة

12:00:00 ص

او

12:00:00 م





المهم ... نريد عرض الوقت بنظام الـ 24 ساعة .... كيف ؟

هل تعرف ؟؟ بسيطة ..








elect to_char(hiredate,'HH24:MI:SS') from emp;







مثال ...

حصلت جريمة في وقت تعيين احد الموظفين ... الجريمة كانت ليلا !! .... اريد ان احصر عدد الموظفين الذين تعينوا ليلا !! .... ماذا اعمل ؟؟ لا يهمني الساعة .. بل يهمني ليلا ام نهارا ؟؟

يعني اريد عرضها بهذا الشكل ...








A ENAME

- ------

AM SMITH

AM ALLEN

AM WARD

PM JONES

PM MARTIN

AM BLAKE

AM CLARK

AM SCOTT

AM KING

AM TURNER

AM ADAMS

AM JAMES

AM FORD

AM MILLER





من النتيجة يظهر تورط مارتن وجونس !!

المهم ... ما هي الجملة ؟؟








select to_char(hiredate,'AM') A,ename from emp ;







هل شاهدت ذلك ؟؟

ما معنى AM في المدخل الثاني ؟؟

هل معناها صباحا فقط ؟؟ لا !!

الدالة ... ترى .... في المدخل الثاني AM ..


وتقول ... "ممممم ... يوجد AM في المدخل الثاني ؟؟ اذن هذا المستخدم يريدني ان اعرض له صباحا ام مساء !! "

هل فهمت الفكرة ؟؟

انا متأكد ان هنالك من لم يفهم .. وأغلق الدرس كله ...

The Coder
04-01-2006, 10:15 PM
اليك مثال .. فيه تلاعب في الطريقة هذه ....

طيب .. لا اريد عرض الساعات : الدقائق : الثواني

اريد عرض الدقائق : الثواني : الساعات ثم صباحا ام مساء ...


واو .. ملخبطة ... ولكنني اريد عرضها بالشكل السابق !!


ماذا اعمل ؟

اليك الجملة ....








select to_char(hiredate,'MI:SS:HH AM') from emp ;







هل فهمت !!

نريد التعقيد اكثر و اكثر .... !! ..


لا اريد عرض الدقائق والثواني ... يهمني عرض الساعات و الايام فقط لا غير ...

يعني على هذا الشكل !! (اليوم .. والساعة)

الاحد 12

الثلاثاء 10

الاثنين 6





اليك الجملة !!








select to_char(hiredate,'DAY HH') from emp ;







معنى DAY أي اعرض لي اليوم ماهو .... والساعة .. لتاريخ تعيين الموظف !!

كل مافي الفكرة يا ناس ... ان الدالة تشاهد المدخل الثاني .... وترى ..

اذا DAY حولته الى اليوم .. بالنطق !!

اذا dd حولته الى اليوم بالرقم ...

اذا mm حولته الى الشهر بالرقم

يعني .. احفظ بعض المصطلحات ... واكتبها في المدخل الثاني .. وسوف تحولها الدالة ... هذا كل شيء !!





اليك مثال معقد جدا .... وهو اعقد مثال في هذه الدالة ..... ان فهمته .. فستفهم كل ما سبق !!

اريد عرض تواريخ التعيين للموظفين على هذه الصورة !!


TEUSDAY OF NOVEMBER 1981 IN 12:00:00 AM


هل شاهدت كلمة OF و كلمة IN ؟؟؟

كيف نعرضها ؟؟

اليك الجملة ... واذا لم تفهمها ... فسوف اعرض لك مثال اخر واخير ....








select to_char(hiredate,'DAY "OF" MONTH YYYY "IN" HH:MI:SS AM') from emp ;





هل شاهدت كلمتي OF و IN ؟؟

وضعناها بين علامتي تنصيص ثنائية وكأني اقول .. اعرض هذه الكلمة كما هي عليه



.. اذا لم تفهم .. فلا تقلق ... فانا اعتبره مستوى شبه متقدم .... بالرغم من سهولتها ...

الفكرة .... هي ما تكتبه في المدخل الثاني ... سواء يوم شهر .. سنة ... صباح ام مساء !! .. فسوف يعرض لك بالكيفية التي كتبتها ..

اليك مثال اخير ...

اريد ان اعرض وقت وتاريخ اليوم ... الحالي !!

ماذا اعمل ؟ اريدها بهذه الصيغة


TODAY … IS SUNDAY OF JANUARY … AND THE TIME IS 02:58:05 PM


أي

اليوم .. هو الاحد من يناير .. والوقت هو 02:58:05 مساء .....

اذا كنت تحب التحديات .... فهو تحدي لك ... ولكن اجابته بالاسفل !!

جرب نفسك .. وواجه نفسك .... حاول كتابتها .. ارجع واقرأ الدرس من جديد ....

يجب ان تكتب الجملة بنفسك ..

انا لم اضع الجملة الا لمن لم يفهم ...

انظر الاجابة .. وكلي ثقة بأنك فكرت فيها ... سواء عرفتها ام لم تعرفها !!








select to_char(sysdate,'"TODAY... IS" day "OF" month "...AND THE TIME IS" hh:mi:ss am') from dual ;







لن اعرض النتيجة ... ولكن ..... اذا لم تفهم .... اطرح أسألتك في موضوع الاستفسارات !!

وعلى فكرة ... قصدي من هذا التلاعب ليس الـ SQL فقط !!

بل سوف تنفعنا كثيرا في المستقبل ..... ثق بي .. الدالة to_char رهيبة !!

كل الامر هو ان المدخل الثاني به بعض الكلمات المحجوزة ... احفظها واستخدمها فقط !! هذا كل شيء !!

واذا اردت مثلا اليوم .. اكتب DAY في المدخل الثاني ... واذا اردت الشهر ... اكتب MONTH وهكذا !!!





اشير الى بعض النقاط والتي اعتبرها زيادة ولكن يجب عدم اغفالها اذا كنا نعمل تحت قطاع يهتم بالتواريخ ومفاهيمها ..


- من الممكن ان لا تعرض لك هكذا ...


Sunday January


بل تعرض مختصرة في بعض الاحيان ...


Sun Jan


لعرض اليوم مختصر ... لا تكتب day في المدخل الثاني .. بل dy


اما الشهر ... MON وليس MONTH


- من الممكن ان نعرض السنة ... بالنطق ... وليست بالارقام ... مثلا الفين وستة .. بدلا من 2006

وذلك بكتابة year بدلا من yyyy




- من الممكن ان اعرض تاريخ اليوم .. بدلا من 26 ... اقول السادس والعشرون ...





- من الممكن عرض السنوات ما اذا كانت سنة كبيسة ام لا ...




باختصار ... مسئلة الوقت والتاريخ ... مسئلة معقدة وكبيرة قليلا ...

اريد تعليمك الـ SQL وليس التواريخ و الأوقات !!

وايضا تحويل الارقام الى نص باستخدام هذه الدالة .. فيها شغل كثير .. سوف نتطرق اليها فيما بعد في لغة الـ PLSQL ان شاء الله اذا احتجناها ... اكرر .. اذا احتجناها !!

لكي ابري ذمتي .. عملت أمثلة على أهم النقاط التي واجهتني في تحويل التاريخ الى نص ....




اولا السنين ,,








select to_char(sysdate , 'yyyy year YEAR Year y,yyy yyy yy y ') from dual ;





النتيجة سوف تكون مثل هذه ..


2006 two thousand six TWO THOUSAND SIX Two Thousand Six 2,006 006 06 6


حيث ان yyyy تعني 2006

وان year عرض السنة كتابة .. ولكن بحروف صغيرة ...

وان YEAR نفس السابقة بحروف كبيرة

وان Year سيكون اول حرف كبير ...

وان الـ y,yyy ستعرض السنة 2.006

وان الـ yyy ستعرض السنة هكذا 006


وان الـ yy ستعرض السنة 06

وان الـ y ستعرض السنة 6





لاحظ ان النقطة (الفاصلة العشرية) ... والفاصلة العادية ... والـ / بامكاننا ان نضعها ولن يحدث خطأ ..







الان مع الأشهر ,,,,








select to_char(sysdate ,'MONTH month Month mon mm RM ') from dual ;





سوف تكون النتيجة بهذه الصورة ...


JANUARY january January jan 01 I


حيث ان MONTH عرض الشهر بحروف كبيرة ...

وان month عرض اسم الشهر بحروف صغيرة

وان Month عرض اسم الشهر بحرف كبير اولا ثم حروف صغيرة

وان mon عرض اول ثلاث حروف من الشهر ... طبعا بحروف صغيرة .. لو كتبنا MON فسوف تعرض بحروف كبيرة ..

وان mm فسيعرض الشهر رقما ... أي 01

وان الـ RM سيعرض الشهر بالحروف الرومانية ... أي I


لو الشهر اثنين فسوف يعرض بالحروف الرومانية II


لو ثلاثة .. III


لو اربعة . IV


لو ثمانية VIII


لو عشرة X


وهكذا ....

The Coder
04-01-2006, 10:42 PM
الان دارت الايام ,,,






select to_char(sysdate,'day DAY Day dy ddd dd d ') from dual ;





سوف تعرض النتيجة بهذا الشكل .... (على سبيل المثال)


Sunday SUNDAY Sunday sun 058 04 2


معنى ..


day أي عرض اسم اليوم بحروف صغيرة ..... sunday

DAY عرض اسم اليوم بحروف كبيرة .. SUNDAY

Day عرض اسم اليوم بالحرف الاول كبير وبعده صغيرة ...Sunday

dy عرض اول ثلاث حروف من اسم اليوم sun .. لو كانت Dy فستعرض Sun ولو كانت DY فستعرض SUN

ddd سوف يعرض اليوم من السنة ... يعني ان في السنة 365 يوم تقريبا ... ففي التاريخ الحالي ... اليوم كم من السنة الحالية ..... ؟؟


dd عرض اليوم من الشهر .. يعني 04 من شهر يناير مثلا !!


d عرض اليوم من الاسبوع ... يعني اذا سبت .. فهو واحد .. اذا احد كمثالنا هذا .. فهو اثنين ... اذا الاثنين . فهو ثلاثة ..

اذا جمعة فهو سبعة !!





بعض المتفرقات ....








select to_char(sysdate,'AM A.M. CC WW W ') from dual ;




AM عرفنا ماهي ..


A.M. نفسها ولكن ستعرض النتيجة يا A.M. او P.M. يعني بالنقاط


CC تعني نحن في القرن كم ^^ ؟؟؟؟ طبعا سوف يكتب لك في النتيجة 21 .. أي القرن الواحد والعشرون


WW هو الاسبوع من السنة .. يعني كم هو الاسبوع من السنة ؟؟


W الاسبوع من الشهر , يوجد في الشهر اربعة اسابيع تقريبا .. يعني لو الاسبوع الاول من شهر يناير .. يكتب واحد ...

لو الاسبوع الثالث من الشهر ... يعني حيكتب ثلاثة





مثال اخير ......

تخيل ان التاريخ اليوم هو .... 03/01


مثلا ....

اريدها هكذا ... ثلاثة / واحد

او اريدها هكذا .. الثالث من هذا الشهر .. 3rd


او اريدها هكذا ... الثالث ... third


كيف ؟؟








select to_char(sysdate,'ddsp/mmsp "or" ddth/mmth "or" ddspth "from" mmspth "month" ') from dual ;





النتيجة ...


three/one or 03rd/01st or third from first month


كل ما فعلته ...

انه أي رقم ... مثلا dd يحضر لي رقم الايام ... الحقته بحرفي sp (اختصار ل spell وهو النطق) لكي يقول ثلاثة بدل من 03

نفس الشيء مع الـ mm


الحقت الحرفين th بـ dd و mm لكي يعرض لي الترتيب ..

يعني بالانجليزي .. الاول 01st والثالث 03rd والرابع 04th وهكذا ,,,

اذا اردت نطق + ترتيب ؟؟

النطق = sp


الترتيب =th


اذن ... dd+sp+th فتساوي ddspth يعني الله لا يهينك ... انطقلي ترتيب اليوم ...

وهو الثالث ... third


ونفس الشيء مع الشهر .. mmspth وهو الشهر الاول ...

طيب ...

مارأيك في كلمة month لماذا لم تتحول الى الكلمة january ؟؟؟

لماذا ؟؟

ركز ركز ركز ؟؟

الم نقل انها سوف تتحول الى الشهر ؟؟

لماذا لم تتحول هنا ؟؟


التحدي الثاني يقول ...








select to_char(sysdate,'ddsp/mmsp "or" ddth/mmth "or" ddspth "from" mmspth "month" ') from dual ;





يوجد كلمة month ... الم يكن من المفترض ان تتحول الى شهر ؟؟؟

النتيجة كانت هكذا .....


three/one or 03rd/01st or third from first month


لماذا لم تتحول كلمة month الى الشهر في تاريخ sysdate أي لماذا لم تتحول الى January مثلا ؟؟؟





واخيرا انتهينا من الدوال الاحادية الصف ,,

ولكن تذكر هنالك مشاكل معك ومع الدوال .. (درس في علم النفس ....)


مشكلة النسيان !!


الحفظ !!

سوف تحفظها الان .. وتنساها غدا ...

لا تخف ... لقد وضعت لك ... جداول وصور ... تلخيص بسيط لها ... اذا نسيتها .. فقط .. اذهب الى هذه الجداول .. والصور ... واقرأها .. اذا لم تفهم نقطة فيها .. راجع شرحي لها ....

تعود ان تلخص بطريقتك ... تسمى هذه الطريقة .. بطريقة الفهرسة !!

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

وانا لا اقصد فقط الأوراكل .... بل كل المواد ...


هل تحس الان .. انك ضائع مشتت بين الدوال ؟؟

هل تحس انك فاهم ولكن ... ملخبط ؟؟

هل تحس انك .. حاسس ان تعبك كله راح .. بالرغم من انك فاهم ؟؟

الحل الفهرسة كما أسلفت !!





حتى عندما ترجع الى الدروس القديمة .. لا ترجع الى الكتاب !! بل ارجع الى فهرستك انت .. التي صنعتها ...

سوف تقرأها .. وتقول .. "نعم نعم .. افتكر هذه النقطة جيدا ... " سوف تذكر كل شيء .... حتى لو لم تكن مكتوبة في الفهرسة والتلخيص الخاص بك ..

مهارة الفهرسة ... تعلمتها انا شخصيا من كتاب علم نفس ...

اعتقد اسم الكتاب "كيف تضاعف ذكائك " ... اعتقد ....

.. ذكر في الكتاب انه من اقوي التكنيكات .... الفهرسة !! وهي تلخيصك انت !! بطريقة الفهرس !!

بإمكانك ان تكتب بعض الرموز لو أردت او بعض التلميحات .. فهي مفيدة جدا ...

تذكر ان تعملها بنفسك انت ... لكي تفهمها انت .... وفقط انت !!





مشكلة الاستحضار !!


("")هل انتهت المشاكل ؟؟ لا لا ... لم تنتهي ..

انت الان حافظ وفاهم .. وعملت الفهرسة كما يجب ....

واذا بأول سوال في الاختبار ..لاتعرف ان تحله !! لماذا ؟؟ لأنك لا تعرف مالذي ستستخدمه !! هل الدالة الفلانية .. هل بدون دالة ؟؟ هل وهل وهل ؟؟؟ لا تعرف ....

اذا حفظت الدوال .. لا تحفظها فحسب ... احفظ لماذا صنعوها !!

لماذا هي موجودة !!

لماذا استخدمها ومتى ؟؟

وهي تسمى الاستحضار ... يعني لو أردت منك جملة ما ... فسوف تقول في نفسك ...

"اووووه ... ماذا استخدم ماذا استخدم ماذا استخدم ؟؟؟؟؟ "

وهي مشكلة بحد ذاتها ...

مع التمرس ... سوف تحل هذه المشكلة أوتوماتيكي ... وهو ان "تواجه المشكلة "...


كان معلمي الهندي يقول دائما .."Face the problem … you people want every thing free "


.. لكن حل التمرس هذا .. يحتاج لجهد ... بالرغم من قوته !!

لو قرأت دروسي .. تخيل وتذكر .. وتصور و أعصر مخك ... لماذا هذه الدالة ؟؟ ولماذا صنعوها ؟؟ ومتى استخدمها ؟؟

هكذا .. حتى لو لم تتمرس كثيرا .. فسوف تعرف متى تستخدمها !!


ولكن يبقى التمرس سيد الموقف !!


...




اشير الى انني عصر يوم كتابتي لهذا السطور الاخيرة ....


اكتشفت لماذا عملوا to_date


هل تذكر انني تركت دالتين لاغراض التواريخ ؟ كانت تحدث معي مشاكل ...

والان عرفت ماهي المشاكل ....

وعرفت ان حلها هي الدالة to_date !!


قبل ان ابدأ التلخيص ... فسوف اعرض لك ... هذه الدالتين ...





الدالة :ROUND


العمل :تقريب !

الأمثلة :


هل تعتقد انني أخطأت ؟؟؟

هل تعتقد انك تذكر هذه الدالة ؟؟

نعم تذكر ... وهي دالة تقريب الاعداد ...

فهي دالة لتقريب التواريخ ايضا !!

بس بطريقة أسهل ..... من تقريب الأعداد ,,


لو ان التاريخ الحالي 03/01/2006

بالله عليك ... بالنسبة للسنة ايهما اقرب .. 2006 ام 2007 ؟؟

طبعا 2006

بالله عليك .. بالنسبة للشهر .. ايهما اقرب .. الشهر الاول .. ام الشهر الثاني ؟؟

طبعا الشهر الاول

كيف ؟؟

التاريخ 03/01/2006

على مستوى السنة ... هل التاريخ الحالي ... اقرب الى 01/01/2006 ام اقرب الى 01/01/2007 ؟؟

أين ننظر يا اصحاب العقول الرزينة ؟؟ في الايام ؟؟ في السنوات ؟ لا ... في الاشهر ..

يعني لو قلت لك على مستوى السنة ... فاننا ننظر في الاشهر ....

الشهر الحالي هو واحد !! لو كان الشهر هو الشهر السادس فأقل (يعني الشهر السادس او الخامس او الرابع .. او الاول )

فهذا يعني انه قريب من السنة الحالية ... وهي 2006

ولو ان الشهر الحالي هو سبعة .... فما فوق .. فهذا يعني انه قريب من السنة القادمة .. وهي 2007

فهمت ؟؟





على مستوى الشهر .... هل التاريخ الحالي (03/01/2006) اقرب الى 01/01/2006 ام اقرب الى 01/02/2006 ؟؟

أين ننظر يا اصحاب العقول الفطنة ؟؟ في الاشهر ؟؟ في السنوات ؟؟ لا ... في الايام

ركز ...

يعني لو قلت لك على مستوى السنة .. تنظر في الاشهر ..

ولو قلت لك على مستوى الاشهر .. تنظر في الايام !! بسيطة صح ؟

اذن اليوم هو الثالث ...

اذا كان اصغر من او يساوي اليوم الخامس عشر !! فاقرب الى الشهر الحالي

واذا كان اكبر من اليوم الخامس عشر فاقرب للشهر التالي ...

لم تفهم ؟؟ لا تريد ان تفهم ؟؟ هل انت من اصحاب العقول التي تفهم مع الامثلة ؟ طيب .. اليك الامثلة ...

تاريخ اليوم ... كما اشرت هو 03/01/2006









select round(sysdate,'MONTH') from dual ;





المدخل الثاني مكتوب فيه .. month يعني على مستوى الشهر ....

النتيجة تتوقعها ماذا ؟؟

طبعا 01/01/2006







select round(sysdate,'YEAR') from dual ;







الـ year تعني على مستوى السنة ..

نحن في شهر واحد .. يعني اصغر من او تساوي 6 ... اذن .... السنة الحالية هي الاقرب ..

النتيجة 01/01/2006




لم تفهم .. اليك الامثلة ...

قبل ان ابدأ ...

كنت قد كتبت سابقا .... مايلي :








select round('01/01/2006','YEAR') from dual ;





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

لاحظ انني ادخلت التاريخ بشكل يدوي .. وليس كمثل sysdate او كمثل احد الاعمدة من نوع تاريخ مثل hiredate


بالله عليك ... مش التاريخ كالنص .. ويشبهه ؟؟ لم تقتنع ؟؟ اليك مثال قديم ..








select ename from emp

where hiredate ='22/02/1981';





بالله هل هذه صحيحة ام لا ؟؟

صحيحة مئة بالمئة ...

لكن عندما استخدمها مع الدالة round .... تحصل مشاكل !! ونفس الشيء ... مع الدالة to_char ... ادخلت فيها تاريخ من رأسي .. ولم افلح !!

الحل هو .. to_Date ...


لكي اجبر الـ round والـ to_char ان تقبل المدخل الاول وبالقوة ... وغضب عليها ان تقبلها !!

اعتقد ان الدالة round حينما كتبت لها الجملة السابقة .. قالت في نفسها .. هذه يضحك علي ويضع نص !! وليس تاريخ .. هاها ... خذ قائمة الاخطاء !!

واعتقد ان المطورين .. يريدون المدخل الاول للدالة round ان يكون تاريخ خالص !!

لا نقلق لاننا نملك الدالة التي قلنا انها عديمة الفائدة سابقا وتدعى to_date !!


لا تلومني يا هذا .. لم اقل انها عديمة الفائدة من فراغ ... لأني لم اعرف ان هنالك دالة غبية .... مثل round ..


لذا .. من الممكن ان تواجهنا دوال وحالات غبية ... فتذكر الدالة to_date كحل إجباري !! ,’,’,’,’




اليك حل المشكلة ^^ ...








select round(to_date('15/07/2006','dd/mm/yy'),'MONTH') from dual;







هاها ... الان تغلبنا على الدالة .. وسوف تعرض النتيجة ماذا ؟؟؟ ركز في انها على مستوى الشهر !!

من يعرف ؟؟

لا احد يعرف ؟؟

؟؟؟؟

؟؟؟

؟؟

؟

The Coder
04-01-2006, 10:46 PM
طيب النتيجة ستكون :


01/07/2006


لأن اليوم 15 .. وهو اصغر من او يساوي 15 لذا فالشهر الحالي هو الأقرب !!




مثال اخر






select round(to_date('16/07/2006','dd/mm/yy'),'MONTH') from dual;





فكر فكر فكر ..

النتيجة بسيطة ..

ستكون ...


01/08/2006


سهلة صح ؟؟





الان على مستوى السنين ...








select round(to_date('15/07/2006','dd/mm/yy'),'YEAR') from dual;







مالنتيجة ؟؟

طبعا .... على مستوى السنة .. ننظر الى الشهر (لاحظ اننا تجاهلنا الايام في مستوى السنين).. نجده اكبر من او يساوي 7

اذن .. النتيجة هي ..


01/01/2007




مثال اخير ...








select round(to_date('15/06/2006','dd/mm/yy'),'YEAR') from dual;





والنتيجة ... هي ....




01/01/2006




اليك التحدي الثالث !!






select round (to_date('16/12/2006','dd/mm/yy'),'month') from dual;





مالنتيجة المتوقعة ولماذا ؟؟

حاول ان لا تستخدم البرنامج .. استخدم عقلك فيها !!





الان انتهت هذه الدالة ... جميلة بعض الشيء .. ولكن انظر الى الدالة القادمة .. دالة غبية بعض الشيء ولكن من الممكن ان تفيد لأغراض اخرى ...





الدالة :TRUNC


العمل :???? اعتقد قص التاريخ ؟؟

الأمثلة :


هل تذكرها ؟؟

نفس تلك الموجودة في قص الاعداد ... ولكن هذه المرة ... التواريخ ....


ندخل في الأمثلة ....









select trunc(to_date('15/08/2006','dd/mm/yy'),'month') from dual;





مالنتيجة لو كانت round ؟؟

طبعا


01/08/2006


طيب ... في هذه الدالة .. النتيجة نفس الشيء ..


01/08/2006


المثال الي بعده ....








select trunc(to_date('18/08/2006','dd/mm/yy'),'month') from dual;





لو كانت الدالة round مالنتيجة ؟

طبعا


01/09/2006




لكن مع هذه الدالة ... النتيجة :


01/08/2006


كأنه يقول ... على مستوى الشهور ... سواء الايام كانت اكبر من 15 او اصغر من او تساوي 15 ... رجعها الى واحد

يعني كأنه يقول صفر عداد الايام !! وارجعه لواحد ,,

اليك مثال السنين ...








select trunc(to_date('15/08/2006','dd/mm/yy'),'year') from dual;





النتيجة ...


01/01/2006







select trunc(to_date('15/04/2006','dd/mm/yy'),'year') from dual;





النتيجة هي ..


01/01/2006




خلاصة الامر .. اذا على مستوى الشهور ... رجع الايام الى 1 واترك الشهر كما هو

اذا على مستوى السنين ... رجع الايام لـ 1 و الشهور لـ 1 والسنين كما هي ... !!

انتهت ....





الان اليك تلخيص مبسط لـدوال الاحادية الصف ...

ولاحظ ان مداخل الدوال من الممكن ان تكون اسم عمود ... او تكون نص .. او رقم .. او تاريخ !!





دوال لأغراض النصوص .. (عرضت في الدرس السابق .. وتعرض الان للتذكير ...) صورة 19


http://img6.picsplace.to/img6/10/19_015.jpg



دوال لأغراض الأرقام ... صورة 29



http://img8.picsplace.to/img8/5/29_006.jpg



دوال لأغراض التواريخ .. صورة 39



http://img8.picsplace.to/img8/5/39_009.jpg



دوال لأغراض التحويل !! صورة 49



http://img6.picsplace.to/img6/10/49_001.jpg








هل انتهت الدوال الاحادية ... هل تخلصنا منها الى الأبد ؟؟ هل نبدأ في دوال المتعددة الصفوف ونرتاح ؟؟

لا لا لا .. لا ...

بقيت دالة واحدة لا تصنف ضمن الدوال السابقة !!

The Coder
04-01-2006, 10:50 PM
الدالة :NVL


العمل :تبدل القيم الخالية ... بقيم اخرى !!


الأمثلة : مهمة هذه الدالة ...

اولا ....


NULL + 800 = ؟؟؟

كم تساوي ؟؟؟

اذا لم تعرف .. اتق الله في نفسك .... وراجع الدرس السادس !!

الحل هو ....


NULL + 800 = NULL


أي عملية حسابية وأي رقم .. مع الـقيمة الخالية فالنتيجة هي قيمة خالية !!

ضرب قسمة طرح جمع .... جذر ... أي شيء ... الناتج قيمة خالية !!

الان ....

اليك هذا المثال القديم ..

نريد عرض اسماء وراتب الكلية ..(الرواتب الكلية = الرواتب الأساسية + الإضافية )

ما هي جملة الاستعلام ؟؟

فرصة لك ان .. تتذكر ...





هيا هيا هيا ....







انتهى الوقت ,,









select ename , sal+comm from emp ;












ENAME SAL+COMM

---------- ----------

SMITH

ALLEN 1900

WARD 1750

JONES

MARTIN 2650

BLAKE

CLARK

SCOTT

KING

TURNER 1500

ADAMS



ENAME SAL+COMM

---------- ----------

JAMES

FORD

MILLER








بعضهم .... قيمة الراتب الكلي .. فارغة ؟؟ لماذا ؟

لان قيمة الـcomm لديه فارغة .....

فـ NULL + راتبه = NULL


مشكلة عويصة ....





مشكلة اخرى .... المدير لا يريد شيء فارغ من هذه الجملة ...









select ename , comm from emp ;








انظر النتيجة .... فراغات فراغات فراغات ... شكلها ... وحش !!






ENAME COMM

---------- ----------

SMITH

ALLEN 300

WARD 500

JONES

MARTIN 1400

BLAKE

CLARK

SCOTT

KING

TURNER 0

ADAMS

JAMES

FORD

MILLER












مالعمل ؟؟

ماذا نفعل ؟؟

من ينقذنا ؟؟

سوبر مان ؟؟

لا ....

بل دالة NVL


دالة NVL تقول .... اعطيني العمود الذي ترى ان فيه قيم خالية ... واعطيني قيمة بديلة .. وانا اضعها لك .. كيف ؟؟

في مثالنا الخاص بـالرواتب الكلية .... انسى القيمة الخالية في حياتك اليومية ... وفكر ..

اذا واحد ما عنده راتب إضافي ... يعني راتبه الإضافي يساوي كم ؟؟

صفر صح ؟؟

ما رأيك لو مثلا ... واحد راتبه الاساسي 1250 وراتبه الاضافي ما عنده ... راتبه الكلي كم ؟؟؟

طبعا 1250 .... مالذي فعلته ؟؟ فكر ؟؟ بسيطة ... 1250 دولار + 0 دولار = 1250 دولار .. هذا كل شيء ..

يعني بدلا من الـ NULL نضع صفر !!

وتعالي يا دالة NVL .... نريدك في مشوار ....









select nvl(comm,0) from emp ;





انظر الناتج وفكر .....









NVL(COMM,0)

-----------

0

300

500

0

1400

0

0

0

0

0

0

0

0

0





هل شاهدت ذلك ...؟؟

بدلا من القيم الخالية .. والفراغات .. اصبح لدينا اصفار !!

دالة NVL لديها مدخلين ... المدخل الاول .. العمود الذي تتوقع ان به قيم خالية ...

والمدخل الثاني .. به القيمة البديلة اذا ... (لاحظ اذا ) كانت القيمة خالية .. اذا لم تكن خالية .. اتركها كما هي ...

ياسلام يا NVL ... حللت مشكلاتنا ببراعة ...





الرئيس ..KING


من اسمه ... تعرف انه ملك !!

ورئيس الموظفين في جدولنا المعتاد ,,

من مديره في الشركة ؟؟

نريد ان نعرف مديره .... كيف ؟؟











select ename , mgr from emp

where ename='KING' ;








والنتيجة ...









ENAME MGR

---------- ----------

KING








اوبس ... قيمة خالية في حقل الـمدير mgr !!


يعني لا مدير له ... وهو التوب (التوب = top = فوق ... والتوب كلمة عربية مأنجلزة .... وليست انجليزية معربة ...)....

حقل المدير ... حقل كله ارقام ....

يعني رقمي .. وليس نص او تاريخ (اسف لاني ذكرتك بمصائب التاريخ !!)

لو جائنا رئيسنا KING وقال .. شكلها مو حلو .. ابي جملة بدلا من الفراغ هذا .... ابيه NO MANAGER


له حق يتشرط ...

ماذا نعمل ؟ بسيطة .... الدالة NVL تحت الخدمة ..













select ename,NVL(mgr,0) from emp where ename='KING';





والنتيجة هي ...









ENAME NVL(MGR,0)

---------- ----------

KING 0





ياسلام .. صار صفر بدلا من الفراغ ...

بالله عليك ... لو احد الموظفين رقمه صفر ..... وهو موظف يأخذ راتب 250 دولار فقط .. تجعله رئيسا على KING !!!


كم نضع ؟؟ واحد ؟؟ عشرة ؟؟ لا نعرف ...


كأننا سمعنا KING قبل ان يذهب يقول .. اريد الجملة NO MANAGER !! صح ... اذن بسيطة !!








select ename,NVL(mgr,'NO MANAGER') from emp where ename ='KING';







شكلها حلو ...

انظر النتيجة الجميلة الان ... بالله انظر ...












ORA-01722: invalid number





جميلة النتيجة ... مجرد ..... خطأ !!!!


مالعمل ... ؟؟

ماذا نفعل ؟؟

دالة NVL تقول ... ان المدخل الاول رقم .. يجب ان يكون المدخل الثاني رقم ...

المدخل الاول نص .. فلا بأس في المدخل الثاني ... رقم نص .... لا بأس !!

في مثالنا .. المدخل الاول هو mgr وهو رقم .... ماذا نعمل ؟؟؟

مشكلة الاستحضار الان بدأت لديكم ....


و أظن ان مشكلة الحفظ بدأت قبلها لديكم ....

ممممم .... هههههه ... سوف اجعله تعذيب .. أأقصد تحدي ,,

وهو التحدي الرابع


انتهت رحلتنا في كوكب ... الدوال الاحادية الصف ,’,’,’,’,’,’,’

The Coder
04-01-2006, 10:54 PM
2) الدوال المتعددة الصفوف Multi-Row Function


اولا وقبل كل شيء .... مالفرق بين الدوال الاحادية الصف ... والمتعددة الصفوف ؟؟

تعرف ؟؟

انظر المثال التالي .. (الصورة 59)









http://img8.picsplace.to/img8/5/59_001.jpg








انظر الى الجدول في المنتصف ...

يمين ... ستجد دالة تسمى بـ SUM وتعني ... مجموع !! (ذات اللون الأحمر)

دالة SUM دالة متعددة الصفوف

يسار ستجد دالتنا الموقرة .. LOWER (ذات اللون الأحمر ) اذا لم تعرف مالذي تفعله ,, روح ونام أفضل ,,

مالفرق بين الدالتين ؟؟

دالة LOWER تأخذ صف صف ...

يعني تأخذ صف واحد .. وتخرجه كصف واحد ..

اما دالة المجموع ... فهي تأخذ مجموعة صفوف ... من الممكن ان تكون صف واحد او صفين او ألف صف !!


وتخرجه كصف واحد !! .. ركز ...

هل فهمت الفرق !!

يعني احادية الصفوف .. تأخذ صف واحد وتخرج صف واحد

متعددة الصفوف .. تأخذ مجموعة صفوف (مجموعة = صف او اكثر ) !! .. وتخرج ايضا صف واحد فقط..

وهو فرق جذري!!


الان اريد ان اسرد لك دوال المتعددة الصفوف ...

اقل من الدوال الاحادية الصف ... وابسط ,,





الدالة :SUM


العمل :ايجاد المجموع





الأمثلة :


ماهو مجموع رواتب الموظفين الذين في قسم 30 ؟؟؟

صعبة !!

اليك الجملة ....








select sum(sal) from emp where deptno =30 ;





وستعرض نتيجة واحدة .. فقط ...








SUM(SAL)

--------

9400






....


اشير الى انها تأخذ في المدخل اعداد فقط ... طبعا !!

لانها لا توجد مجموع اسماء ولا مجموع تواريخ .... كما تعرف ....

هل تصدق ان دالة SUM ذكية ؟؟ تعرف لماذا ؟؟

لانها اوتوماتيكيا ... تحول القيم NULL الى صفر ,,,

جرب الجملة التالية ... وستعرف انها ذكية ..








select sum(comm) from emp ;





سوف تحول القيم الـخالية الى اصفار ,,





اريد .. تعقيد الامور اكثر واكثر ,,

واريد مجموع ... الرواتب الكلية ...


كيف ؟

تعرف ؟؟

اختبر نفسك !! .... لم تعرف ؟؟

طيب ...








select sum(sal+comm) from emp ;





والنتيجة هي .. 7800 دولار ,,

يا سلام ...

انتظر قليلا ... بالله عليك .. اذهب واحضر الالة الحاسبة .... ونفذ هذه الجملة التالية ..








select sum(sal) from emp ;





ستجد ان النتيجة مخيفة .... 29025 دولار !!

يعني بالله .... مجموع الرواتب الاساسية فقط اكبر من مجموع الراتب الكلية ؟

لا نقبلها لا بالعقل ولا بالمنطق ,,,,,

مالذي حدث ؟؟

هل تعرف ؟؟؟

لا تعرف ؟؟؟

سواء عرف ام لم تعرف .. رغبت ام لم ترغب ...


سوف اجعله تحدي خامس

التحدي الخامس يقول ...

فسر لي .. لماذا ظهرت النتيجة 7800 دولار ؟؟ مع العلم ان دالة SUM دالة ذكية !!


واخبرني مالحل .. وما العمل ؟؟ ما الجملة البديلة ؟؟























الدالة :MAX


العمل :توجد اكبر قيمة ,,


الأمثلة :


في جدول الموظفين .. من هو صاحب اكبر راتب ؟؟

تعرف ؟ لا تعرف ؟

اليك الجملة ...








select max(sal) from emp ;





وسوف تعرض القيمة .. 5000 ,,, انتهى ...








الدالة :MIN


العمل :توجد اصغر قيمة ,,


الأمثلة :


في جدول الموظفين .. من هو صاحب اصغر راتب ؟؟

اليك الجملة ..






select min(sal) from emp ;





والنتيجة هي 800 دولار ,,





لاحظ ان في MAX و MIN تستطيع ان تضع نص في مدخلهما !!

فما الذي تتوقعه من الجملة التالية ؟








select max(ename),min(ename) from emp ;







انظر النتيجة ...








MAX(ENAME) MIN(ENAME)

---------- ----------

WARD ADAMS







يعني .. لو رتبنا الاسماء ابجديا .. لوجدنا ان ادم هو الاول ... ووارد هو الاخير ...

يعني MIN اوجدت الاول ... والـ MAX اوجدت الاخير ..

رائع ....

كأن MIN اوجدت اقل الحروف ترتيبا ... مثلا الحرف باء .. هو الحرف الثاني ...

والحرف جيم هو الحرف الخامس .. ماهو الـ MIN وما هو الـ MAX بينهما ؟؟

فالـ MIN هو حرف باء (الثاني الاصغر), اما MAX فهو الحرف جيم ...(الخامس الاكبر)


فهمت ؟؟؟

The Coder
04-01-2006, 10:57 PM
الدالة :AVG


العمل :توجد المتوسط ؟؟


الأمثلة :


اخواننا في الاحصاء .. يعرفون جيدا ما معنى المتوسط الحسابي ...

مثلا .. انظر الى هذه الرواتب من شركة A المحدودة ,,,


1000

2000

5000

6000


ما هو المتوسط الحسابي لهذه الرواتب ؟؟

نوجد المجموع ....




1000+2000+5000+6000 = 14000


بعد ايجاد المجموع ...

نقسمه على عدد الارقام ... هنا اربعة ارقام ... اذن .. نقسم المجموع على اربعة


14000 / 4 = 3500


فهمت ؟





يعني كأنك تقول 3500 لجميع الموظفين في شركة A المحدودة وبالتساوي ....


لماذا المتوسط الحسابي ؟؟

انا اعتبره مقياس فعلي ,,,

مثلا الشركة B

2000

3000

8000

500

2000


لو جمعتها تصبح 15500 ... هل شركة B تعطي رواتب افضل من شركة A اذا قارنا بينهما من ناحية المجموع ؟؟ طبعا لا نعرف ... لماذا ؟ لانه ذكر 4 موظفين في الشركة A و 5 موظفين في الشركة B


اذن ليس المجموع مقياس فعلي !!

اذا حسبنا المتوسط الحسابي للشركة B فإننا نجد مايلي ..


15500 / 5 = 3100


من الأكثر في الرواتب .. A ام B ؟؟

ومن المتوسط الحسابي نجد ان A اكثر كرما بالنسبة للموظفين جميعهم !! اكرر بالنسبة للموظفين جميعهم !!

الان اريد ان اوجد المتوسط الحسابي للـرواتب فإليك الجملة ,,








select avg(sal) from emp ;







النتيجة ... هي






AVG(SAL)

----------

2073.21429







الدالة :COUNT


العمل :ايجاد عدد الصفوف !!


الأمثلة :


لو قلت لك .... كم عدد صفوف الجدول dept ؟؟؟

هي في الحقيقة أربعة ....

طبعا انا ذهبت وكتبت الجملة التالية ...








select * from dept ;





وظهرت لي ..... اربع صفوف ... انا بنفسي عددتهم ...

اقسم انهم اربعة صفوف !!

لا تصدق ... هيا عدهم انت ... .








DEPTNO DNAME LOC

------- -------------- --------

10 ACCOUNTING NEW YORK

20 RESEARCH DALLAS

30 SALES CHICAGO

40 OPERATIONS BOSTON





هل صدقت ؟؟

استطعنا انا وانت ..... ان نعدها بالنظر ...

طيب .. لو قلت لك كم عدد صفوف جدول الموظفين ؟؟

انا لاني اعتدت عليها .. اقول 14 !! عددتهم بنفسي ...

وباستطاعتك انت وبعد ثواني ان تعدهم ...

لو كان جدول الموظفين به مليار وستمئة مليون وثلاث وعشرون الفا وخمسة عشر موظف .. ونصف الموظف ...

بالله عليك .. كيف تعدهم ؟؟ كيف تعرف ؟؟

طبعا دالة count تحت الخدمة ..... دائما وليس مؤقتا !!








select count(*) from emp ;





والنتيجة كانت ...








COUNT(*)

--------

14







هل انتهى كل شيء ؟؟

لا لم ينتهي كل شيء .. اولا ما معنى النجمة * ؟؟؟

في دراستنا السابقة معناها جميع الأعمدة !!


يعني اوجد لي عدد جميع الاعمدة ؟ هل هذا معنى هذه الدالة ؟؟

ركز جيدا ....

هذه الدالة تتجاهل تماما القيم الفارغة !!

افهم ذلك جيدا !!

الحاسب غبي .. لا يعرف الا صفر او واحد .. من الذكي ؟؟ انت يا بشر ...

بالله عليك .. ما معنى 14 صف ؟؟

مش معناها 14 موظف ؟؟؟ كيف عرفت ؟؟ لانك فكرت ... وعرفت ان الجدول خاص بالموظفين .. وان كل صف يمثل موظف واحد !! ياسلام على الاستنتاج !! بشر وذكي وتعرفها بالبديهي ,,

هذه الدالة .. لها نوعين ... نوع يوجد عدد الصفوف لجدول ... ونوع اخر يوجد عدد عمود معين ...


COUNT(*) هذه اوجدت لنا عدد الصفوف في الجدول كله ...

هل تريد عدد الصفوف الخاصة بـالعمود (عمود=حقل) الخاص بالرواتب ؟؟










select count(sal) from emp ;





وسوف تعرض لك كم ؟؟

14 صف .... يعني 14 راتب لـ 14 موظف ....

تعال معي الان ...

كم عدد الصفوف للعمود رواتب اضافية ؟؟










select count(comm) from emp ;





والنتيجة هي .... 4 !!

يعني توجد اربعة صفوف فقط ؟؟

اين العشرة الباقية ؟

ان قيمها ... قيم خالية !!

لذا .... فإن الدالة تتجاهل القيم الخالية ...

هل فهمت ؟

طيب .. هل تذكر deptno الموجود في جدول emp ؟؟ ماهو ؟؟ انه عمود الخاص بارقام الاقسام

كم قسم موجود ؟؟؟ جرب الامر ...








select count(deptno) from emp ;





وسوف تعرض لي 14 صف ..

14 صف يعني هنالك 14 قسم ؟؟؟

هل هذا صحيح ؟

طبعا خطأ !!

يوجد 4 اقسام فقط !! لا تصدق ؟؟ عددناها انا وانت !! هل تذكر !!

من جدول الأقسام dept


اريد ان اوصل اليك معلومة ..... قد تكون الأعمدة بها قيم خالية ... كما شاهدنا في الرواتب الاضافية

قد تكون قيم مكررة كما شاهدنا في المفتاح الغريب (الغريب= الاجنبي) والذي يدعى بـ deptno


فانتبه لهذه النقطة .. لاتعني عدد الصفوف شيء صحيح ! هل فهمت ,,

اريد ان اعرف كم عدد الموظفين الذين يأخذون رواتب اضافية .. كيف ؟؟؟

هل تعرف ؟؟








select count(comm) from emp ;





وسوف تكون النتيجة هي 4 !!

في الحقيقة ... لو شاهدت الجدول فسوف تشاهد ان هنالك 3 أشخاص يأخذون رواتب اضافية .. والرابع يأخذ صفرا !!

هل بالله عليك .. ان الرابع يأخذ راتب إضافي ؟؟ هل نعتبره نحن البشر انه يأخذ راتب إضافي ؟؟

اذن اليك الامر .. ولكن بشكل أفضل ....







select count(comm) from emp

where comm <> 0 ;





معنى السطر الثاني ... عندما لا يساوي الراتب الإضافي صفرا

والنتيجة تكون .. ثلاثة !!

تنبه لهذه الدالة ... قد تكون هنالك اخطاء كهذه لم اذكرها انا .. وقد لا تهتم اليها ,,,

هل هذا كل شيء عن الدوال المتعددة ؟؟

هل هي بهذه السهولة ؟؟

هل انتهينا منها ؟؟

هل توجد مصاعب اكثر ؟؟

هذا ما سنعرفه في الدرس القادم ^^


,’,’,’,’,’,’,’,’,’,’,’,’,’,’,’

The Coder
05-01-2006, 10:07 PM
تنبه ان الدرس القادم .. صعب قليلا ... ومسلي اكثر من هذه الدوال !!

الدوال يجب ان تحفظها عن بكرة ابيها !!

قد تكون كثيرة ..

قد تكون ملخبطة ..

قد تطفش منها ...

قد تكون مملة !!

ستختفي هذه الأعراض اذا تمكنت منها ..... صدقني ,,,





وصلى الله على نبينا محمد وعلى اله وصحبه وسلم





التحديات للتذكير وهي موجودة بين السطور .... أرجو منك عرضها في موضوع الاستفسارات ,,,





التحدي الاول ...


تخيل انه يوجد موظفين أرصدتهم في البنك مايلي ..


10.25 عشرة دولارات وربع ...


20.5 عشرون دولار ونصف ...


1000000.945 مليون دولار وتسع مئة وخمسة واربعون من العشرة ...

يوجد جدول يدعى بـ BANK مثلا .....

اريد عرض النتائج بهذه الصورة


$0,00,00,10.25

$0,00,00,20.5

$1,00,00,00.945




وهلم جر !!







التحدي الثاني يقول ...








select to_char(sysdate,'ddsp/mmsp "or" ddth/mmth "or" ddspth "from" mmspth "month" ') from dual ;





يوجد كلمة month ... الم يكن من المفترض ان تتحول الى شهر ؟؟؟

النتيجة كانت هكذا .....


three/one or 03rd/01st or third from first month


لماذا لم تتحول كلمة month الى الشهر في تاريخ sysdate أي لماذا لم تتحول الى January مثلا ؟؟؟





اليك التحدي الثالث !!






select round (to_date('16/12/2006','dd/mm/yy'),'month') from dual;





مالنتيجة المتوقعة ولماذا ؟؟

حاول ان لا تستخدم البرنامج .. استخدم عقلك فيها !!







التحدي الرابع ...


.. اريد الجملة NO MANAGER !! اذا كان القيمة خالية في عمود mgr


وكتبنا هذه الجملة والتي كانت خطأ






select ename,NVL(mgr,'NO MANAGER') from emp where ename ='KING';







نريد التصحيح ,,,





التحدي الخامس :








select sum(sal+comm) from emp ;





كانت نتيجتها اقل من مجموع الرواتب .. وهي من المفترض ان تكون اكثر !!

فسر لي .. لماذا ظهرت النتيجة اقل ؟؟

واخبرني مالحل .. وما العمل ؟؟ ما الجملة البديلة ؟؟

The Coder
15-01-2006, 12:43 AM
بسم الله الرحمن الرحيم

الدرس العاشر


اسم الدرس : جملة الاستعلام select والدوال

نوع الدرس : تطبيقي

صعوبة الدرس : *** من *****

اهميــة الدرس : ****** من ***** (Over)


درجة احتراف لغةSQL المتوقعة بعد هذا الدرس : *** من ***** (متوسط )


الوقت المتوقع منك لفهم الدرس : 10 ساعة (ساعتين فهم و 8 ساعات تطبيق )

متطلبات تتوفر فيك : التطبيق





المتوقع منك في هذا الدرس :

- اتقان جزء من هذه اللغة 100 %

- معرفة اضافة , تعديل , وحذف البيانات من الجدول عبر لغة DML


- معرفة التراجع والحفظ

- معرفة انشاء , تعديل , حذف الجداول والحقول عبر لغة DDL





هيا لنؤركل ^^





السلام عليكم

قبل البدء .. اكتشفت دالة جديدة ....

المشكلة في تعدد المناهج ....

لا ادري هل يوجد غير هذه الدالة ..... ولكن اذا وجدتها فسوف اعرضها في الدروس القادمة ان شاء الله ’,’,’,’,’,

الدالة صعبة قليلا ...

ليست كالدوال السابقة !!

الدالة قد تجعلك تكره الـ SQL .. وقد تحببك فيها ,’,’,’

اما هذه الدالة فهي ....


الدالة :DECODE


العمل :????


الأمثلة :


لو لدينا مجموعة احتمالات ..... فمثلا ...

انا كمدير عام .. اريد ان ارفع مرتبات الموظفين .... بنسبة معينة ...

فكل محلل ارفع راتبه بنسبة 50%


و كل مدير ارفع راتبه بنسبة 40%


و كل كاتب .. ارفع راتبه بنسبة20%


وكل بائع .. ارفع راتبه بنسبة 10%


وطبعا ارفع راتبي بنسبة 70%


لاحظ انه يوجد مجموعة احتمالات !!

لو فإن ..

لو فإن ...

لو فإن ....

مجموعة مسارات ... مجموعة قرارات .....

يعني اذا شيء .. فارفع الراتب بشيء ..

واذا بشيء .. ارفع الراتب بشيء ...

وهكذا ....

مالعمل ....بالله عليك فكر ... كيف نحل هذه المشكلة .؟؟؟

جرب .... أعصر مخك ...





حلها باختصار دالة DECODE


كيف نستخدم هذه الدالة ؟

اليك المثال نفسه ,’,’,’,’

اولا يا ضعيفي الرياضيات !!

إضافة 10% الى الراتب ...... كيف ؟؟؟

الراتب نفسه + (الراتب نفسه * 0.1 )

لا تعرف كيف جائت الـ 0.1 ؟؟

اولا انطقها .؟؟ لا تعرف ان تنطقها ؟؟ تنطق واحد من العشرة ...

او عشرة من المئة ...

او مئة من الألف

.....


يعني ... 10% هي عشرة في المئة !!

لو قسمنا 10 على مئة .. تصبح 0.1 هل فهمت ؟

طيب ...

نضيف الى الراتب عشرة في المئة ... يعني عشرة في المئة من الراتب نفسه... نضيفها الى الراتب نفسه

مثال ...

1000 دولار .... ماهو الـ 10% منه ؟

100 دولار صح ؟؟

طيب اضف الى الـ 1000 دولار نسبة 10% !!

الحل هو 1000 + 100 = 1100 ,,,


انتهى درس الرياضيات ....

اليك المثال الان .....


Salary after the addition = salary + (salary * (10/100))


و 10 تقسيم مئة كما قلنا ... تساوي 0.1

طيب ...

انظر المثال .. وتعمق فيه وهو عرض الراتب العادي , والراتب ما بعد الزيادة ,,,








select job,sal,

decode(job,'SALESMAN',sal+(sal*0.1)

,'CLERK',sal+(sal*0.2)

,'MANAGER',sal+(sal*0.4)

,'PRESIDENT',sal+(sal*0.7)

,'ANALYST',sal+(sal*0.5) , 0) SAL_AFTER from emp;




واو .. طويلة الدالة ..

دالة ذكية جدا .. تأخذ أي عدد من المدخلات على حسب ما نريد !!

انظر الى المدخل الاول ... وهو حقل الـ job .... لماذا هذا الحقل ؟؟

كأننا نقول يا ايتها الدالة decode .... انظري الى الحقل JOB


اذا كان الـ job يساوي SALESMAN فاعرض القيمة sal+(sal*0.1)


اذا كان الـ job يساوي CLERK فاعرض القيمة sal+(sal*0.2)


وهكذا ....

حتى اذا وصل الى القيمة الغريبة .. التي انا وضعتها !! وهي الصفر ..

هل شاهدت المدخل الاخير ؟؟ انه صفر !! لماذا صفر ؟؟ وما هو فائدته ؟؟

صراحة هنا تأتي أي قيمة .. يعني الدالة decode تشاهد هذا المدخل وتقول .. ممممم اذا لم يكن الـ job لا CLERK ولا ANALYST ولا أي شيء مما ذكر انفا ..... اذن .. اعرض القيمة صفر ..

مارأيك و وضعنا واحد هل تضر ؟؟ هل تؤثر في العمل ؟؟

طبعا لا .. ولكن بدلا من ان يعرض صفر للذي عمله ليس من القائمة السابقة .. فسوف يعرض واحد !!!





JOB SAL SAL_AFTER

--------- ---------- ----------

CLERK 800 960

SALESMAN 1600 1760

SALESMAN 1250 1375

MANAGER 2975 4165

SALESMAN 1250 1375

MANAGER 2850 3990

MANAGER 2450 3430

ANALYST 3000 4500

PRESIDENT 5000 8500

SALESMAN 1500 1650

CLERK 1100 1320

CLERK 950 1140

ANALYST 3000 4500

CLERK 1300 1560




هل رأيت ذلك ؟؟

عرضت بشكل جميل جدا ...

ان بعضكم يعرفون انني اعرف أنهم لم يفهموا لذا .... مثال اخر أصعب ...... واعقد

احتج بعض الموظفين ,, وقالوا من الظلم التفرقة بيننا وان تعاملونا على حسب الوظائف .

المفترض (كما يقولون هم وليس انا) ان يكون على حسب الراتب !! لكي يكون أدق وأفضل لهم !!

يعني كما يلي :

اذا راتب اقل من 1000 دولار ...... يزيد بنسبة 10%

اذا راتب اقل من 2000 دولار واكبر من 1000 دولار .. يزيد بنسبة 20%

اذا راتب اقل من 3000 واكبر من 2000 .. يزيد بنسبة 30%

اذا راتب اقل من 4000 واكبر من 3000 .. يزيد بنسبة 40%

اذا راتب اقل من 5000 واكبر من 4000 .. يزيد بنسبة 50%

اذا راتب اكبر من 5000 ,,,, يزيد بنسبة 60%

هكذا اعدل وافضل !!

سنعود ...

The Coder
15-01-2006, 01:35 AM
اليك الجملة .... وكلي ثقة انك فكرت اصلا في الحل ...

اولا يا اصحاب الرياضيات ... يا احباب الرياضيات .. يا ضعاف الرياضيات ..

كيف نعرف ان هذا الراتب اقل من كذا وكذا ؟؟ واكبر من كذا وكذا ؟؟

المسئلة هذه بسيطة .... فمثلا ... 2500 دولار .. اكبر من 2000 واصغر من 3000

كيف عرفت ؟؟ كيف عرف عقلك البشري اوتوماتيكيا ؟؟ من اخبرك انه بين 2000 و 3000 ؟؟

هل جاءت صدفة ؟؟ هل اتاك الوحي ؟؟

انا اخبرك ... من سرعة عقلك ... حسبها بسرعة فائقة جدا .. وانت لا تعلم

عرف انه بين 2000 و 3000 بطريقة ما ... وانت لا تعلم

لديه قواعد وقوانين .... وطبقها ... وانت لا تعلم ...

اليك حل قوي .. اليك قاعدة مبتكرة ...


Trunc(2500/1000)= 2

Trunc(2999/1000)=2

Trunc(2000/1000)=2


هل شاهدت مالذي حصل ؟؟

الاعداد ما بين 2000 و الـ 3000 لها نفس النتيجة في المعادلة السابقة !


Trunc هي دالة القص ... هل تذكرها ؟؟ اذا لم تذكرها لا تكمل الدرس ... ارجع للدروس السابقة او ارجع للملخص !!....


اذن ..

اخترعنا قاعدة .... اسسنا قاعدة ... اذا كان الناتج من


Trunc(number/1000)=2


فان هذا العدد يكون اكبر من او يساوي 2000 واصغر من الـ 3000 !

نفس الشيء ...


Trunc(number/1000)=1


فان هذا العدد يكون اكبر من او يساوي 1000 واصغر من الـ 2000 !!

لن اكمل .. ولكن اليك الجملة .....








select sal ,

decode(trunc(sal/1000),0,sal+(sal*0.1)

,1,sal+(sal*0.2)

,2,sal+(sal*0.3)

,3,sal+(sal*0.4)

,4,sal+(sal*0.5)

,sal+(sal*0.6) )SAL_AFTER from emp ;







انظر جيدا !! ....

هذه الجملة صعبة ... صعبة جدا لكثير من الناس !!

ركز جيدا فيها ....

قبل البدء .. انظر دالة trunc درسناها بمدخلين صح ..

يعني هكذا


Trunc(1000,2)=1000.00

Trunc(1000,0)=1000


صح ؟

لو جعلناها بمدخل واحد ... فسوف تفترض هي .. ان المدخل الثاني صفر ,ـ,ـ,ـ,ـ,ـ,ـ,ـ,ـ,ـ,ـ,ـ,

اوكيه !! يعني :


Trunc(1000.124547)=1000


الان نرجع لدالة decode


اول مدخل هو ماذا ؟؟


هل هو sal ؟؟

هل هو job ؟؟

لا !!

معادلتنا السابقة !!

الدالة decode تقول ... تريدني ان ارى ناتج هذه المعادلة !!

تأتي لأول صف ... وترى ان راتبه 800 دولار !!

وانظر ماذا تقول هذه الدالة :

"... مممممم 800 تقسيم 1000 الناتج هو 0.8

ومع القص !! ... تصبح صفرا !!

ممممممم اذا كان الناتج صفرا .... فسوف اعرض الناتج بما يلي :


800+(800*0.1)=880 dollar


اذن سوف اعرض الاول ... 880

الي بعده .... هه ... هذا الاخر راتبه 1100 ...

1100 تقسيم 1000 الناتج هو 1.1


ومع دالة القص يصبح الناتج واحد !!

ممممم ... أي الاحتمالات ؟؟ اها ..

اذا كان الناتج هو واحد فانه سوف اعرض مايلي :


1100+(1100*0.2)=1320 dollar


سوف اعرضه اذن ^^


"


هل فهمت ؟

يعني اول مدخل هو المعادلة ... هو ما سوف ننظر الى ناتجه !!

والبقية الاحتمالات !!

اذا كان كذا فيصبح الناتج كذا ...

اذا كان كذا فيصبح الناتج كذا ....

وهكذا ,’,’,’

الاحتمال الاخير ... وهو اذا لم يكن كما سبق .. فاعرض sal+(sal*0.6)




انظر الناتج !!








SAL SAL_AFTER

----- ----------

800 880

1600 1920

1250 1500

2975 3867.5

1250 1500

2850 3705

2450 3185

3000 4200

5000 8000

1500 1800

1100 1320

950 1045

3000 4200

1300 1560







طيب ...


اليك التحدي الاول !! وهو من ابسط التحديات التي اطرحها ,’,’,’,’

لو اردت ان اعرض مايلي :





JOB RANK

--------- ----

CLERK D

SALESMAN E

SALESMAN E

MANAGER C

SALESMAN E

MANAGER C

MANAGER C

ANALYST B

PRESIDENT A

SALESMAN E

CLERK D

CLERK D

ANALYST B

CLERK D




يعني ... مايلي

اذا كان PRESIDENT فالرتبة A


اذا كان ANALYST فالرتبة B


اذا كان MANAGER فالرتبة C


اذا كان CLERK فالرتبة D


اما اذا كان SALESMAN فالرتبة E

The Coder
15-01-2006, 01:50 AM
اليك مثال اخير ....




اذا راتب اقل من 1000 دولار ...... يزيد بنسبة 10%

اذا راتب اقل من 1500 دولار واكبر من 1000 دولار .. يزيد بنسبة 20%

اذا راتب اقل من 2000 واكبر من 1500 .. يزيد بنسبة 30%

اذا راتب اقل من 2500 واكبر من 2000 .. يزيد بنسبة 40%

اذا راتب اقل من 3000 واكبر من 2500 .. يزيد بنسبة 50%

اذا راتب اقل من 3500 واكبر من 3000 .. يزيد بنسبة 60%


اذا راتب اقل من 4000 واكبر من 3500 .. يزيد بنسبة 70%


اذا راتب اقل من 4500 واكبر من 4000 .. يزيد بنسبة 80%


اذا راتب اقل من 5000 واكبر من 4500 .. يزيد بنسبة 90%


اذا راتب اكبر من 5000 ,,,, يزيد بنسبة 100%


لاحظ ان الفرق بين الاحتمالات 500 !!

يعني ... انظر الجملة .. وحاول فهمها !!

مع العلم ان .....


Trunc(999/500)=1

Trunc(1499/500)=2

Trunc(1999/500)=3

……











select sal ,

decode(trunc(sal/500),0,sal+(sal*0.1)

,1,sal+(sal*0.1)

,2,sal+(sal*0.2)

,3,sal+(sal*0.3)

,4,sal+(sal*0.4)

,5,sal+(sal*0.5)

,6,sal+(sal*0.6)

,7,sal+(sal*0.7)

,8,sal+(sal*0.8)

,9,sal+(sal*0.9)

,sal+(sal*1.00))

SAL_AFTER from emp ;







والنتيجة كما يلي ... نتيجة احصائية بحته !!










SAL SAL_AFTER

----- ----------

800 880

1600 2080

1250 1500

2975 4462.5

1250 1500

2850 4275

2450 3430

3000 4800

5000 10000

1500 1950

1100 1320

950 1045

3000 4800

1300 1560




انتهت الدالة ... وبدينا في درس اليوم ...

شاهدنا كيف يمكننا ان نوجد مجموع رواتب الموظفين في القسم 30

انظر الجملة !!








select sum(sal) from emp

where deptno=30;









طيب .. اريد ان اعرض مجموع رواتب الموظفين في القسم 10 .. والقسم 20 والقسم 30

نستطيع بعمل ثلاث جمل .....








select sum(sal) from emp

where deptno=10;










select sum(sal) from emp

where deptno=20;










select sum(sal) from emp

where deptno=30;







طيب لو كان هنالك مليار قسم ؟؟

كيف اعرض مجموع الرواتب في كل قسم ؟؟

يعني عرض مجموع الرواتب لكل قسم في جملة واحدة !!

ماذا اعمل ؟؟

فكر فكر فكر فكر .....

اريد ان اعرض اعلى راتب للمحللين .. واعلى راتب للمدراء .. واعلى راتب للبائعين !!

ماذا اعمل ؟؟

هل تستطيع ان توجد الجملة ؟؟

صح !! بدوال المتعددة الصفوف .. لكن كيف ؟؟

فكر بالله عليك ....

لاحظ انني قسمت المجاميع على حسب الاقسام .. في طلبي الاول

ولاحظ انني قسمت المجاميع على حسب الوظيفة في طلبي الثاني

دوال المتعددة الصفوف لاتتقسم !!

هي توجد مجموعة صفوف واحدة فقط !! في جملة الاستعلام الواحدة !!

ركز .. مجموعة صفوف واحدة .....

اعيد واكرر .. ركز ما معنى مجموعة صفوف واحدة ؟؟

يعني تخيل مجموعة صفوف ... وهي صفوف القسم 30 ..... هذه مجموعة واحدة ....

هل نستطيع ان نوجد مجموعة صفوف القسم 20 ومجموعة صفوف القسم 30 ؟؟

بمعنى اخر .. هل نستطيع ان نوجد مجموعتي صفوف اثنتين ؟؟ او ثلاث ؟؟؟ او اكثر ؟؟؟

في الحقيقة لا تستطيع وحتى هذه اللحظة ...

لذا مالحل ؟؟ مالعمل ؟؟؟ من المنقذ هذه المرة ؟؟ هل هي دالة ؟؟ هل هو شرط ؟؟ هل هو سوبرمان ؟؟؟

انظر الى جملة الاستعلام التالية !! انظر جيدا .... احد الاغبياء كتبها بدون تفكير منطقي (في الحقيقة انا هو من كتبها !)








select ename,sum(sal) from emp ;







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

ماذا تعني الجملة السابقة ؟؟

بالله عليك قلي ... مالناتج من هذه الجملة ؟؟

ماذا تتوقع ان يكون الناتج ؟؟ فكر قليلا .....

هل فكرت ؟

طيب

انا شخصيا وجدت الغباء والبلاهة الشديدين في الجملة السابقة !!

مالذي سوف ينعرض ؟؟ طبعا سوف ينعرض الخطأ التالي !!





ORA-00937: not a single-group group function






لا عليك من الخطأ الان ..

ستعرف الحل ... وسوف اعدك انك ستعرفه افضل من أي شخص اخر في دورة اخرى او كتاب اخر ,’,’,’,’

سوف اجعلك تتعمق في مفهومه .. بشكل معقد وقاسي ..... لكي تتعامل مع أي قاعدة بيانات ضخمة !!

يجب ان تعرف ان صعوبة الامر ليس في الـ SQL !! بل في ضخامة الجداول , وكثرة البيانات , وتعقيد البناء وحساسية الموقف .. اذ انه ادنى غلطة ... تطردك من العمل وغرامات مادية وسجن ووو ..... !!


لذا يجب ان تكون متمكنا وتعرف مداخل ومخارج هذه اللغة بشكل قوي !!

انسى الان شيء اسمه لغة استرجاع البيانات select انسى امرها الان ...

هل انتهت ؟ لا لم تنتهي !!

انا فكرت مليا في تخطيها الان ... وان اقفز الى الامام لنتائج افضل

بامكاني استعرض كل شيء كالكتب التقليدية .. ولكن مالفائدة ؟؟ كان بامكاني اعطائك المراجع ... وانتهى كل شيء !!

سوف اتعمق في الـ SQL لانها روح قواعد البيانات !!

ثم اتعمق في اللغة المتطورة منها وهي PL-SQL وهي العقل المفكر والمدبر من لغة الـSQL أي الجزء المنطقي منها !!

وما بعدهما يهون , وبسيط !!

كيف تعمل التقارير وكيف تعمل النوافذ وكلام فاضي .. تحفظه في ايام بسيطة .. اسبوع اسبوعين بالكثير ولا يوجد معك مشاكل ,’,’,’


........

The Coder
15-01-2006, 01:59 AM
الان ما هي اقسام لغة الـ SQL ؟؟ نسينا ؟؟ نعم اعرف انك نسيت ,,,, الدرس السادس يا محترم !!

هي مايلي :





1- استرجاع البيانات (Data Retrieval)


وبها مصائب الـ select




2- لغة التلاعب بالبيانات (Data Manipulation Language) اختصارها DML


وهي تخص بتعديل , حذف , او اضافة البيانات والسجلات في جدول ما ....




3- التحكم بالعمليات (Transaction Control)


هذه خاصة بتثبيت وحفظ العمليات ...




4- لغة تعريف البيانات (Data Definition Language) اختصارها DDL


وهي التي تخص بتعديل , حذف او اضافة وانشاء الجداول وخصائصها (الاعمدة) وعلاقاتها ..





5- لغة التحكم بالبيانات (Data Control Language) اختصارها DCL


خاصة بالصلاحيات ..





افترض اننا انتهينا من القسم الاول .. ونحن في الحقيقة لم ننتهي !!





القسم الثاني : لغة التعامل او التلاعب بالبيانات (Data Manipulation Language) اختصارها DML


وبها ثلاث جمل !!

الجملة الاولى INSERT INTO وهي خاصة باضافة بيانات للجدول

الجملة الثانية UPDATE وهي خاصة بتعديل البيانات للجدول

الجملة الثالثة DELETE وهي خاصة بحذف بيانات من الجدول

يجب ان تعرف ان هذه الجمل الثلاث اختصاصها الصفوف !

يعني شغلها في الصفوف ... تضيف صفوف تعدل صفوف تحذف صفوف !! تنبه لذلك !!





الجملة الاولى INSERT INTO


انا صراحة .. طفشت من المعلومات التي اراها دائما في جدول emp


اريد ان اضيف معلومات من رأسي ....

ممممم .... مثلا اريد ان يكون هنالك موظف اسمه Bill ويأخذ راتب 4250 دولار ...وهو محلل .... واي معلومات اخرى ,,,

بجملة Insert into استطيع اضافته !!





اليك جملة الاضافة هذه








insert into emp values(7777,'BILL','ANALYST',7566,'20/01/80',4250,null,10) ;




يعني ادخل القيم الى الجدول emp


وللمتعسر في الانجليزية ..


Insert ادخال


Into الى


Values قيم (مجموع قيمة)

الان انسى شرحها التفصيلي وانظر الى النتيجة...





1 row created.







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

يا سلام ...الان .. هل ادخلناه فعلا .. انا لا اصدق .... يجب ان اراه .. يجب ان اتأكد !!

كيف اتأكد ؟؟ كيف اعرف ؟؟ اها .. افتكرت جملة قديمة جدا , لن انساها ابدا .. هذه هي الجملة :





select * from emp

where ename='BILL';







وسوف تظهر النتيجة التالية :





EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

------ ---------- --------- ---------- -------- ---------- ---------- ----------

7777 BILL ANALYST 7566 20/01/80 4250 10




ياسلام .. اضفناه ... رائع !!

الان نرجع الى شرحها ...





insert into emp values(7777,'BILL','ANALYST',7566,'20/01/80',4250,null,10) ;




فكر لماذا وضعناها بهذا الترتيب ؟؟ الترتيب كما يلي

رقم الموظف , اسمه , مهنته,مديره,تاريخ تعيينه,راتبه,الراتب الإضافي, رقم القسم

لماذا لم نضع الراتب اولا ثم اسم الموظف ثانيا ثم رقم القسم ثالثا ؟؟

لماذا بهذا الترتيب بالذات !!

ولماذا الـ null ؟؟ لماذا لم نكتب فراغ إشارة الى القيمة الخالية ؟؟

انا جربت ... الفراغ والذي يمثل علامتي تنصيص احادية فارغة لا شيء بينها كما يلي





insert into emp values(7777,'BILL','ANALYST',7566,'20/01/80',4250,'',10) ;




هل لاحظتها !! انها ليست علامة تنصيص ثنائية !! بل علامتي تنصيص احادية !!

وسوف تضاف على انها قيمة خالية !! هل فهمت !!

لا تنسى ان التاريخ والنص ... بين علامتي تنصيص احادية ,,,,

الان لماذا وضعنا القيمة الاولى رقم وليس نص ؟؟ ولماذا وضغنا القيمة الثانية نص وليس رقم ؟؟؟

ان أي جدول مصمم بشكل معين ... قبل ان تضيف شيء ... تأكد من ترتيب الاعمدة بواسطة الجملة التالية :





select * from emp;




هل فهمت !!

انتبه !! احفظ تركيب جملة الإضافة !!


طيب لو غلطنا ... او تعمدنا ان نضيفه مرة ثانية ...

يعني نكتب الجملة نفسها مرة ثانية ... مالذي يحدث ؟؟؟

مالذي سوف ينتج ؟؟

لو جربنا فسوف نواجه الرسالة التالية !!





ORA-00001: unique constraint (SCOTT.PK_EMP) violated




خطأ !!

لماذا خطأ ؟؟ وماذا تعني الجملة السابقة ؟؟

اتركها الان ولكن سأخبرك لماذا !!

لانك اضفت قيمة مكررة في عمود رقم الموظف !! وهو مفتاح رئيسي .. لا يمكن ان يتكرر ولا يمكن ان يكون خاليا !!

جرب وان تضع قيم من عندك ... وان تضع رقم الموظف خالي !! أو ان تضع قيمة مكررة له !!

او ان تضع قيمة خالية في المفتاح الاجنبي (رقم القسم )

كلها تؤدي الى اخطاء !!

الان ... تخيل انك لا تعرف ترتيب الاعمدة ..

او انك تستعبط وتريد ان تضع من عندك ترتيب ... !! مالعمل ؟؟ ماذا تفعل يا عبيط ؟؟؟

اليك الجملة بشكلها المحسن الكامل !!










insert into emp(ename,sal,hiredate,mgr,empno,comm,deptno,job) values

('JONE',1500,'01/01/88',7782,7744,null,10,'SALESMAN');




يعني فتحنا قوس وذكرنا الاعمدة بترتيبنا الذي نرغبه !! .... ثم وضعنا القيم بالترتيب نفسه !!

لاحظ ان ترتيب القيم هو نفس ترتيب الاعمدة الذي وضعناها !!

لو وضعتها مختلفة عن بعض ... فاتق الله !! وضعها بنفس الترتيب الذي ذكرتها يا عبيط !!

وسوف تكون النتيجة كيف ؟؟ هل تعتقد انها بنفس الترتيب الذي ذكرته ؟؟ انظر مايلي :








select * from emp

where ename='JONE';











EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

----- ---------- --------- ---------- -------- ---------- ---------- ----------

7744 JONE SALESMAN 7782 01/01/88 1500 10





بنفس ترتيب الجدول نفسه !! يعني هذا الترتيب المبني عليه هذا الجدول !!


بالرغم من اننا ادخلنا بترتيب عشوائي اخترناه ... فهو يخزنه على حسب ترتيبه في الجدول ,’,’,’

الان .. يجب ان لا يكون المفتاح الرئيسي والمفتاح الاجنبي خاليان

فيما عداهم .. لا ضير من كونها خالية !!

طيب ... احدهم يريد ان يضيف اسم ورقم موظف .. وقسمه فقط !! والبقية قيم خالية , اليك الجملة

مثلا الاسم ANY_ONE


والرقم 7000 وفي قسم رقم 90





insert into emp(ename,empno,deptno) values

('ANY_ONE',7000,90);




هل لاحظت ترتيب الاعمدة ؟؟ لم اذكر كل الاعمدة .. بل ذكرت الاعمدة التي اردتها ,,,

وبالترتيب الذي اريده ... انظر النتيجة الجميلة :








ORA-02291: integrity constraint (SCOTT.FK_DEPTNO) violated - parent key not found




خطأ موقع ومعتمد من قبل الهيئة الملكية الشرعية للأوراكل !!

تعرف لماذا هذا الخطأ ؟؟

لأننا اضفنا رقم قسم غير موجود اصلا في جدول الاقسام !!

انظر الى نتيجة الجملة التالية





select * from dept;
















DEPTNO DNAME LOC

------- -------------- --------

10 ACCOUNTING NEW YORK

20 RESEARCH DALLAS

30 SALES CHICAGO

40 OPERATIONS BOSTON




لا يوجد رقم قسم =90

هل فهمت لماذا ؟؟

لانه هناك في جدول الـموظفين مفتاح اجنبي !!

وهنا طبعا مفتاح رئيسي ,

الأوراكل لديها علم بذلك ... من قال له ؟؟ من غششه ؟؟ من اخبره بأن رقم القسم مفتاح اجنبي في جدول الموظفين ؟؟

وما هي المخاطر والمشاكل المحتملة عن وجود رقم 90 ؟؟أو عن وجود قيم خالية في المفتاح الاجنبي !!

هل تذكر الصفوف او السجلات اليتيمة !! ؟؟

هل تذكرها ؟؟ في الدرس الخامس على ما اعتقد !!

اذهب واقرأها ثانية !!

The Coder
15-01-2006, 02:08 AM
أصر على عدم إكمال مشوارك اذا لم تفهمها او نسيتها !!

وأصر على ان ترجع الى الدرس الخامس وبشدة !!

نرجع ...

لقد اخبر الأوراكل هو من عمل الجدول !!

وسوف ندرس كيف نعمل الجداول ونعمل هذا الربط بين الجداول , ان شاء الله قريبا

هل صعبة جملة الادخال Insert into ؟؟؟

ابدا ليست صعبة

هل انتهت ؟

لا لم تنتهي !!

هنالك جزئية متقدمة قليلا ..

مثلا عملنا جدول المدراء .. وبه الاعمدة التالية :

رقم الموظف

اسم الموظف

الراتب

القسم

واردت ان انسخ معلومات المليار مدير في جدول الموظفين !! ماذا اعمل ؟

لدي حلين !!


اما ان اكتبهم واحد تلو الاخر , وهذا الحل مريح جدا كما تعرف

فعملية نقل مليار مدير .. سهلة جدا لمدخل البيانات , وهو مبسوط وفي ثواني ينتهي منها !!!

الحل الثاني وهو ما سوف نستخدمه

الاستفسارات او الاستعلامات الفرعية !

لا عليك من هذا الاسم .. ولا تخف ولا تحزن .. وابشر بالفهم السريع لهذه الاستفسارات الفرعية sub-query


مجرد استفسارات عادية جدا وسوف تدرسها بتعمق شديد لقوتها وبعض تعقيدها !!

اليك النقل السريع في اللا وقت , ونسخ بالملي والسانتي ,

ولاحظ عدم وجود كلمة values في هذا النوع من الجملة !








insert into manager (empno,ename,sal,deptno)

select empno,ename,sal,deptno from emp where job='MANAGER';




في جملة الاستعلام , كأنه لا يقول اعرض كل من كان مهنته=مدير !!

بل يقول اعطي الصفوف التي اخترتها لجملة الادخال !!

يعني اعطي كل من كان مهنته = مدير الى جملة الادخال

لاحظ ترتيب الاعمدة في جملة الاستعلام مطابقة تماما في جملة الادخال !!

هل رأيتها ؟؟ ركز !! لو شقلبنا الترتيب ... حنروح في ستين نيلة ,

انتبه جيدا !!

الان اذا لم تفهم فكرة الاستفسارات الفرعية فلا تخف ... سوف اغطيها ان شاء الله , وسوف تفهمها اكثر

كل ما في فكرتها هي بدلا من اعرض , اعطي !!

وسوف نستخدمها في جملة الاستعلام ايضا !! فهي عظيمة النفع





الان اعتقد انني ارتكبت حماقة !!

ادخلت الموظف BILL في قسم غير قسمه !!

لقد اخطأت !! مالعمل ؟؟ ماذا افعل ؟

اعدله ؟ نعم اعدله !! ولكن كيف ؟؟





الجملة الثانية UPDATE


وهي خاصة بتعديل البيانات للجدول

اعيد واكرر !!

نحن نتعامل في لغة DML مع الصفوف .. مع السجلات !!

هل تفهم ذلك ؟ هل تذكر جملة الادخال ؟؟ كانت تدخل اعمدة جديدة ام سجلات (سجلات = صفوف) جديدة ؟

طبعا سجلات !!

فانتبه لهذه النقطة

الان اريد ان اعدل حماقاتي وان اجعل رقم قسم الموظف بيل الى القسم رقم 70

هل يجوز ؟؟ هل يصلح ؟؟ هل محلل عند اوراكل ام محرم ؟؟

طبعا لا يجوز !!

انت هكذا تعمل جريمة شنيعة بحق codd وبحق قواعد البيانات العلائقية كافة

لماذا ؟ لأنه لا يوجد قسم 70 في جدول الأقسام !!


وانت تعرف مخاطرها .....


الان ... اريد ان اجعله في القسم 30 !! اريد ان اعدله ...

اليك الحل .. جملة التعديل , جملة من اخطر الجمل !! جملة مخيفة فعلا !!

تعتبر الفلم المرعب لكل قاعدة بيانات !!

لماذا ؟ لأنها تصلح اخطائنا بكل سهولة ويسر , وتدمر احلامنا بنفس السهولة واليسر !!

بامكانها ان تعدل معلومات مليارات السجلات في .......... اقل من الثانية !!

وراحت المعلومات في الباي باي ,

الان انظر الى جملة التعديل ... بالعربي

عدل في جدول الموظفين قيمة رقم القسم الى 30 لكل السجلات التي رقم الموظف لديها = 7777







update emp

set deptno=30

where empno=7777;




وسوف تعرض النتيجة





1 row updated.




ياسلام ... صف واحد فقط تعدل !!

جميل ... الان و انا مطمئن , بامكاني ان ارى الجدول ,

الان هل تعرف لو لم نضع جملة الـشرط Where مالذي سوف يحدث ؟؟

سوف يقرأها البرنامج الغبي كما شاهدها ...

عدل في جدول الموظفين قيمة رقم القسم الى 30 لكل السجلات !!

وسوف تعدل جميعها , يعني تخيل تريليون سجل (تريليون = 1000 مليار) كلها سوف تعدل !!

وفي لمحة البصر ,’,’,’,’

فانتبه اخي , والله اني اريد لك الخير ,

اذا تذكرت جملة التعديل , فتذكر معها جملة الشرط !!

عود نفسك المقولة التالية " جملة الشرط مع جملة التعديل , جملة الشرط مع جملة التعديل .........."

جملة الشرط تتحكم في عدد السجلات , وما هي اصلا هذه السجلات فمثلا احد الاغبياء يريد ان يغير معلومات احد الموظفين (لاحظ احد وليس كل )والذي يدعى بـ Bill , المصيبه انه كتب هذا الامر








update emp set deptno=30

where ename='BILL';




ومالذي حدث ؟؟ الذي حدث ان حظه العاثر !! خانه هذه المرة وطعن في الظهر !!

لقد عرضت له هذه النتيجة





3000000 row updated.




ثلاث مليون سجل , قد تعدل

ثلاث مليون سجل , قد تغير

ثلاث مليون بيل قد تعدلت معلوماتهم

وجد انه يوجد 3 مليون موظف يدعى ببيل !!

لم نقل له كل من اسمه بيل !! بل قلنا له بيل الفلان الطيب الشخص الذي اوصافه كذا وكذا !!

انتبه لهذه النقطة !! اختر ما تريده في الشرط وكن حذرا !

الان اريد ان اعدل معلومات كل من اسمه بيل بمثل معلومات الموظف الطيب WARD


نرجع الى الاستعلامات الفرعية , او الاستفسارات الفرعية , او الاستعلامات الجزئية ..... سمها ما شئت ,

لا اريد ان ادوخك الان بها , ولكن للعلم الان ,

تعديل الثلاث مليون بيل (بيل = اسم لموظف وليس اسم لعملة !!) سهل جدا بالكتابة اليدوية , لكن انا لا اعرف معلومات الطيب WARD !! بافتراض انه لايوجد الا موظف واحد يدعى بـ WARD


اكرر ... موظف واحد فقط !! يدعى بـ WARD مثلا !!

كيف اعمل ؟

حلين .... اولا اذهب وارى معلومات الموظف ward ثم انسخ معلوماته على ورق ومن ثم اعدل الموظفين الذين اساميهم بيل بنفس المعلومات

الثاني هو ان استخدم الاستعلامات الفرعية وهي الاضمن !!

لانه في الحل الاول , لو يوجد 1000 عمود , (عمود = حقل) هل بالله عليك انسخهم على الورق قيمة قيمة ؟؟

او انتبه !! لو انك لم تكن تعرف معلومات الرجل الطيب !! ليس لك صلاحية ان تراها !! لا يحق لك ان تعرض معلوماته ... كيف تتصرف ؟

اذن الحل الثاني عملي اكثر و أأمن , وهو يصلح ايضا للحالة التي لا نعرف ماهي قيمها اكرر .... تصلح للحالة التي لا نعرف قيمها مثل انك لا تملك صلاحية رؤية ward ولا تعرف ما هي البيانات والقيم !!

اليك الحل








update emp

set (deptno,mgr)=(select deptno,mgr from emp where ename='WARD')

where ename = 'BILL' ;




Wow.. look at that


طبعا ركز في الاستعلام الفرعي , يقول الاستعلام الفرعي

اعطي رقم القسم و مدير الموظف ward لجملة التعديل ,

وتقول جملة التعديل ...

هاتي يا أيتها الاستعلام الفرعي قيمة رقم الموظف و رقم المدير لكي اعدل رقم قسم ورقم مدير كل من اسمه بيل ,

(اعرف ان لغتي العربية غبية ولكن ................... اكمل يا رجل )

لاحظ تطابق الاعمدة في جزئية set وفي جزئية الاستعلام الفرعي !!

نفس التطابق ونفس الحقول ونفس ما كنا نتوقعه !!

هنا حقلين , وهناك حقلين .

لو شقلبنا الترتيب , لو اضفنا حقل في جزئية واحدة , لو وضعنا عمود زائد في جزئية ... كلها اخطاء لا تغفر .

الان ياسلام ... النتيجة تقول لك هنالك ثلاث مليون بيل (اكرر .. بيل ليست عملة !! بل اسماء موظفين) قد تغيرت قيم مدرائهم و ارقام اقسامهم بنفس قيم الموظف الطيب ward


الان دعك من الاستفسارات الفرعية , بسيطة ولكن لها قوانين وشروط سوف ندرسها بتعمق اكثر .

الان .. اريد ان احذف الموظفين BILL و JONE الذان اضفناهما صباح هذا اليوم ...

كيف ؟

بالجملة الاكثر رعبا من التعديل !! انها الجملة المدمرة !! انها الجملة القاضية !!

انها جملة حذف وتدمير السجلات !!

The Coder
15-01-2006, 10:21 PM
الجملة الثالثة DELETE


وهي خاصة بحذف بيانات من الجدول أي حذف والتهام السجلات ولا شيء غير السجلات !!

نفس فكرة التعديل !!

يجب ان تحذر في وضع الشرط ... لان الشرط هو الذي يحدد مَنْ مِنَ السجلات سوف يتم إعدامه




نريد ان نحذف BILL و JONE


هيا نحذفهما !! لقد خربناهما ولعبنا في قيمهما كثيرا










delete emp

where ename='BILL' or ename = 'JONE';




الذي لا يعرف لماذا الـ or ولماذا لم تكن and فإنا لله وانا إليه لراجعون

الان سوف يحذف لنا كل من اسمه بيل او اسمه جون

وسوف تكون النتيجة





2 rows deleted.




اعيد واكرر .. انتبه للشرط !!

لو لم تضع الشرط , ستنسف ابو الجدول عن بكرة ابيه بقاذفة الصواريخ هذه !!

لو لم تتمعن في اختيار الشرط .. فسوف تذهب ضحايا من السجلات لا ذنب لها

فانتبه اخي ,

هنالك كلمة لا تسمن ولا تغني من جوع .. وهي from يعني بدلا من الجملة السابقة .. نكتبها بهذا الصيغة :





delete from emp

where ename='BILL' or ename = 'JONE';







لو اردنا حذف كل من هم في قسم WARD


لاحظ انني لا اعرف ما هو قسم الموظف ward !!


تخيل انني لا املك الصلاحية لرؤية قسمه !! مالحل ؟؟ مالعمل ؟ الاستفسارات الفرعية ,,,

الجملة كما تلي .. (اذا كنت تطبق فلا تكتب الامر التالي !! )





delete emp

where deptno=(select deptno from emp where ename='WARD') ;




بافتراض انه لا يوجد الا موظف واحد يدعى WARD


لاحظ انني اركز الان في الاستفسارات الفرعية على قيمة واحدة , صف واحد , WARD واحد

سوف تعرف فيما بعد عن الاستفسارات الفرعية .

اريد ان احذف القسم 10 من جدول الاقسام !!

مالعمل ؟

اليك الجملة (اكتبها ولا تخف )





delete dept

where deptno=10;




سوف يرفض البرنامج ذلك ويخبرك انه يوجد سجلات ابناء ,

وهي سجلات موجودة في جدول اخر يدعى بـ emp


فلا يجوز قتل ابيهم السجل صاحب رقم القسم 10 !!

والا فسوف ينتج عن ذلك السجلات اليتيمة ,

ويا عيني على الدرس الخامس لو مافهمت شي ... ارجع اليه !!





الان عرفنا ان نضيف , نعدل و نحذف البيانات .

وانتهينا من لغة الـ DML


ارتكبنا بعض الحماقات فيها , ولكن ... احدكم اخطأ وكتب الامر التالي بكل سهولة :








delete emp ;




واني اراه من الباكين .... واني ارى ان جدوله قد تدمر كليا , ولا يستطيع الان ان يطبق معنا

مسكين يا هذا ...

ولكن لا تخف !!

لا تقفل البرنامج يا رجل !!

انتظر !!

يوجد امر التراجع !! انتظرررررررر !!!!!

يظهر انني تأخرت كثيرا ..... المسكين اقفل وذهب الجدول سدى !!

هنالك اخر لم يقفل بعد بالرغم من انه يائس هو الاخر ,


اقول له ...تهانينا .. تستطيع ان تتراجع عن الحذف والتعديل

وذلك عبر لغة التحكم بالعمليات .... سوف نقفز اليها مباشرة ....


3- التحكم بالعمليات (Transaction Control)


هذه خاصة بتثبيت وحفظ العمليات ... او التراجع عن بعض العمليات ..

نقصد بالعمليات ماذا ؟؟عمليات استئصال القلب ؟؟ شرايين ؟؟

العمليات هي على سبيل المثال عمل جدول , اضافة حقل , حذف سجل , اضافة بيانات , تعديل البيانات .....


هذه هي العمليات ... هل فهمت ؟


اولا :COMMIT


هذا يحفظ العمليات التي قمت بها

فمثلا قمنا باضافة احدهم , ثم حذفنا اخر , ثم عدلنا ثالث ....

ثم كتبنا هذا الامر ... فسوف يتم حفظ ما فعلناه ,

في الحقيقة هذا الامر يكتب اوتوماتيكي اذا كتبنا الامر التالي :


SQL>EXIT


أي خروج , لذا فتنبه لهذه النقطة .

لو مثلا لم تكتب الامر EXIT , وضغطت على علامة X الموجودة في اعلى النافذة (الصورة 1001)


http://img9.picsplace.to/img9/6/1001.jpg


فسوف لن يحفظ لك العمليات التي عملتها .. جرب واضف موظف , ثم اغلق البرنامج من علامة الـ X ,


عندما تفتح البرنامج , وتبحث عنه فسوف لن تجده لانك لم تحفظ العملية .





ثانيا :ROLLBACK


هذا يقوم بالتراجع عن ما فعلته من عمليات ,,

احذر !! لو مثلا حصل ما يلي :


قمت صباحا

شغلت البرنامج

اضفت موظف اسمه احمد ,

عدلت اسمه من احمد الى خالد ,

عدلت اسمه من خالد الى سامي

ثم كتبت ROLLBACK


فمالذي يحدث ؟؟

ماهو اسم الموظف الان ؟؟ وهل يوجد الموظف المضاف قبل قليل اصلا ؟

بالطبع لا ....

لايوجد موظف ,لاننا تراجعنا عن كل العمليات !!

طيب لو مثلا حصل مايلي :

قبل النوم .....

شغلت البرنامج

اضفت الموظف عبدالله

عدلت اسمه من عبدالله الى محمد

كتبت الامر commit


عدلت اسمه من محمد الى مصطفى

ثم كتبت الامر rollback


فمالذي سوف تتوقعه ؟؟؟ وهل يوجد الموظف الذي أضفته قبل قليل اصلا ؟ وما اسمه ؟

انتبه !! سوف يكون الموظف موجود , واسمه .......

ليس مصطفى !! بل اسمه محمد !!

لان الـ rollback ترجع لآخر نقطة تم الحفظ فيها , ونحن أضفنا عبد الله ثم سميناه بمحمد ثم حفظنا ثم عملنا بعض العمليات

ولما تراجعنا , فسوف نتراجع للنقطة الأخيرة عند الحفظ !

الان تخيل معي المنظر :


1- اضفنا الموظف سامي


2- عدلنا اسمه الى خالد


3- غيرنا رقمه

4- غيرنا قسمه

5- اضفنا موظف اخر اسمه عبدالله

6- حذفنا خالد

7- حذفنا عبدالله

تخيل اننا نريد ان نرجع الى النقطة 3

او تخيل اننا نريد ان نرجع الى النقطة 5

أو تخيل اننا بعد ان رجعنا الى النقطة 5 نريد ان نرجع الى النقطة 2

لا تنفع اذن commit لكي تكون نقاط حفظ !!

بل تنفع كحفظ نهائي لا رجعة له ,لذا نريد نقاط حفظ مؤقته .. مالعمل ؟؟؟ ماذا نفعل

اليك الامر التالي


SQL>SAVEPOINT A


وهذا الامر يخبرنا اننا حفظنا بشكل مؤقت , واسم النقطة هي A


الان انظر كيف القصة تغيرت (القصة=story وليس القصة التي في مقدمة الرأس !!)

1- اضفنا الموظف احمد

2- اضفنا الموظف خالد


3- SAVEPOINT the_add


4- عدلنا اسم احمد الى محمد

5- عدلنا اسم خالد الى سامي


6- SAVEPOINT the_update


7- حذفنا محمد

8- حذفنا سامي


9- savepoint the_delete


10- اضفنا الموظف سليم

الان لو كتبنا الامر ....


SQL> ROLLBACK TO the_delete


فسوف نرجع للنقطة التاسعة !! يعني كأننا لم نضيف سليم .

الان وبعد ان تراجعنا الى النقطة التاسعة .....

نريد ان نرجع الى النقطة السابعة .. نستطيع ؟؟ لا نستطيع

الان لا وجود للموظفين محمد وسامي

نستطيع ان نعود الى النقطة السادسة ... عبر الامر التالي :


SQL> ROLLBACK TO the_update


واو .. الموظفين موجودين الان !!

تذكر .. نحن الان في أي نقطة ؟؟ في النقطة السادسة .. والتي تسمى بـ the_update


الان لدينا خيارين .. اما ان نعود الى البداية او الى النقطة التي تسمى the_add والتي تتواجد في النقطة الثالثة

اعيد واذكرك الان ... اننا في النقطة السادسة !

كيف نرجع للبداية .. بكتابة الامر التالي :


SQL> ROLLBACK


كيف نرجع لنقطة the_add ؟؟ بكتابة الامر التالي :


SQL> ROLLBACK TO the_add




تخيل اننا قفزنا من النقطة السادسة (التي نتواجد بها حاليا ) الى نقطة البداية !! بكتابة الامر السابق ذكره ....

هل يتواجد موظفين احمد و خالد ؟؟

طبعا لا !

هل نستطيع الرجوع الى النقطة التاسعة ؟؟؟

طبعا لا !!!! انتبه .... انتبه جيدا !!

الان تخيل اننا في النقطة السادسة .. هل نستطيع العودة للنقطة المستقبلية وهي التاسعة !؟ لا لا نستطيع !!

تخيل اننا في النقطة الثالثة ... هل نستطيع التقدم الى المستقبل وان نذهب الى النقطة السادسة ؟؟ لا !!

هل فهمت ؟؟

اذن .....

هي نقاط تخزين مؤقته .... تنفعنا كثيرا وتخدمنا كثيرا , فلا تنساها ابدا ... لعلك تتندم يوما على عمل شيء ... فتتذكر انك عملت نقطة تخزين وترجع اليها , فسوف تفرح كثيــــــــــــــــــرا صدقني ,’,’,’,’,’,’,’

الان انتهينا من لغة الـ DML و لغة التحكم بالعمليات .... تقريبا ...

سوف نواجه بعض الامور فيهما , وسوف نرجع اليهما اذا لزم الامر ....

الان ... عرفنا ان نضيف نعدل ونحذف بيانات (سجلات بكلمة اخرى) في جدول ما ... ولكن كيف نضيف حقول !! مثلا

او كيف نضيف جدول اصلا !! طبعا عبر لغة تعريف البيانات .




4- لغة تعريف البيانات (Data Definition Language) اختصارها DDL


وهي التي تخص بتعديل , حذف او إضافة و إنشاء الجداول وخصائصها (الاعمدة) وعلاقاتها ..

هذه اللغة طويلة الى حد ما ... فانتبه ,

وتنبه لشيء اخر , وهو الحفظ !! سوف تتشتت كثيرا , لذا حاول ان تعمل عملية الفهرسة (التلخيص الذاتي) لكي لا تتشتت ,’,’,’,’,’


- البيانات ... وما أدراك مالبيانات .


هي القيم ... الموجودة في الجداول , والتي اما ان تكون أرقام , تواريخ , نصوص

الان اريدك ان تنسى أرقام تواريخ نصوص !!

وأريدك الان ان تتعرف الى أنواع البيانات الحقيقية في الأوراكل !!

The Coder
15-01-2006, 10:25 PM
اولا : Char وهو الخاص بالنصوص ....

اذا قال لك ان حقل ENAME من نوع CHAR(10) مثلا , فماذا تعني ؟؟

تعني ان الحقل ENAME نوعه نص , ويستوعب كحد أقصى 10 حروف للاسم الواحد !!

طيب واحد اسمه LEE هل يستوعبه ؟ نعم .... لأنه اقل من او تساوي 10

طيب واحد اسمه SADFJAPJFASDPJF هل يستوعبه الحقل ؟ لا يستوعبه لان الحروف اكبر من 10 ...





ثانيا : Varchar2 هذا الخاص بالنصوص ايضا ...

نفس الفكرة تخيل ان حقل ENAME من نوع VARCHAR2(10) فهذا يعني انه يستوعب 10 حروف للاسم الواحد .





في الحقيقة ... انه بينهما فرقين ... الفرق الاول .. الحجم ,

الـ char يأخذ كحد أقصى 2000 حرف أي اننا لو قلنا CHAR(2000) فهو صحيح , ولو قلنا CHAR(2001) فهو خطأ ,مالحل ؟؟ مالعمل ؟؟ نريد 2001 حرف !! مثلا لحقل العنوان !! .... الحل هو الـ varchar2 والذي يأخذ كحد أقصى 4000 حرف

الفرق الثاني , في الحقيقة انني لم افهمه , لأنه اولا لا يوجد عليه مثال في منهجين مختلفين !! يقولون ولا يمثلون او يشرحون , لذا فسوف ابحث فيها فيما بعد ان شاء الله , لن يرتاح لي بال حتى ارى ما كان قصدهم فيه !! فانتظرني .





ثالثا : number


وهي للأرقام طبعا , مثلا حقل الرواتب SAL فهو من نوع NUMBER(7,2) أي يكتب بهذه الصيغة :


Sal number(7,2)


ما معنى السبعة وما معنى الاثنين ؟؟؟؟

معنى السبعة ان حده الأقصى سبعة أرقام !!


اما معنى الاثنين فهو كم عدد بعد الفاصلة العشرية ؟

أي بمعنى اخر العدد :


99999.99


عدد مقبول وهو صحيح .. لماذا لانه سبعة ارقام ..... عدها ... هل عددتها ؟

منها رقمين عشريين ...

طيب احدهم اضاف الى الحقل sal هذا الرقم :


999999.9 هل هذا صحيح ؟؟

طبعا خطأ !!

لماذا ؟؟ صحيح انه سبعة ارقام .. ولكن يجب ان تنظر انه حدد خمسة ارقام للاعداد العشرية !!

كيف ؟

نحن قلنا ان حقل sal من نوع number(7,2)


يعني 7-2=5

خمس اعداد صحيحة كحد اعلى ....

وعددين عشريين (الاعداد العشرية هي الاعداد التي يمين الفاصلة ) سوف يعرضان فقط !!

يعني اكبر عدد بامكاننا ان نضعه هو 99999.99 واصغر عدد طبعا 0.00

لو وضعنا مثلا 100000.00 فهو خطأ !!

طيب احدهم اضاف الى الحقل sal هذا الرقم :

9999.999999999 هل هذا صحيح ؟؟

في الحقيقة انه صحيح لماذا ؟؟ ما هو السبب ؟ الم نقل ان حد الاعداد العشرية رقمين ؟؟

لماذا هذه صحيحة و شكلها خطأ !!

انا اخبرك ....

نحن حددنا ان الاعداد العشرية عددين صح ؟

طيب هو اوتوماتيكيا اذا شاهد اكثر من عددين عشريين فسوف يقربه !!

يقربه كيف ؟

انت قلت اننا وضعنا كحد اقصى عددين عشريين صح ؟

طيب انظر العدد هذا :


1.214235


سوف ينظر كم حددنا من اعداد عشرية ...

سوف يرى انها اثنين ,

سوف يرى العدد الثالث وهو الرقم 4

اكبر من او يساوي الخمسة ؟؟ لا

اذن كل الاعداد التي يمين العدد الثالث بما فيهم العدد الثالث ..... قص !!

ويصبح العدد 1.21

وسوف يخزن كما هو .... 1.21

طيب مثال اخر ....


1.425167


ينظر كم حد الاعداد العشرية ..

يجدها اثنين ....

ينظر الى العدد الثالث وهو الخمسة ....

هل اكبر من او يساوي خمسة ؟؟ نعم !!

اذن قص العدد الثالث وكل الاعداد التي يمينه واضف واحد للعدد الثاني

يصبح الناتج : 1.43





الان تخيل واحد قال


Sal number


ماذا يعني ؟؟ يعني ان الحقل sal يستوعب عدد ضخم من الارقام يصل الى 127 رقم ... هل تعرف ما معنى 127 رقم ؟؟؟؟

يعني 99999999999999999......... افففف ... تعبت وانا اكتب !!!


يعني مئة وسبعة وعشرون ...... رقم تسعة بامكاننا ان نضعها !!

اما الاعداد العشرية . فحدث ولا حرج ...... لذا فهو يقرب بطريقة معقدة قليلا فتجاهل الوضع ....





الان ..... لو عندنا حقل ... أي حقل ... اسمه وليكن any_column وهو رقم ...

اذا كنت تريد عرضه بشكل عادي ..... فاجعل دائما الاعداد العشرية اصغر من الاعداد الصحيحة ...

يعني المثال التالي صحيح

Any_column number(10,9)


اما لو وضعت :


Any_column number (9,10)


فمالذي سوف يحدث ؟؟

هذا تحدي ثاني !! للمساعدة .. اعمل جدول جديد (سوف تعرف كيف في هذا الدرس )وبه هذا العمود واجلس جرب .. اضف قيم من عندك .....





رابعا : date


وهو التاريخ , وما أدراك مالتاريخ , يستوعب أوتوماتيكيا 14712 ما قبل الميلاد الى 319999 ميلادي ...

كيف اتوماتيكيا ؟ يعني بدون ان نحدد له حد .. مثل ما فعلنا سابقا في CHAR(2000) مثلا , هو يكتب مجرد DATE.




خامسا : LONG


مثلا اريد حقل يتكون من اكثر من 4000 , هل استخدم معه VARCHAR2 ؟؟؟ طبعا لا

تستخدم الـLONG وطبعا لا يمكن تحديد عدد معين مثل CHAR(40) ولكن يكتب كما هو مجرد LONG مثل الـتاريخ .

الـ LONG يصل حده الى اكثر من 2000000000 (اثنين مليار) حرف !!!

لا اعلم لماذا وضعوه ولم اشاهد حقل نوعه LONG ولا اعتقد انني سوف اشاهده , لانه اكيد للمشاريع الضخمة جدا .





يكفي عليك هذه الانواع , ولا اخفيك انه يوجد اربع او خمس اخرى , ووالله لا اعرف اصلا في أي شيء تستخدم , ولكن لو تفرغت فسوف ابحث فيهم . ولكن معظمها للحقول ذو كمية استيعاب ضخمة جدا لأغراض الصور والرسومات كبيرة الحجم .





الان نرجع لمحورنا الرئيسي .

الجداول ...

الان نستعرض أوامر لغة DDL


DESC : لاستعراض بناء جدول ما .


CREATE TABLE : لإنشاء الجداول .


ALTER TABLE : للتعديل في بناء الجدول .


RENAME TABLE : لتعديل اسم الجدول


DROP TABLE : لحذف الجدول نهائيا .


TRUNCATE TABLE : لحذف السجلات !!؟؟


COMMENT : لاضافة التعاليق التذكيرية على الجداول والاعمدة .




"واو .. كثيرة ... معقدة .. صعبة !!

ماذا تفعل .. اترك الأوراكل ... انها صعبة جدا !! "


هذا قول بعضكم , انهم سارقو الطاقات !! انهم المحبطون لأنفسهم و محبطون لمن بجانبهم .... انهم الهاضمين لحقوق انفسهم .... انهم المتشائمون .

تالله انها بسيطة , وسوف نسردها على السريع الطاير , ولن نكثر فيها الكلام لانها .... منطقية بالنظر ..

أي مشاكل راسلنا او اعرض مشكلتك في موضوع الاستفسارات .

الان ... نبدأ على بركة الله


الامر DESC :


ما رأيك في الجدول DEPT ؟؟؟

هل تذكره ؟؟؟

اعتقد ان له بعض الحقول منها DEPTNO وهو رقم , ولكن لا اعرف كم يستوعب , مارأيك ؟؟؟ هل نشاهد ذلك ؟ لنشاهد ذلك :





DESC DEPT;




الامر الخاص بالكشف عن تركيب وبناء الجداول .. استخدمناه مع الجدول DEPT


والنتيجة كانت :





Name Null? Type

-------- -------- -------------

DEPTNO NOT NULL NUMBER(2)

DNAME VARCHAR2(14)

LOC VARCHAR2(13)




هل فهمت شيء ؟؟

يستعرض هنا اسماء الحقول NAME في الجدول DEPT


وهل هذا الحقل من الممكن ان يكون فارغا ام لا NULL?

ويستعرض ايضا نوعه TYPE , هل رقم هل نص , وكم يستوعب !!

لاحظ انه في الحقل DEPTNO يقول انه ليس من الممكن ان يكون فارغا (NOT NULL)


هل فهمت ؟

كيف اعرف ما اذا كان الحقل الفلاني مفتاح اساسي ام اجنبي ؟؟؟؟؟؟؟ هذا ما ستعرفه في الدرس القادم , ترقب


هذا كل شيء ,’,’,’,’


ماذا تنتظر ؟؟؟ هيا جرب وانظر الى الجدول EMP وانظر بنائه وتركيبه .





الامر CREATE TABLE:




مثلا اريد ان أنشئ الجدول التالي :

اسم الجدول : DEP


حقول الجدول :


DNO NUMBER(1)

DNAME VARCHAR2(10)

LOCATION VARCHAR2(12)




طبعا انا انتقيت الحد الاقصى لاسم الاقسام 10 حروف ..

وانتقيت الحد الاقصى للموقع .. وهو 11 حرف ..

وطبعا رقم القسم جعلته رقم .... أي يستوعب 1 أو 2 أو ...... 9 فقط .

بالله عليك هل تعتقد ان هذه الارقام اتت عبطا ؟؟؟

طبعا بالمنطق فكر ... ما هو الاسم الاطول الذي من الممكن ان يكون في هذا الحقل ؟

يعني مثلا رقم القسم ... لو جعلته ثلاثة ارقام , هل ينفع ؟؟ طبعا ينفع , ولكن لماذا اجعله ثلاث ارقام (ثلاث ارقام أي كحد اقصى 999) وانا اعرف انه لا يوجد لدي الا بضع اقسام يمكن اربع او ستة اقسام ... واذا كثرت تسعة اقسام كحد اقصى ؟؟

لماذا التهم الذاكرة وابطيء من عمل النظام ؟؟ لا تستغرب !! تخيل اننا نلعب في نظام ضخم جدا , وبه مليارات السجلات , وانت تأتي يا باش مهندس , وتضيف خانة رقم او خانتين على الفاضي بدون أي تفكير منطقي ؟؟؟

مالذي تتوقعه ان يحدث ؟؟

انتبه لهذه المسألة .

الان نريد ان نعمل الجدول السابق ... اليك الامر :





create table dep (

dno number(1),

dname varchar2(10),

location varchar2(11) );






والنتيجة :





Table created.






كأنه يقول "اعمل جدول dep وبه الاعمدة التالية ......."

صعب ؟؟ جدا معقد !!

هيا انظر الان الى تركيبته وبناءه عبر الامر desc , واستمتع بمشاهدة اول جدول تعمله ^^ .

عظيم جدا ....

الان .... انتبه جيدا ... الجزئية التالية صعبة قليلا ...

الان ... نريد ان نعمل جدول يدعى بـ EP مثلا .....

اريده مثل الـ emp .... في بعض الحقول .. وفي جميع السجلات ...... ماذا اعمل ؟؟

اريد ان انسخ حقول وسجلات الجدول emp في جدول جديد يدعى بـ EP مثلا ,

لماذا ؟؟ لا تسألني لماذا ..

كل ما اريده هو ان اعمل نسخة احتياطية سرية لجدول الـ emp في جدول يدعى EP , ماذا اعمل ؟؟

هل نستطيع فعل ذلك ؟؟ هل تتخيل معي الوضع ؟؟ هل من الممكن ان انسخ جدول كامل بكل مافيه .. من سجلات واعمدة في جدول اخر في امر واحد فقط ؟؟؟ الان نرى ذلك .

The Coder
15-01-2006, 10:31 PM
اليك الأمر .... كأننا نستخدم الاستفسار الفرعي .. هل تذكره ؟؟








create table ep

as

select * from emp ;




يالله .... الان اكتب جملة الاستعلام التالية .. وانظر مالذي حدث !!





select * from ep;




سوف تشاهد نفس ما تشاهده في الجدول emp


ياسلام ... والله تقنية رائعة ..

انظر الاستفسار الفرعي (select * from emp) كأنه لا يقول اعرض !! بل يقول ضع النتيجة في الجدول الجديد !!

والله عظيمة هذه الاستفسارات الفرعية ..... وقوية الطريقة هذه ....

اولا عمل جدول ..

ثم عمل الحقول .. أوتوماتيكيا ...

ثم وضع السجلات ... أيضا أوتوماتيكيا !!

يعني تخيل لو قلت لك انقل كل معلومات الجدول emp يدويا ... كم تأخذ ؟؟ هذا وهي 14 سجل تقريبا .

متى نستخدم هذه الطريقة ؟ أو لماذا نستخدمها ؟؟

اذا كنا نريد ان نعمل نسخة احتياطية لجدول ما !!


اذا كنا نريد ان نعمل جدول مبسط من بعض الحقول ... مثلا نريد ان نعمل جدول يشبه لجدول الموظفين ولكن اريد ان تكون حقوله ename و empno فقط على سبيل المثال





اريد الان ان اعمل جدول .... ولكن به حقلين .. ename و empno الموجودين في جدول الـ emp


صراحة .. اريد ان اسميهما هذان الاسمان eno بدلا من empno , و nameبدلا من ename


لاحظ .. انتبه ... توقف !! ....

اني ارغب في السجلات جميعها ولكن اريد وضع هذان الحقلان فقط .....

نفترض ان اسم الجدول .... مممممم .... وليكن emp_2







create table emp_2 (eno , name)

as

select empno,ename from emp ;







انظر كيف اخترنا اسماء الاعمدة في جدولنا الجديد ... صحيح نفس قيم الجدول emp


صحيح نفس السجلات .. ولكن اسماء اخترناها من رؤوسنا !! ياسلام على المرونة ...

لاحظ انني وضعت eno اولا ثم name


وفي الاستفسار الفرعي وضعت empno اولا ثم ename


وكانني اقول .. الاول مع الاول .. والثاني مع الثاني .. وهكذا ... يعني طابق الترتيب .. مهم الترتيب !!





الان اليك التحدي الثالث


اريد ان اعمل جدول يسمى بـ annual_emp_30


وبه الحقول التالية


Eno

Ename

Sal

Annual_sal

The_date




الـ Eno هو نفس الحقل الذي يدعى بـ empno في جدول الموظفين

الـ annual_sal هو عبارة عن sal*12


الـ the_date هو نفسه الـ hiredate في جدول الـ emp


الجدول به نفس سجلات جدول الموظفين ولكن ليس كل السجلات !! بل فقط سجلات موظفي القسم 30 .....

ماهو السؤال ؟؟؟ أعطيني يا نظر عيني الامر اللازم لعمل هذا الجدول ولكن بطريقتين مختلفتين !! انا ذكرت طريقة واحدة .. وتوجد طريقة اخرى قد درسناها منذ زمن !! ماهي ؟





الامر ALTER TABLE :


ارتكبت حماقة !!

لم ارغب في الجدول dep كما كان في السابق ..

لقد واجهتني عقبة !!

لقد واجهت اسم قسم يمتد الى 20 حرف !!

وانا وضعت 10 حروف كحد اقصى !!

حماقة اخرى عملتها !!

لا يرغب المدير في الحقل location اريد حذفه ... مالعمل

حماقة ثالثة !!

نسيت حقل قد طلب مني .... وهو :


Dep_code varchar2(20)


وهو كود خاص للقسم ... له اغراض امنية لا اعرف ما بداخله .


نسيت ان اضيفه !!

مالعمل ؟؟ من المنقذ ؟؟ من يستطيع عمل كل ذلك ؟؟

دعنا الان نعدل الحقل dname ونجعله يستوعب 20 حرف .





alter table dep

modify (dname varchar2(20) );




دعنا الان نحذف الحقل location





alter table dep

drop column location ;




الان سوف نضيف الحقل الجديد .....





alter table dep

add(dep_code varchar2(20));




هل شاهدت الحذف , التعديل , الاضافة ؟؟

سهلة جدا .... كلها تندرج تحت الامر ALTER TABLE .... سوف اشرحها ببعض التفصيل بعد قليل ....

الان لدينا جدول dep ... واريد ان اضيف فيه بعض القيم ....

أي قيم ولتكن مايلي :





insert into dep values (1,'any_name','10150115');




مارأيك ان نستعرضه ؟





select * from dep ;










DNO DNAME DEP_CODE

--- -------------------- ---------

1 any_name 10150115




شكله جميل .... هل ترى الحقل dep_code ؟؟ من الافضل ان يكون رقم ... مارأيك ؟

هل نستطيع تعديله ؟ طبعا !!





alter table dep

modify (dep_code number) ;




(لاحظ ان number لم نحدده بحد اقصى ...)والنتيجة كانت .....





ORA-01439: column to be modified must be empty to change datatype




يقول لي ... يجب ان يكون الحقل لايوجد به بيانات ...

الدالة تريد ان تحول من نص الى رقم .... ولكن يوجد بيانات .....

فهي خائفة ان تحول ... ويكون هنالك بيانات نصية فيها ABC وحروف اخرى .....

ولما تحوله الى رقم ... تتفاجئ بهذه القيم ...

فاذا كنت تريد ان تحول من نص الى رقم ... او تاريخ الى نص ........ الخ

فيجب ان يكون الحقل فارغ !!

الان انا مصر على ان يكون هذا الحقل عدد ... ماذا اعمل ؟؟

اريد ان اجعل الحقل فارغ ... بدون ان المس البيانات الاخرى في الحقول الاخرى كيف ؟؟؟

هل تعرف ؟؟ فكر .......

بسيطة .... اليك الامر !!







update dep set dep_code =null;




فقط ..... هذا كل شيء ....

صعبة ؟؟؟ مستحيلة ؟؟ فكر بمثل هذه الطرق .....

الان كل القيم بهذا الحقل ... فااااارغة ... اما البيانات الاخرى لم نمسسها بسوء .

الان نغير نوع الحقل ..... وقلوبنا مطمئنة ...... ولم يدمر طموحنا شيء :





alter table dep

modify (dep_code number) ;




الان لو كان عندنا أي حقل من نوع varchar2 واردنا تحويله الى char هل يلزم ان نفرغ بيانات الحقل ؟؟

لا .... لا يحتاج ذلك لانه من نص الى نص .. فلا داعي لافراغ البيانات .

The Coder
15-01-2006, 10:36 PM
طيب ... عرفنا ان الـ dname هو نص حده 20 حرف ..

واضفت النص التالي : any_name


صحيح ؟

كم حرف هذا النص ... ثماني حروف ...

وهو اكبر عدد موجود في هذا الحقل .. اكرر اكبر حقل موجود !!

واردنا ان نعدل ونقلل الحقل dname الى 10 حروف .. هل يجوز ؟؟

طبعا يجوز .. لان اكبر عدد حروف موجود في الحقل هو ثمانية ....

اردنا ان نقلل الحقل dname الى 5 حروف .. هل نستطيع ؟؟

لا ... لا نستطيع ... سوف تعرض لنا الرسالة التالية :


ORA-01440: column to be modified must be empty to decrease precision or scale


أي ان هنالك بيانات في الحقل .. حروفها اكثر من 5 حروف !!

لذا لا يجوز ان تقلل من حجم الحقل .. والا فسوف تفقد البيانات !!

ياسلام ... هذه البرمجة على الاصول .

انا لم اكتفي بعد .. اريد ان احذف جميع الحقول ... اريد ان اخرب الجدول ...








alter table dep

drop column dep_code;








Table altered.








alter table dep

drop column dname;








Table altered.








alter table dep

drop column dno;








ORA-12983: cannot drop all columns in a table




اوبس ... لم استطع حذف كل الاعمدة ؟؟

ممممم يظهر انه يجب ان يكون عمود واحد على الأقل في الجدول ... انتبه لهذه النقطة .

كما شاهدنا ان الامر ALTER TABLE يستطيع عمل الثلاث عمليات (إضافة , حذف , تعديل )

وهو متخصص في الحقول (الاعمدة) وتركيب الجدول كما شاهدنا .....


بخلاف الأوامر التي في DML والتي تخصصت في السجلات والبيانات التي فيها .


هنالك نقطة... لا يمكنك التراجع عن الحذف او الإضافة او التعديل في لغة الـ DDL!!


الان سوف تدخل في تسمية الجداول ....











الامر RENAME TABLE :


اسم dep لا يعجبني ...... اريد تغييره الى depart!!


... اليك الامر





rename dep to depart;




يا الله !

صعب جدا هذا الامر !

معقد لدرجة انني سوف اتركه الان وانتقل الى الامر التالي .





الامر DROP TABLE :


اريد قتل الجدول dep ... اااقصد depart .


لا اريده ... اريد امحاء كل ما فيه ...

كيف ؟ يقفز احدكم ويقول ... بسيطة , نعمل الامر التالي :
















delete depart;




وينتهي كل شيء !!

اقول تعال يا سيدي , انت حذفت السجلات , ولكن مازال الجدول موجود , والدليل هو :





select * from depart;




سوف يخبرك انه لا يوجد سجلات به ....





no rows selected




أي انه مازال موجود !!

أي انه لم يتم حذفه نهائيا !!

اريد هذه الرسالة بدلا من السابقة :





ORA-00942: table or view does not exist




ينفي تماما انه لا يوجد جدول !!

اليك الامر .... والذي يعد اقوى وابشع وافضع القتلة !!

والذي اخطر من امر delete و update


والذي لا رجعة في قتلته !!

انه drop table


سوف يقتل الجدول ... ويقتل البيانات عن بكرة ابيها !! حتى لو كانت مليارات البيانات !!

سوف يمحو جميع الروابط المرتبطة بالجدول ... سوف و سوف و سوف .....

انتبه جيدا يا فتى .. انت تلعب بمستقبل أمم !! انظر الى تركيبته البسيطة جدا جدا جدا ....










drop table depart ;




سوف يمحوه عن ارض الواقع وبكل هدوء ..... الى اللقاء يا depart ... فلن نراك ثانية .





Table dropped.




(هيا اذهب وامسح جميع الجداول التي عملناها في هذا الدرس فلن نحتاجها !! .... لا تمسح emp والجداول المهمة الأخرى !!)


الامر TRUNCATE TABLE :


هذا الامر نفس الامر الموجود في اللغة DML ولكن يختلف باختلافين ..

لا رجعة فيه ....

وانه يحرر سعة التخزين !! ....

نعرف انه لا رجعة فيه لانه من اوامر DDL , ولكن غير موضح ما معنى انه يحرر سعة التخزين !!

لذا فسوف اسأل عنها وما معناها تماما !! فانظرني واعذرني .





truncate table e;




وسوف تذهب جميع السجلات في الباي باي مع بقاء الجدول .

لايوجد هنا شرط ولا هم يحزنون .. فقط حذف كل السجلات .




الامر COMMENT


("")انتبه للتهجئة !! ليست مثل commit


انها comment أي تعليق ...

الم تشاهد اذا قال احدهم لا تعليق بالانجليزي ؟

طبعا يقول NO COMMENT


تعرف ... انت الان ماشاء الله عليك حافظ جداولك جدول جدول ...

وعارف الحقول كلها حقل حقل ...

وكما تعرف ان الحقول والجداول أسمائها خلفة !!

خلفة أي شكلها عبيط !!

تأتي وتنظر الى emp ..... بالله عليك هل هذه اصلا كلمة في قاموس الانجليزية ؟؟

ويأتي الاخر بعمود empno .... لو قلتها لاحد الأمريكيين على سبيل المثال ... لا يعرف عما تتحدث ...

بالمختصر المفيد ...بعد ستين سنة ... تأتي المخابرات الفيدرالية تطالبك ببعض المعلومات السرية التي عملتها في عام 2006 ....

وتأتي انت وتعرض emp وتعرض sal ..... للاسف

بعد ستين سنة سوف تعرف كل شيء ... ولا يتبقى عليك الا تذكرها اصلا !!

يعني سوف تنسى .... صدقني سوف تنسى السنة القادمة اذا ربي أحيانا معظم الحقول والجداول .. فما بالك بعد ستين سنة ؟؟؟!!!

مالحل ... مالعمل ....

الحل هو COMMENT تعليق .... ملاحظات ... هذه ما سوف تتذكره ....

الاوراكل عملت لك اربع جداول محترمة للتعاليق !!

انت اضف التعليق الذي تريده , واستعرضه من تلك الجداول الأربع .


الان اريد ان اكتب عن الجدول emp معلومة ...

أي انه جدول خاص بمعلومات الموظفين ..... هيا لنكتب ذلك ...








COMMENT ON TABLE EMP

IS 'THE_INFORMATION OF EMPLOYEES';




هل شاهدت النص !!! .... هو إضافة تعليق لجدول الموظفين ..

الان نضيف لأحد الاعمدة ... وانت اضف للاعمدة الباقية .... اوكيه !!








COMMENT ON COLUMN EMP.EMPNO

IS

'THE NUMBER OF EMPLOYEES ... IT IS PRIMARY KEY ';




هنا شيء جديد !!

لماذا ذكرنا اسم الجدول هنا ؟

كأنه يقول ان العمود empno الخاص بالجدول emp , هل فهمت !!

لو مثلا عندنا جدول يدعى بـ emp_2 وبه حقل يدعى empno , بالله عليك كيف يفرق الأوراكل بينهما !!؟؟

انظر كيف التكنيك , اريد الحقل empno الذي في جدول emp_2 اكتبها هكذا :


Emp_2.empno


اريد الحقل empno الذي في جدول emp اكتبها هكذا :


Emp.empno


هذا التكنيك هو الذي سوف نعتمده فيما بعد , فافهمها الان .

انتهى التعليق ...... وانتهينا من ddl


اوه اسف نسيت الجداول الاربعة !!

طبعا اريد ان اتحدث قليلا عن المستخدمين , فنحن الان ندخل بمستخدم يدعى scott ,


هذا المستخدم لديه جداول خاصة به هو لوحده , ولا احد يراها غيره والمدير او من له صلاحيات اكبر .

اذا كان هنالك مستخدم اخر اسمه مثلا abc ولديه هو الاخر جداول , هل استطيع ان اراها واتعامل معها ؟

بالطبع اذا كانت لدي صلاحية اعلى .

الان كل ما اريده منك معرفة انه يوجد جداول لكل مستخدم خاصة به .

نرجع لموضوعنا وهو الجداول الاربعة , وهي جداول خاصة بالتعاليق .

The Coder
15-01-2006, 10:47 PM
user_col_comments وهو جدول به تعاليق comments الاعمدة , والخاصة بالمستخدم الحالي


all_col_comments وهو جدول به تعاليق الاعمدة والخاصة بالمستخدمين اجمعهم


user_tab_comments وهو جدول به تعاليق الجداول والخاصة بالمستخدم الحالي


all_tab_comments وهو جدول به تعاليق الجداول والخاصة بالمستخدمين اجمعهم





يعني ايش المستخدم الحالي ؟

يعني انت الان تدخل بمسمى Scott , و اسكوت هذا هل هو طيارة ؟ صاروخ ؟؟

بل مستخدم . انت دخلت بهذا المستخدم , اذن المستخدم الحالي الذي انت عليه هو Scott


هيا لننظر الى تعاليق جداول الرجل الطيب Scott , ولكن اولا دعنا نرى بناء الجداول الاربعة .












desc user_col_comments;








Name Null? Type

----------------------------------- -------- ---------------

TABLE_NAME NOT NULL VARCHAR2(30)

COLUMN_NAME NOT NULL VARCHAR2(30)

COMMENTS VARCHAR2(4000)








desc all_col_comments;








Name Null? Type

--------------------------- -------- --------------

OWNER NOT NULL VARCHAR2(30)

TABLE_NAME NOT NULL VARCHAR2(30)

COLUMN_NAME NOT NULL VARCHAR2(30)

COMMENTS VARCHAR2(4000)








desc user_tab_comments;








Name Null? Type

---------------------------- -------- --------------

TABLE_NAME NOT NULL VARCHAR2(30)

TABLE_TYPE VARCHAR2(11)

COMMENTS VARCHAR2(4000)








desc all_tab_comments;








Name Null? Type

---------------------------- --------- --------------

OWNER NOT NULL VARCHAR2(30)

TABLE_NAME NOT NULL VARCHAR2(30)

TABLE_TYPE VARCHAR2(11)

COMMENTS VARCHAR2(4000)









الان بامكانك ان ترى جميع التعاليق الخاصة بالمستخدمين جميعهم , والتي على الجداول ...

ولكن لا تنسى انها سوف تكون ضخمة !!

لذا يفضل ان تكتب اولا :





set linesize 10000;




والان تعاليق المستخدمين على جداولهم (اعتقد ان لدى اسكوت الصلاحية لرؤيتها )





select * from all_tab_comments ;




النتيجة ضخمة !! طلعت عندي اكثر من 1600 سجل

لا لا نريد فقط المستخدم اسكوت ... كيف ؟ لديك طريقين .....

الاول : من جدول تعاليق الجداول لكل المستخدمين ....





select * from all_tab_comments

where owner='SCOTT';






الثاني وهو الاسهل طبعا :من جدول تعاليق الجداول للمستخدم الحالي (اسكوت في مثالنا)





select * from user_tab_comments;






الان نرى تعاليق المستخدمين على اعمدة (حقول ) جداولهم :





select * from all_col_comments




النتيجة جدا ضخمة ...

لا لا نريد فقط تعاليق المستخدم اسكوت على الاعمدة .. كيف ؟لديك طريقتين ...

الاولى :من جدول تعاليق الاعمدة لكل المستخدمين





select * from all_col_comments

where owner='SCOTT';






الثانية وهي الاسهل طبعا :من جدول تعاليق الاعمدة للمستخدم الحالي (اسكوت في مثالنا )





select * from user_col_comments;






اعطيك تحدي بسيط !!

وهو التحدي الرابع ,


اريد ان تعمل تعليق على أي جدول , واي عمود به ....

ثم تستعرض تعليق الجدول فقط , وليس كل الجداول ,

ثم تستعرض تعليق العمود فقط , وليس كل الاعمدة !!





انتهت رحلتنا في كوكب DDL


اريدك ان تعرف بعض المعلومات التي ارى انه من المهم ان تعرف عنها وهي ....

هنالك نوعين من الجداول !!

جداول المستخدم user tables


وجداول اخرى تسمى بـ Data Dictionary


جداول المستخدم نعرفها وهي مثل emp,dept…… أي الجداول التي ينشئها المستخدم ,

والجداول الاخرى من انشأها ؟ ليس المستخدم , بل الاوراكل نفسه !!

لماذا هذه الجداول الاخرى ؟ لكي يخزن بها بعض المعلومات المهمة للبرنامج نفسه وفي نفس الوقت ليست مهمة لنا كثيرا .

على ماذا تحتوي ؟ على معلومات عن قواعد البيانات , بعض المعلومات التي لا اعلم كثيرا منها ولكن ... لنستعرض هذه الجداول وليكن ما يكن :





set linesize 10000;




هذا الامر لكي يجعل السطر يتحمل 10000 حرف ... لذا فأول ما تشغل البرنامج اكتبه لكي تعرض الجداول بشكل سلس وواضح .... وخاصة اذا كانت جداول كبيرة !!

الان اريدك ان تعرف ثلاث جداول ... وهي


User_tables


وهو جدول به معلومات عن جداول المستخدم .... يعني اول ما تنشيء جدول .. تأتي بعض المعلومات التي يريدها البرنامج في هذا الجدول .... وانا شخصيا فهمت بعض هذه المعلومات ..

الذي فهمتها هي : اسم الجدول , هل هو متاح للمشاهدة ام لا , عدد السجلات الموجودة به ,معدل طول السجل الواحد يعني كم حرف وعدد ووو .... ,اخر وقت عد تم الدخول عليه ,واخرى لا اعلمها .

جرب واكتب الامر التالي :








select * from user_tables;




سوف تعرض لك معلومات كثيرة عن جداول موجودة لديك تعلمها واخرى لا تعلمها , طبعا لا يمكننا المس بهذا الجدول ولا بغيره من جداول النظام .

مارأيك لو ترى اسماء الجداول بواسطة الاستعلام التالي :





select table_name from user_tables;




النتيجة التي ظهرت عندي :





TABLE_NAME

------------------------------

BIN$zh6K7mL3TQSEjFVbw8huPA==$0

BIN$CdOCgSM0RVe9oZZa3a7yYw==$0

BIN$0HH1em/pSYGnFZh44HJRbw==$0

BIN$osPd+65HQRWuHRThb+5mrg==$0

BIN$8E2pLO9KS/2S+IX45TNq5A==$0

EMP_2

ANNUAL_EMP_30

EP

BIN$6BmCVHt5QJ+2kgFtGw15dw==$0

BIN$u1ury6+3TR2Z4hKShyoYdg==$0

E

BIN$2td3bfKwR/+G9k4rFB72QQ==$0

BIN$1HvD1IMCQhOnrSP7pNbAQg==$0

BIN$orKQ6c4BQOCBXgSBC1dgHQ==$0

BIN$aVeWAgZdTeKcyOVUJ9D9YA==$0

A

SALGRADE

BONUS

EMP

DEPT




يظهر ان بعض الجداول ..... لا اعرف كيف اتت ولكن ..... لا يهم .

الجدول الثاني :user_objects


وهو جدول شبيه بالسابق ..

اريد ان تعرف شيء الان , وهو object اوبجيكت .....

وهو أي شيء موجود على الـقرص الثابت hard disk يسمى بـ object , نخص في كلامنا هذا .. الملفات !!

الجدول قلنا منذ زمن بعيد انها مجرد ملف , لذا فتوجد بعض الملفات الاخرى غير الجداول سوف تعرف بعض منها فيما بعد .

هذا الجدول (اقصد به user_objects) يعرض معلومات كل الملفات او الاوجكت الموجودة لديك والتي تخص اوراكل طبعا .

بعض المعلومات التي فهمتها انا هي :

اسم الاوبجكت,نوع الابجكت هل جدول ام شيء اخر (ستعرفونه فيما بعد) ,تاريخ انشاء الاوبجيكت (معلومة مهمة للتجسس) ,اخر عملية DDL اجريت عليه (معلومة اخرى مهمة ) , هل متاح و لنا صلاحية بالتعامل معه ام لا .

The Coder
15-01-2006, 11:09 PM
الان اكتب الامر التالي :





select * from user_objects ;




لكي ترى كل ما فيه , وترى مالديك من مصائب تعلمها و اخرى لا تعلمها .

الان اريد ان استعرض تاريخ إنشاء جدولنا الخاص بالموظفين ..

انا شخصيا نفسي منذ زمن اعرف متى انشيء .... عبر هذا الاستعلام .





select created from user_objects

where object_name ='EMP';






سوف تعرض لك تاريخ إنشائه .. اذا أردت المعلومات الاخرى فما عليك الا كتابة :





select * from user_objects

where object_name ='EMP';






الجدول الثالث وهو جدول user_catalog


به معلومات طفيفة عن الجداول الموجودة لديك .... فقط اسم ونوع الجدول , لا اعرف ما قصده بنوع الجدول ولكن لايهم .. المهم انه والله اعلم ان هذا الجدول يعرض ما انشأته انت وفقط انت ....

اما جدول user_tables فهو لما تمتلكه من جداول ...سواء انت انشأته او انشأه غيرك .





بامكانك ان تكتب احد الاستعلامين :








select * from user_catalog ;




او اختصارا ....





select * from cat;




والسلام ختام .





سوف نتكلم في الدرس القادم عن الصلاحيات وما هي الصلاحيات ولماذا الصلاحيات وكيف نتعامل مع الصلاحيات

وربما عن القيود وما هي القيود ولماذا القيود وكيف نتعامل مع القيود .


ولا يبقى علينا الان الا التذكير والتلخيص لأوامر الـDDL والـ DML


الكلمات الحمراء في الصور ... هي ما يجب كتابته كما هو بدون تعديل او نقصان .

الكلمات الزرقاء في الصور .. هي ما يجوز لك كتابته او حذفه .. لا فرق فهي زيادة لا غير .

الصورة 1002 تلخيص للـ DML ولغة التحكم بالعمليات :


http://img9.picsplace.to/img9/6/1002.jpg





الصورة 1003 تلخيص للـ DDL :(الصورة كبيرة نسبيا)


http://img8.picsplace.to/img8/6/1003.jpg

The Coder
15-01-2006, 11:15 PM
اانتهى الدرس .. وكلي امل بان تنتفعو به
وان تتمتعو بالدرس ...
....
التحديات بين السطور ....
ابحثو عنها ,’,’,’,’,’,’,’
والى لقاء اخر في الدرس القادم ....

The Coder
20-01-2006, 04:34 AM
السلام عليكم
ظروف المت بي ..
سوف اتأخر اسبوع من تاريخه
اسف اسف اسف
..
سوف نسرع ان شاء الله ....
بعد اكثر من اسبوع,,,,
فاعذروني يا شباب

king.romance
22-01-2006, 08:22 PM
التميز للمتميزين دائما ارجو من الله ان يوفقق ومن اهل المنتدى وبالنيابة عنهم اشكرك على الموضوع الرائعوالجميل وادعوا الله ان يوفقق مرة اخرى

ســــــــــــلام

king.romance
22-01-2006, 08:25 PM
التميز للمتميزين دائما ارجو من الله ان يوفقق ومن اهل المنتدى وبالنيابة عنهم اشكرك على الموضوع الرائعوالجميل وادعوا الله ان يوفقق مرة اخرى

ســــــــــــلام
http://proxy.guardster.com/cgi-bin/nph-proxy.cgi/111100A/687474702f7777772e73686b6f6d616b6f2e636f6d2f41726162696325323073686b6f6d616b6f2f73686b6f6d616b6f2532 30617261626963253230776974682532306672616d652f50616e6f72616d612f626967253230706963747572657325323061 6e642532306172746963616c732f70616c6d2532307069632e676966 (http://www.grank.com/in.php?id=elsa7er3)

king.romance
22-01-2006, 09:02 PM
ياريت شكل الدرس يتعدل اكثرمن كدة
علشان يحث الناس انهم يقراءوة
وشكرا على المعلومات:أفكر: :أفكر: :أفكر:

http://www.webmistris.us/dancerssphere_webmistris2.gif

The Coder
27-01-2006, 06:09 AM
ياريت شكل الدرس يتعدل اكثرمن كدة

علشان يحث الناس انهم يقراءوة
وشكرا على المعلومات:أفكر: :أفكر: :أفكر:




http://www.webmistris.us/dancerssphere_webmistris2.gif

السلام عليكم ,,
شكرا لك اخي ....
مارأيك ؟؟ تريد دروس فلاش او فيديو ؟
لو لدي وقت طويل , ولو لدي خدمة نت سريعة , ولو لدى القارئين نت سريع ,,
لعملت دروس صوت وصورة وفلاش ,,,,
بس ...العين بصيرة , واليد قصيرة يا صاحبي ^^
شكرا لك ثانية

هانى الفقى
30-01-2006, 01:17 AM
ياجماعه والله الشخص الى اسمه
InternetMaster

ملوش حل وشرحه لمفاهيم قواعد البيانات فى الجوان وكان الأستاذ جافا ادانا اللينك
عموما هو فى موقعarabteam2000 فى قواعد البيانات بأكسس وليست موجوده فى قواعد البيانات لأوركل لأنى دخت لغايه ما لقتها وحبيت افيد اللى عايز يستفيد.
على فكره انا لسه بقرأ من يومين اتنين بس وكنت عايز أقل حاجه انى ان شاء الله هخلص خلال يومين الشرح بتاع جافا وانترنت مستر لانى عندى حماس مش ذيكم متكاسلين وان شاء الله هبقى أحسن منكم لانى بذاكر باخلاص وهحل الواجب من اول درس الى اخر درس وابعته للاستاذ جافا وربنا يسهلى الحال ويسهلكم جميعا يارب

The Coder
30-01-2006, 10:52 AM
ياجماعه والله الشخص الى اسمه
InternetMaster

ملوش حل وشرحه لمفاهيم قواعد البيانات فى الجوان وكان الأستاذ جافا ادانا اللينك
عموما هو فى موقعarabteam2000 فى قواعد البيانات بأكسس وليست موجوده فى قواعد البيانات لأوركل لأنى دخت لغايه ما لقتها وحبيت افيد اللى عايز يستفيد.
على فكره انا لسه بقرأ من يومين اتنين بس وكنت عايز أقل حاجه انى ان شاء الله هخلص خلال يومين الشرح بتاع جافا وانترنت مستر لانى عندى حماس مش ذيكم متكاسلين وان شاء الله هبقى أحسن منكم لانى بذاكر باخلاص وهحل الواجب من اول درس الى اخر درس وابعته للاستاذ جافا وربنا يسهلى الحال ويسهلكم جميعا يارب

اهلا بك يا فقي .. ^^
يعجبني حماسك .. والى الامام ^^
والدرس الخامس ... كله للاستاذ الكبير ... انترنت ماستر ..
والذي اختفى بالمرة .. ولا اعرف اين ارضه الان ...
المهم ... ضع حلول واجباتك في موضوع استفسارات اوراكل ..
وضع ملاحظاتك واسألتك هناك ^^
يالله شد حيلك ^^ ... وادعيلي

The Coder
01-02-2006, 06:06 AM
بسم الله الرحمن الرحيم

الدرس الحادي عشر


اسم الدرس : جملة الاستعلام select والدوال


نوع الدرس : تطبيقي


صعوبة الدرس : **** من *****


اهميــة الدرس : ****** من ***** (Over)


درجة احتراف لغةSQL المتوقعة بعد هذا الدرس : **** من ***** (متوسط متقدم )


الوقت المتوقع منك لفهم الدرس : ثماني ساعات .


المتوقع منك في هذا الدرس :


- معرفة الشروط والقيود .

- معرفة اجزاء جملة select .


- التعامل مع دوال المتعددة الصفوف وحل مشاكلها .





هيا لنؤركل ^^


السلام عليكم

وجهت بعض المشاكل المتعلقة ببرنامج SQL PLUS , تجدني اكتب جملة ما , وكلي ثقة انها صحيحة مئة بالمئة , واذا بالبرنامج يعطيني خطأ !!

اذا واجهت هذه المشكلة , اعد كتابة الجملة مرة ثانية يدويا وسوف تحل مشكلتك , اعيد واكرر !! ... اذا واجهت المشكلة ... اعد كتابتها يدويا , وما بقي عليك الا معرفة ان هذه المشكلة هي احد أسباب تأخر الدرس !!


,,,


الان ....


الـ Constraints او ما تسمى بالقيود , مجرد شروط نضعها على أعمدة الجداول.

شروط نريدها في عمود ما من جدول ما ...

اليك طريقتين في انشاء هذه القيود ...


الطريقة الاولى : ان تنشئ هذه القيود وقت انشاءك للجدول

الطريقة الثانية : ان تنشئ هذه القيود بعد انشاء الجدول ..


لم تفهم ؟ طيب

هل تذكر امر إنشاء الجداول ؟

ماهو الامر ؟؟

اليك مثال للتذكير :





create table abc (

abcno number ,

abcname varchar2(20) );




انشأنا جدول يدعى بـ abc


بامكاننا ان نتبع الطريقة الاولى , وهي ان ننشيء القيود وقت انشاء الجدول ....

قبل البدء ...

الان اين المفتاح الرئيسي ؟

لا احد يعرف !!

حتى الأوراكل بنفسها لا تعرف ..

بالله عليك كيف تعرف ؟

طيب اين المفتاح الاجنبي ؟ هل يوجد مفتاح اجنبي ؟ لا احد يعلم

مالحل ؟

الحل هو إضافة القيد Primary key


ما هو هذا القيد ؟

هو شرط ... ان لا تتكرر القيم ... وان لا تكون خالية !!


هل فهمت ما معنى هذا القيد .... سوف نستعرض انواع القيود ...

هنالك خمس شروط ... اااقصد خمس قيود , هي :


القيد Check :


هذا قيد يحصر العمود ويجبر العمود ان يكون بين قيمتين ....


مثلا نريد العمود deptno الموجود في جدول dept ان تكون قيمه ما بين 10 و 90 فقط ,

يعني لو اضاف احدهم صف جديد في جدول الاقسام كما يلي :





insert into dept values

( 99 , 'ANY' , 'LOCATION' );






فانه خطأ ,

الامر السابق صحيح .... جدا صحيح

ولكن انا اريد ان تكون القيم ما بين 10 و 90 !!

يعني اريد ان تظهر خطأ لكل من يجرؤ ان يضيف عدد ليس بين الـ 10 و الـ 90 .. اريد ان يرفض أوراكل هذا العمل ....

الحل هو القيد check


صاحبنا check يحدد القيم التي نريدها ,


الان نحن نتبع الطريقة الاولى ... (وقت انشاء الجدول ) ... :








create table A

( ano number check (ano between 20 and 40 ) );







عملنا جدول يدعى بـ A , ولديه عمود يدعى ano , العمود هذا يجب ان تكون قيمه بين الـ 20 والـ 40 ..

عملنا القيد check وقت انشاء الجدول ... يعني سوف ينشئ الجدول .... ثم ينشئ القيد , هذه الطريقة الاولى ..

الان تأكد بنفسك هل القيد يعمل جيدا !!





insert into A values (22) ;




سوف يضيف بدون أي مشاكل ... لان القيمة بين 20 و 40 ....

والان دعنا نرى لو اضفنا قيمة ليست بين 20 و 40





insert into A values (10) ;




سوف يعمل لك فضيحة مدوية ... ويقول "لا لا لا ... لا يجوز !! يوجد قيد .. يقيدني بان تكون القيم ما بين 20 و 40"

الان ...الطريقة الثانية بعد انشاء الجدول ....

بالله عليك ... اريد ان اضع القيد check في عمود deptno في جدول الاقسام , كيف ؟

هل احذف الجدول ... وتذهب جميع بياناته !! ... ثم اعمل الجدول مرة ثانية واعمل معه القيد ؟؟؟؟؟؟؟

طبعا غير معقول ان نعمل هذا الغباء .

اليك امر ليس بغريب عليك ... وسوف يضيف القيد الى أي جدول عملناه منذ زمن .





alter table dept

add constraint dept_deptno_ck check(deptno between 10 and 90 ) ;




واو ... ماهذا !!

الامر alter الخاص بتعديل خصائص الاعمدة وحذفها واضافتها الى جدول سبق وان عملناه سابقا !

ها هو الامر الرائع يظهر لنا ثانية كحلال لمشكلتنا ...

يقول في السطر الاول "عدل الجدول الخاص بالاقسام"

ويقول في السطر الثاني "اضف قيد بمسمى dept_deptno_ck ... وهو قيد check .. للعمود deptno على ان يكون قيم هذا العمود ما بين 10 و 90"

لاحظ المسمى dept_deptno_ck , من كتب هذا المسمى ؟؟

هل تصدق انه انا !

يعني بامكانك ان تكتب ما شئت , لكن المسمى العالمي , والطريقة العالمية المثلى هي ان تكتب اسم الجدول , ثم اسم العمود ثم نوع القيد !! كيف ؟ سوف تعرف بعد قليل .

لماذا هذا المسمى ؟؟ وما فائدته ؟ سوف تعرف بعد قليل .

هل تعرف ان تضيف هذا القيد في جداول اخرى ؟؟

بقي علي ان اخبرك ان تتنبه الى هذا القيد , لو وضعنا هذا القيد على عامود deptno , وجعلنا القيم ما بين 20 الى 90 مثلا , هل هذا صحيح ؟ بالنظر صحيح .. لكنه خطأ , لانه يوجد قيم سابقة ليست بين 20 و 90

(القسم 10) , سوف يخبرك انه من المستحيل عمل ذلك لانه يوجد قيم في الجدول منافية للشرط .


سنعود بعد قليل ^^

The Coder
01-02-2006, 06:09 AM
القيد Primary key:


هذا قيد يجعل قيم العمود المراد وضع القيد عليه .. لا تتكرر ولا تكون خالية .


الان سوف نعمل هذا القيد بالطريقة الاولى على جدول جديد ويدعى B :





create table B

( bno number primary key , bname varchar2(10) ) ;




سهلة ؟

اعتقد انها سهلة ....

عملنا جدول B وبه عمودين .. احدهما حددناه ان يكون مفتاح اساسي .... هذا كل شيء .





الان الطريقة الثانية :


... هل تذكر مثالنا السابق .. حينما عملنا الجدول A ؟

يوجد عمود واحد وهو ano , اريده مفتاح اساسي ... كيف ؟

فكر .. فكر .. فكر ...








alter table A

add constraint a_ano_pk primary key(ano);




نفس الشيء ... يوجد مسمى , ثم كلمة primary key ثم بين قوسين العمود المراد وضع القيد .







القيدUnique :


قيد يجعل قيم عمود ما , لا تتكرر . معنى unique بالعربي ... وحيد .

الان بالطريقة الاولى , نعمل جدول يدعى بـ c ولديه عمود cno , نريد هذا قيم هذا العمود لا تتكرر ....





create table c

( cno number unique , cname varchar2(10) );




بمجرد إضافة كلمة unique , وانتهى كل شيء .

بالطريقة الثانية ... ممممم هل تذكر الجدول B الذي عملناه قبل قليل ؟

يوجد عمود يسمى bname , اريده عمود ذو قيم لا تتكرر .....





alter table B

add constraint b_bname_uk unique(bname) ;




لاحظ المسمى b_bname_uk , وهو مسمى من عندي , بامكانك وضع ماشئت , وبامكانك اتباع طريقتي .

يجب ان نضع اسم العمود المراد وضع أي قيد فيه بين قوسين .








القيدNot null :


قيد يجعل قيم عمود ما , لا يمكن ان تكون خالية .


اليك الطريقة الاولى ...





create table d

( dno number not null ) ;




عملنا الجدول d , وبه عمود dno , وجعلنا قيم هذا العمود لا يمكن ان تكون خالية ... جرب وادخل قيم خالية , سوف يعطيك خطأ

اليك الطريقة الثانية ...

على جدول B , عمود bname , وضعنا به القيد الخاص بعدم التكرار ... صح ؟

الان اريد ان اضيف القيد الخاص بعدم وجود قيم خالية .... هل يجوز ان نضيف قيدين على عمود ؟؟ طبعا نعم ..

لكن يوجد مشكلة مع هذا القيد , انه لا يمكن اضافته بالامر alter و add ....


بل بالامر التالي :





alter table b

modify (bname varchar2(20) not null) ;







وهو تعديل العمود اصلا !!

أي كأنك سوف تعدل العمود وخصائصة , ثم تضع هذا القيد .


هذا هو القيد الوحيد الغريب , والبقية تستخدم add . افهم ذلك ...






.


القيد Foreign key (references):


قيد يجعل عمود ما مفتاح اجنبي , أي انه ينشيء علاقة ما بين جدولين .


انتبه الى نقطة مهمة !!

يجب ان يكون المفتاح الاساسي الذي سنجعله مفتاح اجنبي في الجدول الثاني .. مساوي كقيمة للمفتاح الاجنبي .. ومطابق لصفاته !!

الان دعنا ننشئ جدولين , اولهما يدعى بالمتهم h والاخر المدعي g







create table h

( hno number ,

hname char );




اوبس .... نسيت ان اضع القيد PRIMARY KEY ... ما رأيك ان نجرب ماذا سيحصل ؟ لنرى :








create table g

( gno number ,

ho number references h(hno) ) ;




عملنا عمود يدعى بـ ho , وهو مفتاح اجنبي .. للمفتاح الرئيسي الموجود في الجدول h


لكن اسمه هناك hno .... هل تعتقد ان وضع اسم للمفتاح الاجنبي غير اسم المفتاح الاساسي خطأ ؟؟ في الحقيقة لا ...

لا يوجد خطأ في ذلك ..

الان انظر النتيجة :








no matching unique or primary key for this column-list




خطأ !! ؟؟؟

يقول انه لايوجد مفتاح اساسي !!

اوه صحيح .. نسيت ان اضع القيد PRIMARY KEY على العمود hno ....





alter table h

add constraint h_hno_pk primary key (hno) ;




الان .... نكرر العملية ونحن مرتاحو البال .








create table g

( gno number ,

ho number references h(hno) ) ;




وسوف يربط بين الجدولين ...

سوف يخبر هذا الامر أوراكل .. بأنه يوجد علاقة وثيقة واتصال عميق بين الجدول h و g


وسوف يعيشون بسلام وأمان معا ,,,

الان بالطريقة الثانية ....تخيل لدينا جدولين اخرين ...


احدهما U والاخر يدعى T


هيا لننشئهما .....





create table u

( uno number primary key ) ;








create table t

( tno number , uno number ) ;






الان اريد العمود uno في جدول الـ t مفتاح اجنبي يشير الى المفتاح الاساسي uno الموجود في جدول u


اليك الامر ولاحظ ان uno الاولى التي بين قوسين ... هي العمود الخاص بالجدول t والثانية هي الخاصة بالجدول h







alter table t

add constraint t_uno_fk foreign key (uno) references u(uno) ;




هل رأيت المسمى ؟؟ هل رأيت foreign key ؟؟؟ هل وهل وهل ؟؟

الان عملنا الرابط الوثيق بالطريقة الثانية (الطريقة الثانية = بعد انشاء الجداول ...)

الان انتهينا من انواع القيود ...

الان ... يوجد شيئين لم اطلعك عليهما , وهو "على مستوى العمود" والاخر "على مستوى الجدول"

صراحة استغرب من هذان الشيئان ... فلا اعرف لماذا عملوها هكذا .... الان سوف اريك شيء اخر .... جدول جديد

وهو تابع للجداول التي تكلمنها عنها , والتي تسمى بـ Data Dictionary ,,, هل تذكرها ؟

جدول يعرض جميع القيود لدى جداولك , الجدول يدعى user_constraints


هيا اذهب واستعرض محتوياته ....








set linesize 10000 ;




لكي يعرض الجداول بشكل مقبول .... (كأنه يقول ... اجعل حجم السطر 10000 حرف ....)

الان اكتب جملة الاستعلام التالية ....

وهي عرض كل القيود التي على الجدول B







select * from user_constraints where table_name='B' ;











OWNER CONSTRAINT_NAME C TABLE_NAME SEARCH_CONDITION

------------- ------------------------------ - ----------------------- -----

SCOTT B_BNAME_UK U B

SCOTT SYS_C005555 C B "BNAME" IS NOT NULL

SCOTT SYS_C005549 P B





هل تذكر تلك المسميات ؟؟


B_BNAME_UK احد هذه المسميات ...

وقد عرض هنا !!

هل تشاهد المسميين SYS_C005555 و SYS_C005549 ؟ من اسماهما ؟؟

انه الأوراكل !!

هل المسميات هذه مهمة ؟ ولماذا ؟ ستعرف بعد قليل ....

هل تشاهد تلك الرموز ؟ U C P ….


هي رموز تشير الى القيود ..


P أي Primary key

C أي check أو not null

U أي unique

R أي references (وهو الخاص بـ foreign key )


العمود search_condation يعرض الشروط الخاصة بالقيد check والقيد not null


الان ...

لو عملنا جدول جديد .. وبه مفتاح اساسي ... هل نستطيع تسميته بهذا الامر :





create table XYZ

( xyzno number primary key ) ;




طبعا لا نستطيع تسميته .

انظر الى جملة الاستعلام التالية ...





select * from user_constraints where table_name='XYZ' ;




النتيجة سوف تكون ....






OWNER CONSTRAINT_NAME C TABLE_NAME SEARCH_CONDITION

---------- ------------------------- - ----------------- -----

SCOTT SYS_C005562 P XYZ





لاحظ هذه التسمية SYS_C005562 .. أوراكل سماها .

الان نريد ان نحذف القيود جميعها من جدول ما ... كيف ؟

مالعمل ؟

اريد ان احذف القيد Primary key مثلا من جدول xyz


كيف ؟

يا ترى كيف ؟؟

The Coder
01-02-2006, 06:11 AM
هل تصدق انها بتلك التسميات !!

الان لنحذف قيد المفتاح الاساسي من جدول xyz





alter table xyz

drop constraint SYS_C005562 ;




واو .... alter ,, ذلك الامر الرائع تكفل ايضا بحذف القيود عبر جملة drop constraint ثم ذكر مسمى القيد المراد حذفه .

الان اكتب جملة الاستعلام السابق ذكرها ....





select * from user_constraints where table_name='XYZ' ;




والنتيجة هي :





no rows selected




لقد نسف الامر alter بجملته drop constraint القيد الخاص بالمفتاح الأساسي !!


ولا وجود له الان . باي باي يا مفتاح يا أساسي ... لقد كنت طيب معنا .

الان لدينا مشكلة ... وهي التسميات !!

كيف نعرف التسميات ؟

هل نذهب الى الجدول user_constraints ونأخذ من هناك المسمى لكي يتم حذف القيد الذي نريده ؟

اعتقد انه حل لا بأس به ... ولكن الحلو ما يكملش .... واليك مشكلة اخرى ...


مارأيك ان نعمل جدول يدعى بـ W ولديه من الابناء .. ااقصد من الاعمدة wno و www وهما عمودين ذوي بيانات رقمية .... انا سوف اضع لهما القيد عدم التكرار .... كما يلي :







create table W

( wno number unique , www number unique ) ;




هيا لنستعرض عضلات وقيود الجدول W





select * from user_constraints where table_name='W' ;




انظر وتمتع بالنتيجة ... وحتى اشعار اخر ... اريد ان احذف القيد الخاص بـالعمود www وليس العمود wno






OWNER CONSTRAINT_NAME C TABLE_NAME SEARCH_CONDITION

----------- ------------------------- - ----------------- -----

SCOTT SYS_C005563 U W

SCOTT SYS_C005564 U W





هيا .. اخبرني أي من المسميين احذفه ؟

هل SYS_C005563 ام SYS_C005564 ؟؟

أي منهما هو الذي يمثل العمود www ؟؟؟

طبعا يجب ان تذهب الى جدول اخر ... وترى اسم العمود , واسم الجدول , ومسمى القيد ..... ثم ترجع وتأخذ المسمى ... ثم تحذف القيد ....

انا كسول جدا ... اعتبرها معضلة ... وذهاب وعودة و تعب ....

اليك الجدول ... والذي سوف يعرض اسم العمود + مسماه ..





select * from user_cons_columns ;






الان نريد حل لهذه المعضلة (لا ارى انها مشكلة .. ولكن اريد تجربة طريق اخر !! هذا كل شيء ) , نريد ان نسمي القيود عندما ننشئها !! كيف ؟


اعتقد انه يوجد حلين ... وقد تعرف احدهما !!

حل بالطريقة الاولى (تسمية و انشاء القيود وقت انشاء الجدول ) و حل بالطريقة الثانية (انشاء القيود بعد انشاء الجدول)!!

في الحقيقة ان الطريقة الثانية مررنا بها !! وعملناها !!

أي انك تعمل الجدول ... ثم تضيف القيود كما ترغب وهو حل لا بأس به . وانا اعرف انك فكرت بها اصلا .

اما الحل بالطريقة الاولى ... عرفنا اننا نستطيع انشاء القيود وقت انشاء الجدول , ولكن لم نعرف كيف نسميها !!

الان ركز فقط بالطريقة الاولى ... الطريقة الاولى يوجد بها طريقتين (بدأت الامور تتعقد اكثر !!)

على مستوى العمود و على مستوى الجدول .

الذي عملناه هو مستوى العمود ... الان ننشيء جدولين وبها قيود على مستوى الاعمدة ...

الجدول الاول وهو الخاص بجدول السيارات , والاخر هو جدول الزبائن

الزبون الواحد يستطيع ان يمتلك اكثر من سيارة

السيارة الواحدة تمتلك للزبون الواحد ...

لو بتفكر قليلا .... حتعرف فين نضع المفتاح الاجنبي !!

العلاقة واحد لمتعدد .

فكر أين نضع المفتاح الاجنبي .....

هل فكرت ؟ صحيح .... في جدول السيارات .

الان ننشئ جدول الزبائن .... وبه رقم الزبون كمفتاح أساسي ... واسمه كقيم يجب ان تكون غير خالية ...ثم عمره والذي يجب ان يكون ما بين 18 و 30 ...





create table customer (

cno number primary key ,

cname varchar2(10) not null ,

cage number check (cage between 18 and 30 ) ) ;




يا سلام ...

الان جدول السيارات ...





create table cars (

carno number primary key ,

carname varchar2(10) not null ,

carage number check (carage between 0 and 10) ,

carpanel number unique ,

cno number references customer(cno) ) ;




يا سلام ...

رقم السيارة كمفتاح أساسي , اسم السيارة كقيم لا يمكن ان تكون خالية , و عمر السيارة المتوفرة والتي تصلح للبيع وهو ما بين 0 و 10 سنين , ولوحة السيارة وهو رقم لا يتكرر ابدا , واخير رقم العميل المالك لها كمفتاح اجنبي !!

لاحظ انه مثال عبيط من رأسي !! تحليليا خطأ في خطأ ...

لكن تقنيا .. لقد جمعت كل القيود في هذين الجدولين كتلخيص !!

ارجع لهما وقت نسيانك لشيء ! فقد ينفعانك كثيرا .

مع العلم انهما بمستوى الاعمدة ....





التحدي الاول ...الان تخيل لو اردنا ان نجعل لاسم العميل قيدين !!

أي انه غير خالي , و ايضا لا يمكن ان يتكرر !! كيف ؟؟ اريدها بطريقتين ! وهو كتحدي .... لكن انتظر !

اقرأ الدرس كاملا ... ثم اجب على هذا التحدي ... لان الطريقة الاولى تعرفها والطريقة الثانية اتية في الطريق .

ولكي اكون واضحا معك .. اليك اجابة خاطئة .. لكي لا تفكر فيها بتاتا :





create table customer (

cno number primary key ,

cname varchar2(10) not null ,

cname varchar2(10) unique ,

cage number check (cage between 18 and 30 ) );




وستكون النتيجة هي .......





ORA-00957: duplicate column name




(لقد كررت اسم عمود !!)











الان اريدك ان تعرف انه لو حذفنا جدول العملاء .... فسوف يرفض اخونا الأوراكل .... اليك ما يلي :










drop table customer ;




سوف يقول لك ... ان هنالك مفتاح اجنبي في جدول اخر(جدول السيارات) .. مرتبط ارتباط وثيق مع جدول العملاء ...





ORA-02449: unique/primary keys in table referenced by foreign keys




اذن مالعمل ؟؟؟؟

حذف هذا الارتباط او حذف ذلك الجدول الاخر (جدول السيارات) الذي به المفتاح الاجنبي

الان انشأنا القيود بالطريقة الاولى .... على مستوى العمود ... وقد عرفنا ذلك ..

اليك انشاء القيود بالطريقة الاولى ايضا ولكن على مستوى الجداول ...

اريدك ان تحذف كل الجداول التي عملناها هذا الصباح .... بما فيها جدولي السيارات و العملاء (عملاء = زبائن)

اليك انشاء القيود على مستوى الجدول :





create table customer (

cno number ,

cname varchar2(10) ,

cage number ,

constraint customer_cno_pk primary key (cno) ,

constraint customer_cname_uk unique(cname) ,

constraint cusotmer_cage_ck check(cage between 0 and 10 ) ) ;







يتم فيها سرد الاعمدة بشكل طبيعي بدون قيود .. وبعد الانتهاء من الاعمدة .. يتم سرد القيود بشكلها الذي تراه ...


وهو اولا كلمة constraint ثم المسمى ....

المسمى عادة وبالطريقة المعروفة والاصلية .... اسم الجدول ثم _ ثم اسم العمود المراد وضع القيد فيه , ثم _ ثم نوع القيد ..

نوع القيد اذا كان uk فمعناه القيد unique


واذا كان pk فمعناه Primary key


واذا كان fk فمعناه foreign key


واذا كان ck فمعناه check


اما القيد not null فانه لا يمكن وضعه على مستوى الجدول !!

لا اعرف لماذا .. ولا اعرف ما هو القصد الغبي وراء منع وضع هذا القيد بالذات , ولكن .... انا لله وانا اليه لراجعون.

نرجع الى محور حديثنا ...

ولا تنسى اننا نتبع الطريقة الاولى (الطريقة الاولى = انشاء القيود وقت انشاء الجدول) وهذه الطريقة الاولى على مستوى الجدول , ولا تنسى انها حل لتسمية القيود , ليس كمثل الطريقة الاولى على مستوى العمود !!


يجب وضع اسم العمود المراد الحاق القيد الخاص به ...

فمثلا السطر الاخير :


constraint cusotmer_cage_ck check(cage between 0 and 10 )


لاحظ انه ذكر العمود cage .... بين قوسين ..

والسطر ما قبل الاخير ذكر اسم العمود بين قوسين ... وهلم جر .

الان لاحظ الجدول الثاني (اعيد واكرر .. الطريقة الاولى .. على مستوى الجدول )








create table cars (

carno number ,

carname varchar2(10) ,

carage number ,

carpanel number ,

cno number ,

constraint cars_carno_pk primary key(carno) ,

constraint cars_carage_ck check( carage between 0 and 10 ),

constraint cars_carpanel_uk unique(carpanel) ,

constraint cars_cno_fk foreign key (cno) references customer(cno) );




كل شيء واضح الان ... انتبه الى جزئية المفتاح الاجنبي !!


foreign key (cno)


الـعمود cno هو العمود التابع للجدول cars أي لسان حاله يقول "هذا مفتاح اجنبي ... للعمود cno "


واما الجملة التالية :


references customer(cno)


فكأنه يقول ... "يشير الى جدول العملاء ( عمود cno ) "


الان ... اذهب وانظر الى الجدول الخاص بعرض القيود ... سوف ترى المسميات واضحة وصريحة , ولا يوجد أي مشكلة :










select * from user_constraints where table_name='CUSTOMER';











OWNER CONSTRAINT_NAME C TABLE_NAME SEARCH_CONDITION

------------ ------------------------------ - ----------------- -----

SCOTT CUSOTMER_CAGE_CK C CUSTOMER cage between 0 and 10

SCOTT CUSTOMER_CNO_PK P CUSTOMER

SCOTT CUSTOMER_CNAME_UK U CUSTOMER





هل رأيت المسميات .. واضحة هاه ,

The Coder
01-02-2006, 06:17 AM
الان انظر الى قيود الجدول الاخر :


















select * from user_constraints where table_name='CARS';






النتيجة كانت :


















OWNER CONSTRAINT_NAME C TABLE_NAME SEARCH_CONDITION


---------- -------------------------- - ---------------- -----

SCOTT CARS_CARAGE_CK C CARS carage between 0 and 10

SCOTT CARS_CARNO_PK P CARS

SCOTT CARS_CARPANEL_UK U CARS

SCOTT CARS_CNO_FK R CARS
















للتذكير ... ما فائدة المسميات ؟ لماذا المسميات مهمة لهذه الدرجة ؟


لكي نحذف القيود بسرعة وبشكل عملي اكثر ولكي نحل معضلتنا تلك .. هل تذكرها (ارجع الى الجدول W )







هيا لنحذف القيد الخاص بالمفتاح الأساسي بجدول العملاء !!












alter table customer

drop constraint customer_cno_pk ;












والنتيجة :












ORA-02273: this unique/primary key is referenced by some foreign keys









خطأ !!


يقول انه يوجد مفتاح اجنبي يعتمد على هذا المفتاح الأساسي ... طيب ... حاضر يا سيد أوراكل ... سوف نحذف هذه العلاقة ثم نرجع ونحذف القيد Primary key أو ............ بطريقة اخرى وهي :











alter table customer

drop constraint customer_cno_pk cascade ;









إضافة كلمة cascade والذي سوف يمحي العلاقة برمتها , أي انه سوف يمحي القيد الخاص بالمفتاح الأساسي , و القيد الاخر الخاص بالمفتاح الاجنبي في الجدول الاخر .. تأكد بنفسك ... اذهب وشاهد ذلك في جدول القيود user_constraints










الان نحذف القيود جميعها من جدول السيارات ... مارأيك


(باعتبار انك لم تكتب الامر الذي يحتوي على cascade)








alter table cars

drop constraint cars_cno_fk ;










alter table cars

drop constraint cars_carage_ck ;










alter table cars

drop constraint cars_carpanel_uk ;










alter table cars

drop constraint cars_carno_pk ;










select * from user_constraints where table_name='CARS';










no rows selected






وبالمثل .. في جدول العملاء ... لو اردت ان تجرب .


لا ادري هل يوجد فرق فعلي بين "على مستوى الاعمدة" و "على مستوى الجداول" ؟

المناهج لم تتحدث فعليا عن فرق جدير بالذكر ... انما انا استنتجت الفرق الخاص بمسميات القيود .

بقي شيء واحد نسيته !! التحدي ثاني ....

وهو القيد not null كيف نحذفه ؟

باعتبار ان احد الاعمدة به قيم لا يمكن ان تكون خالية ... حاول ان تحذف هذا القيد ....
















هيا اذهب و امسح جميع الجداول التي عملناها صباح هذا اليوم ... فلا حاجة لنا بها !!


انتهينا من دوخة القيود ...
















والان لنرجع الى الوراء .... الى الماضي , ونذكر شيء قد نسيناه , الا وهو جملة الاستعلام select








توقفنا في نقطة مهمة جدا في الدوال المتعددة الصفوف ... وعرفنا ما الفرق بين المتعددة الصفوف والاحادية الصف ....


واخر مثال كان :




















select ename,sum(sal) from emp ;

















وكانت النتيجة جميلة ورائعة ....


















ORA-00937: not a single-group group function

















الان , اريد ان اعرف .... مجموع الرواتب الكلية للقسم 30 و مجموع الرواتب الكلية للقسم 20 و مجموع الرواتب الكلية للقسم 10 (الرواتب الكلية = الرواتب الأساسية + الرواتب الإضافية )


اريد ان اعرضهم لكي أقارن مثلا ...

ماذا اعمل ...

اليك حل عبيط و متعب ..... متعب كثيرا .... ويمكن يحتاج ورقة وقلم ... و آلة حاسبة ,

















select sum(sal) from emp

where deptno=30 ;








SUM(SAL+NVL(COMM,0))

--------------------

11600








elect sum(sal + nvl(comm , 0) ) from emp

here deptno =20 ;








SUM(SAL+NVL(COMM,0))

--------------------

10875








select sum(sal + nvl(comm , 0) ) from emp

where deptno =10 ;








SUM(SAL+NVL(COMM,0))

--------------------

8750






حل رائع ...


تكتب كل قسم ... على حدة ...

وترى النتائج متفرقة ...

تخيل انه 100 قسم ؟؟؟؟؟

هل تكتبها مئة مرة ؟ وتسجل البيانات مئة مرة ؟ لا لا ,, هذا غباء

الان سوف تتعلم شيء جديد ....







انظر الى الصورة اولا ... (الصورة 1101)








http://img8.picsplace.to/img8/8/1101.jpg










الصورة توضح عرض اكبر قيمة في القسم 10 , واكبر قيمة في القسم 20 واكبر قيمة في القسم 30 ....


الجدول الذي في اليسار هو جدول الموظفين ... أي عرض منه رقم القسم و الراتب ....

الجدول الذي في اليمين ... هو ما نريده !! ....

لو قلنا :











select max(sal) from emp ;









فإنه سوف يعرض لنا ...









MAX(SAL)

--------

5000






اذن نريد استخدام الدوال ذوات الصفوف المتعددة , ونريد تقسيم الناتج ...


دوال متعددة الصفوف .. نتيجتها صف واحد , ونحن نريد صف متعدد , لذا تنبهوا اولئك المبرمجين (مبرمجو أوراكل) , وعملو شيء يسمى بـ group by









جملة group by :


Group معناها بالعربي .... مجموعة , تقسيم .....

وكأن معنى هذه الجملة "تقسيم بحسب ".....







وكما شاهدنا ... نريد تقسيم ناتج الدالة ذات الصف المتعدد على حسب ماذا ؟؟ على حسب رقم القسم ...


الان انظر الى الحل ....

اريد عرض مجموع رواتب الموظفين في قسم 10 و مجموع رواتب الموظفين في قسم 20 ومجموع رواتب الموظفين في قسم 30 في جملة استعلام واحدة ,











select sum(sal) from emp

group by deptno ;









وكأنه يقول .. اعرض مجموع الرواتب ... مقسمة بحسب رقم القسم !!


انظر الى الناتج :











SUM(SAL+NVL(COMM,0))

--------------------

8750

10875

11600









يااااا سلام ... رائع

The Coder
01-02-2006, 06:19 AM
الان نطورها قليلا , ونضع الرواتب الكلية :





select sum(sal+nvl(comm,0) ) from emp

group by deptno ;








SUM(SAL+NVL(COMM,0))

--------------------

8750

10875

11600




ممممم لا تعجبني النتيجة هكذا ...

اريد ان اضيف رقم القسم بجانب النتائج ....





select deptno , sum(sal+nvl(comm,0) ) from emp

group by deptno ;




والان دعنا نرى النتيجة ... بشكلها الجميل :





DEPTNO SUM(SAL+NVL(COMM,0))

------ --------------------

10 8750

20 10875

30 11600




الان اقتنعت ...

لنجرب دالة القيمة الاعلى max للرواتب ...








select deptno , max(sal) from emp

group by deptno ;








DEPTNO MAX(SAL)

------ ----------

10 5000

20 3000

30 2850




الان ... انا لم اكتفي .. اريد تعقيد الامور !!

اريد ان اعرض اسم صاحب اكبر راتب و قسمه ... مقسما النتائج على حسب رقم القسم ..

ما رأيك في هذا الحل :





select ename,deptno,max(sal) from emp

group by deptno ;




فكر في حلي ...

هل هو صحيح ؟؟ ولماذا ؟

لماذا هو صحيح ؟ لماذا هو خاطئ ؟؟

في الحقيقة .. هو خاطئ مئة بالمئة !!

لماذا خاطئ ؟ وضعنا سابقا العمود deptno فصار الحل صحيح ... ولكن عندما اضفنا ename اصبح خاطئ !!


لماذا يا ترى ؟

اذا لم تفهم لماذا ... فسوف تضطر لقرائة عدة سطور مملة (ما بين علامتي التنصيص) ... اقرأها او لا تقرأها , الخيار لك ... سوف تستغرق قرائتها اقل من دقيقتين ونصف ...


"


انظر هذه الجملة .. للتذكير:





select deptno , max(sal) from emp

group by deptno ;







في الجملة قلنا (اعرض رقم القسم , و أعلى راتب ..... و قسم النتائج بحسب رقم القسم) .... ما معنى هذا ؟؟

معناه انه لو يوجد لدينا الأقسام 10 و 20 و 30 و 40 مثلا ...




- سوف يقسم الصفوف الى اربع مجموعات , المجموعة الاولى و بها الصفوف التي تحتوي على القسم 10

والمجموعة الثانية تخص الصفوف التي تحتوي على القسم 20 ...... الخ




- المجموعة الاولى مثلا بها 5 صفوف ... وكل من هذه الصفوف تتبع القسم 10 صح ؟

أي ان المجموعة الاولى همها واحد , لغتها واحدة , قسمها واحد , تشترك في صفة واحدة وهي القسم 10

المجموعة الثانية تشترك في صفة واحدة وهي القسم 20 ... لا احد يشترك معها في هذه الصفة

كذلك المجموعة الثالثة والرابعة .....




- مثلا المجموعة الاولى ... هل تشترك في اسم الموظف و اسم الموظفين جميعهم اسم واحد ؟؟ لا

هل تشترك في الراتب أي ان جميع الرواتب فيها راتب واحد ؟؟ طبعا لا .... الرواتب مختلفة بين كل صف وصف في المجموعة الاولى ...




- الان بعد تقسيمها الى مجموعات نعمل اهم خطوة... وهي ضم كل صفوف المجموعة الواحدة لتمثل صف واحد !! انتبه ... فهذه اهم خطوة يجب التنبه فيها , الان .... قبل ان نضم... هل توجد دالة من نوع المتعددة الصفوف لنقل مثلا نعم توجد دالة .... إنها دالة max ... أي اكبر راتب موجود في هذه المجموعة .



- سوف يختار اكبر راتب ...و ينشئ عمودين هما رقم القسم , واكبر راتب لكي يمثلان المجموعة الاولى ....

وهكذا مع المجموعات الاخرى




- اذن الخلاصة هي انه بإمكاننا ان نعرض رقم القسم لاننا وضعناه في جملة group by , ولا يمكننا ان نعرض عمود اخر كاسم الموظف ..., لذا لا تضع عمود لم يذكر في جملة group by


"


الان .... لنعقد الامور اكثر واكثر ....

الان تخيل انه لدينا الف قسم ... واريد ان اعرف اكبر مجموع رواتب كل قسم ...

أي انه بعد معرفة مجموع رواتب كل قسم ... كما شاهدنا سابقا , اريد ان اعرف اكبر مجموع !!

لو نظرنا الى مايلي :





DEPTNO SUM(SAL+NVL(COMM,0))

------ --------------------

10 8750

20 10875

30 11600




لعرفنا ان اكبر مجموع بين الثلاثة هو 11600

طيب .... تخيل انه الف قسم الان ... كيف تعرف وبسرعة ما هو اكبر مجموع ؟؟

فكر قليلا .... الجواب في رأسك وانت لا تعلم ....







اليك الحل :





select max(sum(sal+nvl(comm,0) ) ) from emp

group by deptno ;




والنتيجة ...





MAX(SUM(SAL+NVL(COMM,0)))

-------------------------

11600






كل مافعلناه .... هو مايلي ..


Max(sum(….) )


وكما نعرف ... الدوال ترجع بقيمة (تخرج قيمة)

دالة الـ sum هنا اخرجت لنا قيم .. وهي ثلاث صفوف ... (مجموع رواتب كل قسم من الأقسام الثلاثة ...)

هل عرضت لنا ثلاث صفوف ؟ لا !!

من استقبلها ؟ انها الدالة max , استقبلتها بكل سرور , واختارت القيمة الاعلى منها , ثم عرضته لنا

هل فهمت الفكرة ! اعتقد انها سهلة .

الان اليك التعقيد العالمي .....

تخيل انه يوجد لدينا جدول الطلبة .. مجرد تخيل لهذا الجدول ...به الاعمدة التالية :

رقم الطالب ... رقم الكلية .. عدد الأترام ... ومعدل الطالب .

اريدك ان تنسخ هذا الجدول كما هو .... :





create table stud(

stu_no number ,

col_no number ,

trm_no number ,

avg_po number(3,2),

constraint stud_stu_no_pk primary key(stu_no) );




Stu_no رقم الطالب .

Col_no رقم الكلية.

trm_no رقم اخر ترم درسه .

Avg_po معدل الطالب .


الان .. انسخ جميع الصفوف كما هي , ثم الصقها في البرنامج SQL PLUS* ... :






insert into stud values (10 ,1,1,3.74) ;

insert into stud values (20 ,1,1,5.00) ;

insert into stud values (30 ,1,1,4.85) ;

insert into stud values (40 ,1,2,3.12);

insert into stud values (50 ,1,2,3.66);

insert into stud values (60 ,1,2,4.02);

insert into stud values (70 ,1,2,2.00);

insert into stud values (80 ,1,2,2.88);

insert into stud values (100,2,1,4.89);

insert into stud values (110,2,1,4.00);

insert into stud values (120,2,2,1.89);

insert into stud values (130,2,3,4.61);

insert into stud values (140,2,3,4.22);

insert into stud values (150,2,3,4.57);

insert into stud values (160,2,3,4.64);

insert into stud values (170,2,3,3.01);

insert into stud values (180,2,4,4.42);

insert into stud values (190,2,4,3.64);

insert into stud values (200,2,4,4.99);

insert into stud values (210,2,4,4.50);

insert into stud values (220,3,1,3.32);

insert into stud values (230,3,1,2.23);

insert into stud values (240,3,1,3.73);

insert into stud values (250,3,2,4.77);

insert into stud values (260,3,3,2.40);

insert into stud values (270,3,3,2.93);

insert into stud values (280,3,3,3.40);

insert into stud values (290,3,3,3.66);

insert into stud values (300,3,4,2.71);

insert into stud values (310,3,4,4.17);

insert into stud values (320,3,5,4.98);

insert into stud values (330,3,5,2.53);

insert into stud values (340,3,5,4.24);







يا سلام ... الان انظر الى الجدول الجديد :








select * from stud ;

The Coder
01-02-2006, 06:21 AM
الان اريد ان اعرض عدد الطلبة الذين اخذو عدد اترام معين , في الكلية الواحدة ,


أي انه يخبرني ان هنالك ثلاث طلاب يأخذون الترم الثاني في الكلية الاولى , وهنالك طالبين يأخذون الترم الثالث في الكلية الاولى , وان هنالك طالب واحد يأخذ الترم الاول في الكلية الثانية .... وهكذا ...

اريدك ان تفكر في السوال .. لا تفكر في الاجابة ..

يجب ان تفهم السوال , لكي تعيش المشكلة والتجربة . لاحظ انه يجب استخدام الدالة count , وهي دالة متعددة الصفوف ... اذا فهمت السوال , فحاول ان تجد الاجابة .... لا اعتقد انك ستجدها طالما انني لم اخبرك .

النتيجة ستكون بهذا الشكل .....










NUMBER_OF_STUDENT COL_NO TRM_NO

----------------- ---------- ----------

3 1 1

5 1 2

2 2 1

1 2 2

5 2 3

4 2 4

3 3 1

1 3 2

4 3 3

2 3 4

3 3 5






في الصف الاول .... يقول انه يوجد ثلاث طلبة في الكلية رقم واحد يدرسون الان الترم الاول ,


وفي الصف الثاني ... يقول انه يوجد خمس طلبة في الكلية رقم واحد ايضا , يدرسون الترم الثاني .

اليك الحل ....











select count(*) number_of_student , col_no , trm_no

from stud

group by col_no , trm_no ;









جملة التقسيم group by احتوت على عمودين !!


لاحظ انني وضعت رقم الكلية و الترم لكي اعرضهما ... أي كلاهما باستطاعتنا عرضهما ولا يوجد مشاكل .. لماذا ؟ لانهما ذكرا في جملة الـ group by...







العملية معقدة جدا , لو كان هنالك تقسيمات اكثر من عمودين .


في الجملة السابقة سوف يقسم الصفوف الى ثلاث مجموعات (لانه يوجد ثلاث كليات)

ثم يقسم كل مجموعة من هذه المجموعات على حسب رقم الترم ...







أي انه بعد تقسيمه الى ثلاث مجموعات ينظر الى المجموعة الاولى من الصفوف ... ويجدها 8 صفوف ...


الصفة المشتركة بينهما هي ان رقم الكلية هو 1

نأتي للتقسيم الاخر ...

وهو على حسب عدد الاترام ...

الثمانية صفوف التي بالمجموعة الاولى سوف تقسم الى مجموعتين(لانه في الصفوف الثمانية لا يوجد الا ترمين , الاول والثاني !!)... الاولى منها صفوف الطلبة الذين يدرسون في الترم الاول , والثانية هي صفوف الطلبة الذين يدرسون في الترم الثاني ... لو وجد ترم اخر مثلا .. سوف يكون هنالك مجموعة ثالثة .... وهلم جر ... الان لدينا مجموعتين في الكلية رقم 1 ...









اذا كنت ما زلت غير مقتنع ... اذا كنت لا تفهم بلغة الكتابة ... اذا لم تعرف كيف اتت النتيجة السابقة ... اذا لم ترد ان تقرأ اصلا ... انظر الصورة :








http://img5.picsplace.to/img5/18/1102.jpg










لاحظ انه في حلنا السابق .. كتبنا مايلي :








group by col_no , trm_no










لو قلبناها وجعلناها هكذا :








group by trm_no , col_no








مالذي سوف يحدث ؟


ستكون نفس النتائج , ولكن بترتيب مختلف ...

في الاولى يقسم المجموعات بارقام الكليات ثم بالاترام ,

الثانية يقسم المجموعات بالاترام ثم بالكليات ...

انظر النتائج واستنتجها بنفسك ...

















select count(*) number_of_student , col_no , trm_no

from stud

group by trm_no , col_no ;








NUMBER_OF_STUDENT COL_NO TRM_NO

----------------- ---------- ----------

3 1 1

2 2 1

3 3 1

5 1 2

1 2 2

1 3 2

5 2 3

4 3 3

4 2 4

2 3 4

3 3 5






الان ... اريدك ان تتعرف على جملة الترتيب , والتي تجاهلتها منذ البداية لشيء ما في نفسي .


جملة Order by :







اريد ترتيب جدول الموظفين تصاعديا على حسب رواتبهم ...


تصاعديا يعني Ascending ... من تحت الى فوق , يعني يصعد ... يعني من الصغير الى الكبير .

تنازليا يعني Descending ... أي العكس .

اليك الجملة ....

















select ename,sal from emp

order by sal asc;










ENAME SAL

---------- ----------

SMITH 800

JAMES 950

ADAMS 1100

WARD 1250

MARTIN 1250

MILLER 1300

TURNER 1500

ALLEN 1600

CLARK 2450

BLAKE 2850

JONES 2975

SCOTT 3000

FORD 3000

KING 5000






الان تنازليا ...












select ename,sal from emp

order by sal desc ;








ENAME SAL

---------- ----------

KING 5000

SCOTT 3000

FORD 3000

JONES 2975

BLAKE 2850

CLARK 2450

ALLEN 1600

TURNER 1500

MILLER 1300

WARD 1250

MARTIN 1250

ADAMS 1100

JAMES 950

SMITH 800

The Coder
01-02-2006, 06:24 AM
بإمكاننا ان نتجاهل كلمة ASC , أي لو كتبنا :





select ename,sal from emp

order by sal ;




سوف يتم عرضها تصاعديا , لذا فبامكانك تجاهل ASC .


الان تعال لنعقد بعض الامور , ونخلط group by مع order by ولنرى النتائج ...

على فكرة , group by ترتب النتيجة تصاعديا بشكل اوتوماتيكيا , أي :





select deptno from emp

group by deptno ;








DEPTNO

------

10

20

30




اريد ان اعرض مجموع رواتب الموظفين لكل قسم , بشكل تنازلي .








select sum(sal) , deptno from emp

group by deptno

order by sum(sal) desc ;








SUM(SAL) DEPTNO

-------- ----------

10875 20

9400 30

8750 10




هل لاحظت جملة الترتيب ؟ رتبنا ماذا ؟ هل رتبنا الرواتب ؟ بل رتبنا مجموع الرواتب ..... اذا لم تفهم مالذي حدث فاقول لك .... ركز قليلا في الجملة ... اذا لم تفهم لماذا حدث ما حدث .. فاقول لك صبرا وسوف تعرف لماذا .

طيب , فكر لو كتبنا هكذا :





select sum(sal) , deptno from emp

order by sum(sal) desc

group by deptno ;




فهذا يعتبر خطأ !!

اذن يجب ان تكتب جملة التقسيم group by ثم جملة الترتيب order by


انظر ما يلي :





select sum(sal) , deptno from emp

group by deptno

order by sal desc ;




فهذا الامر .... خطأ !!

لان order by قال "رتب بحسب الرواتب " , فنقول له , لقد قسمنا الناتج وضمينا الناتج , ونتوقع منك يا order by ان ترتب على حسب رقم القسم او على حسب مجموع الرواتب فقط لا غير .





بإمكاننا ان نعمق مفهوم الترتيب اكثر , ونقول لك ..

اريد ان اعرض جدول الموظفين على حسب رقم القسم تصاعديا , ويكون كل قسم مرتب فيه الرواتب تنازليا .





DEPTNO SAL ENAME

------------ ----- ------

10 5000 KING

10 2450 CLARK

10 1300 MILLER



20 3000 SCOTT

20 3000 FORD

20 2975 JONES

20 1100 ADAMS

20 800 SMITH



30 2850 BLAKE

30 1600 ALLEN

30 1500 TURNER

30 1250 WARD

30 1250 MARTIN

30 950 JAMES




اليك الامر ...








select deptno,sal,ename from emp

order by deptno asc ,sal desc;




الان .... انا ارى في النتيجة السابقة لا تعجبني .

هنالك اثنين تعملون في القسم نفسه ... و يأخذون الراتب نفسه , احدهما SCOTT والاخر FORD


وهنالك اثنان آخران نفس الحالة ...

لو انه يوجد الف شخص يعملون في نفس القسم , لهم نفس الراتب .. اريد ترتيبهم على حسب القسم تصاعدي , ثم الراتب تنازليا , ثم الاسم تصاعديا !! فكما شاهدنا في النتيجة السابقة , وضع scott اولا ثم ford وانا اريده بالعكس .. وترتيب الاسم تصاعدي أي من A الى Z









select deptno,sal,ename from emp

order by deptno asc ,sal desc,ename asc ;




والان ستكون النتيجة :





DEPTNO SAL ENAME

------ ---------- ------

10 5000 KING

10 2450 CLARK

10 1300 MILLER

20 3000 FORD

20 3000 SCOTT

20 2975 JONES

20 1100 ADAMS

20 800 SMITH

30 2850 BLAKE

30 1600 ALLEN

30 1500 TURNER

30 1250 MARTIN

30 1250 WARD

30 950 JAMES




اعتقد انني سئمت وزهقت من هذا الموضوع , وطولت فيه

مثال اخير :





select col_no , to_char(avg(avg_po) ,'0.00') , trm_no , count(*) number_of_student

from stud

group by col_no , trm_no

order by col_no , avg(avg_po) ;










COL_NO TO_CH TRM_NO NUMBER_OF_STUDENT

------ ----- ---------- -----------------

1 3.14 2 5

1 4.53 1 3

2 1.89 2 1

2 4.21 3 5

2 4.39 4 4

2 4.45 1 2

3 3.09 1 3

3 3.10 3 4

3 3.44 4 2

3 3.92 5 3

3 4.77 2 1




جملة HAVING :


الان اريد ان اعرض مجموع رواتب الموظفين في كل قسم , بشرط ان يكون مجموع الراتب لقسم ما اكبر من 9000 دولار !!

فكر .... فكر .... فكر ......

انظر الى الحل الصحيح ... :





select sum(sal),deptno

from emp

where sum(sal) > 9000

group by deptno;




والنتيجة سوف تكون ....





ORA-00934: group function is not allowed here




خطأ مع مرتبة الشرف .!!!!

The Coder
01-02-2006, 06:26 AM
لا يمكننا استخدام الدوال المتعددة الصفوف مع جملة الشرط where , لذا لزم علينا اختراع جملة شرطية جديدة خاصة بالدوال المتعددة الصفوف , الا وهي having .







select sum(sal),deptno

from emp

group by deptno

having sum(sal) > 9000 ;








select sum(sal),deptno

from emp

group by deptno

having sum(sal) > 9000 ;








SUM(SAL) DEPTNO

-------- ----------

10875 20

9400 30




هل فهمت ؟ سهلة جدا , كأنها where لكنها خاصة بالنتائج النهائية لجملة التقسيم !!, هل تفهم ما معنى النتائج النهائية ؟ أي انظر فيما يلي :





select sum(sal),deptno

from emp

group by deptno ;




انظر الى النتيجة النهائية ...





SUM(SAL) DEPTNO

-------- ----------

8750 10

10875 20

9400 30




طيب .. من النتيجة النهائية , اريد ان اعرض منها فقط , كل ارقام القسم التي هي اكبر من 10 .... :








select sum(sal),deptno

from emp

group by deptno

having deptno>10 ;




انظر الناتج :








SUM(SAL) DEPTNO

-------- ----------

10875 20

9400 30




بعد ان قسم الى مجموعات ... وعرف الناتج ... طبق جملة الشرط having , ثم عرض علينا الناتج النهائي .

مع العلم انه لو قلنا :





select sum(sal),deptno

from emp

group by deptno

having sal > 1000 ;




فهو خطأ !! , واعتقد انك تعرف لماذا .

الان دعنا نضع كل شيء في جملة واحدة !

اريد ان اعرض وظائف و مجموع الرواتب لكل وظيفة والتي هي اكبر من 4000 دولار , بشرط ان لا تكون هذه الوظيفة وظيفة مدير , ومرتبه ترتيبا تنازليا على حسب مجموع الرواتب !!


بالله عليك فكر قليلا , لان هذا المثال من اعقد ما يكون ..

فكر فكر فكر فكر فكر فكر .........

هل فكرت ؟ اليك الحل :







select job,sum(sal)

from emp

where job <> 'MANAGER'

group by job

having sum(sal) > 4000

order by sum(sal);




هل تصدق ان هذا المثال الشامل الكامل لدرس اليوم !!

احفظ الترتيب ... (clause = جزئية او جملة ... )

Select clause

From clause

Where clause

Group by clause

Having clause

Order by clause




الان .. ما رأيك ان تكتشف حقيقة برنامج الأوراكل في ترجمة جمل الـ SQL ؟؟

مع العلم ان هذا استنتاجي ورأيي الخاص !! , اعتقد انه 90% صحيح , لكن الله العالم كيف عملوا طريقة ترجمة هذه الجمل , انا اجتهدت واختبرت كثيرا , واعتقد انه بإمكاني عمل برنامج شبيه ببرنامج SQL PLUS*




ترتيب قرائة برنامج الأوراكل :

اذا لم ترغب بالقرائة ... او انك لم تفهم السطور القادمة , يكفيك فقط ان تعرف ان البرنامج سوف ينفذ اولا الجملة الشرطية where ثم group by ثم having ثم أخيرا order by


اليك مثالنا السابق :








select job,sum(sal)

from emp

where job <> 'MANAGER'

group by job

having sum(sal) > 4000

order by sum(sal);




اولا : يذهب الى from clause


يرى ما هو الجدول ... ثم يذهب ويبحث عنه اذا لم يجده فسوف يعطيك خطأ بأنه لم يجد الجدول .. اذا وجده يذهب للخطوة الثانية





ثانيا : يذهب الى where clause (اذا وجده اصلا)

يرى الشرط هل هو صحيح اصلا او لا , اذا كان صحيحا يبدأ ويطبق الشرط على الجدول , ثم ينسخ الى الذاكرة الناتج (لنسميه الناتج أ ).




ثالثا : يذهب الى group by clause (اذا وجده اصلا)

يرى هل العمود المراد تقسيم الناتج ( الناتج أ ) .. موجود اصلا في الجدول او لا !!


اذا لا ... فهذا خطأ .


طبعا اذا وجد عمودين , يقسم بالاول ثم يقسم بالثاني ...


المهم يقسم على حسب الاعمدة الموجودة , ثم يخزن في الذاكرة الناتج مقسما (لنسميه الناتج ب ) .




رابعا : يذهب الى having clause (اذا وجده اصلا )

سوف يرى , هل الشرط صحيح او لا .. بمعنى هل الشرط يتناسب مع التقسيم (الناتج ب) او لا ...

في الحقيقة ان having اصلا لا يأتي نفعها فعليا الا اذا وجد group by .


الان سوف يطبق الشرط الموجود في الجملة having على الناتج المقسم ( الناتج ب ) ومن ثم يكون الناتج الاخير في الذاكرة ( لنسميه الناتج ج )

خامسا : يذهب الى order by clause


سوف يرى اولا هل الاعمدة التي في order by موجودة في الناتج ج ؟؟ او لا

اذا وجدها .. فسوف يرتبها على حسب الاعمدة المذكورة ... ويكون الناتج د .....





سادسا :الان يذهب الى select clause , ويرى الاعمدة الموجودة به , والتي نريد ان نعرضها ,

- يرى هل الاعمدة المذكورة موجودة اصلا في الجدول او لا ... اذا لا يعطي خطأ ويتوقف .


- يرى هل يوجد دالة متعددة الصفوف او لا , اذا لا يطابق الاعمدة المذكورة مع النتيجة د واذا طابقت يعرض فقط صفوف الاعمدة المذكورة , ويتجاهل البقية .

- اذا وجد دالة متعددة الصفوف , فإنه ينظر في الناتج د , ويطبق الدالة على كل صف في الناتج د

The Coder
01-02-2006, 06:27 AM
الان هذه الخطوات الخمسة نطبقها بشكل عملي على حسب المثال السابق :





select job,sum(sal)

from emp

where job <> 'MANAGER'

group by job

having sum(sal) > 4000

order by sum(sal);




اولا : يذهب الى from clause


يرى الملف ... اااقصد الجدول emp موجود ولا زال على قيد الحياة .





ثانيا : يذهب الى where clause (اذا وجده اصلا)

نعم يجد الجملة الشرطية هذه , والتي تقول كل الصفوف التي لا تحتوي على العمل "مدير"

سوف يكون الناتج أ :






EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

----- ---------- --------- ---------- -------- ---------- ---------- ----------

7369 SMITH CLERK 7902 17/12/80 800 20

7499 ALLEN SALESMAN 7698 20/02/81 1600 300 30

7521 WARD SALESMAN 7698 22/02/81 1250 500 30

7654 MARTIN SALESMAN 7698 28/09/81 1250 1400 30

7788 SCOTT ANALYST 7566 19/04/87 3000 20

7839 KING PRESIDENT 17/11/81 5000 10

7844 TURNER SALESMAN 7698 08/09/81 1500 0 30

7876 ADAMS CLERK 7788 23/05/87 1100 20

7900 JAMES CLERK 7698 03/12/81 950 30

7902 FORD ANALYST 7566 03/12/81 3000 20

7934 MILLER CLERK 7782 23/01/82 1300 10








ثالثا : يذهب الى group by clause (اذا وجده اصلا)

سيجده يقول ترتيب بواسطة الـ job , نعم هذا عمود موجود في النتيجة أ

الان سوف يقسمه ويضم الناتج ويتجاهل الاعمدة ما عدى الاعمدة الموجودة في الـ group by


انظر الناتج ب :





JOB

---------

ANALYST

CLERK

PRESIDENT

SALESMAN







رابعا : يذهب الى having clause (اذا وجده اصلا )

سيجد الشرط يقول ... sum(sal) >4000


ينظر الى الناتج ب .... ويعمل الآتي :


- يجد أول صف هو (العمل = analyst)

- يبحث في جدول الـ emp (الجدول الأصلي الذي به جميع الصفوف !!) عن جميع الصفوف التي ( job <> 'MANAGER' ) و التي (job ='ANALYST') فسوف يكون الناتج ...





EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

----- ---------- --------- ---------- -------- ---------- ---------- ----------

7788 SCOTT ANALYST 7566 19/04/87 3000 20

7902 FORD ANALYST 7566 03/12/81 3000 20




- قلنا ان الشرط sum(sal) >4000 , مجموع الرواتب هنا ... 6000 ... هل هو اكبر من 4000 ؟ نعم انه اكبر ...

اذن ANALYST ستكون في القائمة ....

- يرجع الى الصف الذي يليه ثم ينفذ الخطوات السابقة ..





في النهاية سوف يكون لدينا ... الناتج ج :





JOB

---------

ANALYST

CLERK

PRESIDENT

SALESMAN







(بالصدفة وجد كل الوظائف ... مجموع رواتبها اكبر من 4000)





خامسا : سوف يذهب الى order by clause والذي يطلب ترتيب على حسب مجموع الرواتب ..

سوف يمر على كل صف في الناتج ج


- فمثلا .. يرى ANALYST , ويذهب الى الجدول emp (الجدول الأصلي الذي به جميع الصفوف !!)...

- يبحث عن كل الصفوف التي يكون العمل فيها لا يساوي مدير , والتي يكون العمل فيها يساوي ANALYST


ثم تظهر له عدة صفوف , ويبدأ يحسب مجموع الرواتب في هذه الصفوف .....

- انتهى من ANALYST , يبدأ في الصف التالي ....

- في النهاية وبعد ان حفظ مجاميع الرواتب لكل صف في الناتج ج .... يبدأ يرتب بطريقته الخاصة !! وبالتالي تظهر النتيجة د :





JOB

---------

CLERK

PRESIDENT

SALESMAN

ANALYST




مرتبة على حسب مجموع الرواتب .





سادسا :الان يذهب الى select clause , ويرى الاعمدة الموجودة به , والتي نريد ان نعرضها ,

موجود يا سيدي ... الـ job .... اذن مقبولة لانها موجودة في النتيجة د وسوف تكون في الحسبان للعرض ,

وموجود شيء اخر وهو ... sum(sal)


سوف يوجدها لكل صف في النتيجة د كما عملنا في الخطوة الخامسة ... ومن ثم يعرضها .





انتهت الخطوات ....

وما بقي عليك الا معرفة انه من الممكن ان تكون طريقتي هذه غير كفئ 100% , اعتقد لو أمعنا وفكرنا , من المؤكد انه يوجد طريقة اخرى أسهل و أفضل .


الان دعنا نعطي بعض الأمثلة . من جدول stud السابق ....

اريد عرض عدد الطلبة الذين حصلوا على معدل ما بين 1 و 1.99 أي المعدل الذي عدده الصحيح واحد .

وعدد الطلبة الذين حصلوا على معدل ما بين 2 و 2.99اي المعدل الذي عدده الصحيح اثنين ..... الخ

أي اريد الناتج كما يلي :







the avg the number of students

------- ----------------------

1 1

2 7

3 9

4 15

5 1




فكر قليلا !!

يجب ان تعرف حله بنفسك .. واجه المشكلة بنفسك ..





اليك الحل :








select trunc(avg_po) "the avg" , count(*) "the number of students"

from stud

group by trunc(avg_po) ;




انظر الى الحل ..

كم هو سهل ...

فكر لو حللنا هكذا .. هل ستصبح صحيحة ؟؟ :





select avg_po "the avg" , count(*) "the number of students"

from stud

group by trunc(avg_po) ;




في الحقيقة خاطئة !!

هل avg_po نفس trunc(avg_po) ؟؟


انا شخصيا كنت اعتقد انهما متساويتين في العمل , وكنت اعتقد ان الحل السابق كان صحيح !!

لكن ظهر لي الخطأ فعرفت ان :


Group by trunc(avg_po)


سوف يظهر لي نتيجة غير :


Group by avg_po




فكر فيها .. , ستجد انه من المخزي عمل مثل الجملة السابقة !! فكر وارسم على ورق الناتج .





الان , اريد ان اعرض المعدل الحسابي ( المعدل الحسابي هو مجموع القيم مقسوم على عددها !! ) لمعدلات كلية ما والذين اخذو ترم ما ...

أي مثلا .. اريد عرض المعدل الحسابي لمعدلات جميع الطلبة في الكلية الاولى والذين درسوا ترم واحد كمجموعة ...

و عرض المعدل الحسابي لمعدلات جميع الطلبة في الكلية الاولى والذين درسوا ترمين كمجموعة اخرى ... وهكذا !!

اريد النتيجة كما يلي :





AVG COL_NO TRM_NO NUMBER_OF_STUDENT

----- ---------- ---------- -----------------

1.89 2 2 1

3.09 3 1 3

3.10 3 3 4

3.14 1 2 5

3.44 3 4 2

3.92 3 5 3

4.21 2 3 5

4.39 2 4 4

4.45 2 1 2

4.53 1 1 3

4.77 3 2 1






فكر ....





اليك الحل :








select to_char(avg(avg_po) ,'0.00') "AVG" , col_no , trm_no , count(*) number_of_student

from stud

group by col_no , trm_no

order by avg(avg_po) ;




تم تقسيم الصفوف على حسب رقم الكلية , وعدد الأترام !!

... فكر فيها ..... وحاول فهمها بطريقتك .


الان اريد تعميق التقسيم ... لقد قمت بالتجارب كثيرا .. واخترعت امثلة كثيرة ...

جاء دورك لكي تخترع انت بنفسك امثلة ... لان ذلك يزيد من عمق فهمك ...

اليك مثال اخير نختم به الدرس .. واعتقد انه سهل عليك الان ,’,’,’

في جدول الطلبة stud اريد عرض كم عدد الطلبة الذين اخذو معدل عدده الصحيح موحد , وقسمهم موحد , و لهم نفس عدد الأترام ,


أي عدد الطلبة الذين اخذوا معدل بين 1 و 1.99 في الكلية الاولى , وعدد اترامهم ترم واحد ...

وعدد الطلبة الذين اخذوا معدل بين 1 و 1.99 في الكلية الاولى ... وعدد اترامهم ترمين ...

.....

.....

.....


أي اريد النتيجة كما يلي :





COL_NO TRM_NO TRUNC(AVG_PO) NUMBER_OF_STUDENT

------ ---------- ------------- -----------------

1 1 3 1

1 1 4 1

1 1 5 1

1 2 2 2

1 2 3 2

1 2 4 1

2 1 4 2

2 2 1 1

2 3 3 1

2 3 4 4

2 4 3 1

2 4 4 3

3 1 2 1

3 1 3 2

3 2 4 1

3 3 2 2

3 3 3 2

3 4 2 1

3 4 4 1

3 5 2 1

3 5 4 2




و الحل .... ؟؟

The Coder
01-02-2006, 06:28 AM
اليك الحل ....





select col_no ,trm_no ,trunc(avg_po), count(*)number_of_student

from stud

group by col_no , trm_no , trunc(avg_po) ;









فكرته تقسيم بحسب ثلاث اعمدة ....

حاول رسم التقسيم ..... وفهمها , طبق وجرب وفكر وارسم وخطط وتعذب واشقى واتعب ...... وفي النهاية سوف تفهم مالم يفهمه غيرك .

الان انتهى الدرس ...

سوف تتعرف في الدرس القادم على الصلاحيات , و ربط الجداول , والاستعلامات الفرعية ....

واعتقد ان الدرس القادم هو اخر درس في الـ SQL والدرس الذي بعده سوف يكون تمارين وامثلة وحل لأسئلة اختبارات شهادات أوراكل المعتمدة ان شاء الله ... لذا ترقب

عجماني
01-02-2006, 09:26 AM
بصراحه احببتك في الله


صح شرحك طويل بس ممتع ومفيد

الى الامام يابرفسور

The Coder
01-02-2006, 06:30 PM
بصراحه احببتك في الله


صح شرحك طويل بس ممتع ومفيد

الى الامام يابرفسور


شكرا لك يا عجماني ....
و انا كنت قاصد تطويل الدرس ... لان بعضهم لا يستطيع الفهم كثيرا .. من الكلام المختصر ^^
الناس اجناس يا سيدي ^^
سلااااااااام

allahome
02-02-2006, 03:29 PM
بسم الله الرحمن الرحيم
أخى العزيز ...
بارك الله فيك و جعله الله فى ميزان حسناتك
اخى الفاضل
انا اقوم الآن و معى بعض الزملاء المتخصصين بعمل موسوعه كبيره تكون مرجع شامل و شافى و وافى للعرب و المسلمين و ذلك ابتغاء وجه الله تعالى من باب علم ينتفع به و يكون صدقه جاريه باذن الله
حيث نقوم بكل طاقتنا بشرح موضوعات عده ، كل فى تخصصه فهناك من يشرح الفيجوال بيسك دوت نت و السى شارب دوت نت و الدلفى و هناك من يشرح السكوال سيرفير و هناك من يشرح windows server 2003 و كيفيه عمل دومين و عمل و الإتصال به عن طريق خط adsl كل ذلك الشرح عن طريق الفيديو بالصوت و الصورة.
و انا كنت متابع لشركات كثيره فى هذا المجال و شركه ميكروسوفت التى اعجبت بها كثيرا و لكنى وجدت قصور شديد فى المكتبه العربيه فى الشرح بالصوت و الصورة
فكثيرا من الأشخاص يتابعون كتب كثيره مشروح بها و لكنهم لا يستطيعون التطبيق اما مع الشرح بالصوت و الصورة فالأمر يسير جدا جدا جدا و هناك اشياء كثيره تكون اسهل فى الكلام اكثر منها بالكتابه
صديقى الفاضل
نحن نمتلك افضل و اروع برنامج لتسجيل الشروحات بالفيديو البرنامج قمه فى الروعه دقع عاليه و مساحه قليله و يمكن التسجيل باكثر من نسق فهناك تنسيق الفلاش او الفيديو avi , wvm و غيرها دقه عاليه جدا جدا جدا فى الصوت و الصورة و كذلك حجم صغير نوعا ما فقد يكون حجم الملف wvm حوالى 13 ميجا لنصف ساعه شرح
و الحمد لله مع انتشار خطوط الـdsl فى الوطن العربى لا توجد مشكله من تحميل اى منها
ولو اردت حضرتك ان تأخذ بعض العينات من اعمالنا فى ذلك المجال فممكن ان تراسلنى لأن الأعمال لم تظهر للنور بعد فنحن نود ان نعمل سيرفير مجانى شامل كل هذه الشروحات و تكون شروحات فيديو و صوت من المتخصصين فى كل مجال حتى يبدع كل منهم
معذرة للإطاله و لكنى اردت ان تحول شرحك الى شرح فيديو حتى تعم الفائده للجميع
و ذلك سواء كان الشرح هذا عملى او نظرى لأن الشرح النظرى بالصوت يقرب الفكره جدا جدا للأنسان و لا تعجب عن كيفيه الشرح النظرى فانشاء الله ممكن ان اعطيك جزء من اعمالنا لترى كيفيه الشرح النظرى و العملى بكل سهوله و الشرح النظرى باستخدام برامج رسوميه ممتازه من الممكن ان نقوم بتوفير كل الأدوات اللازمه من تصميم شاشات عرض و غيرها حتى تكون جاهزه لسيادتكم على العمل
و معذرة للإطالة
تحياتى
د. علاء عبد الرحمن
محاضر لغات برمجه
AGC

The Coder
04-02-2006, 07:25 AM
بسم الله الرحمن الرحيم
أخى العزيز ...
بارك الله فيك و جعله الله فى ميزان حسناتك
اخى الفاضل
انا اقوم الآن و معى بعض الزملاء المتخصصين بعمل موسوعه كبيره تكون مرجع شامل و شافى و وافى للعرب و المسلمين و ذلك ابتغاء وجه الله تعالى من باب علم ينتفع به و يكون صدقه جاريه باذن الله
حيث نقوم بكل طاقتنا بشرح موضوعات عده ، كل فى تخصصه فهناك من يشرح الفيجوال بيسك دوت نت و السى شارب دوت نت و الدلفى و هناك من يشرح السكوال سيرفير و هناك من يشرح windows server 2003 و كيفيه عمل دومين و عمل و الإتصال به عن طريق خط adsl كل ذلك الشرح عن طريق الفيديو بالصوت و الصورة.
و انا كنت متابع لشركات كثيره فى هذا المجال و شركه ميكروسوفت التى اعجبت بها كثيرا و لكنى وجدت قصور شديد فى المكتبه العربيه فى الشرح بالصوت و الصورة
فكثيرا من الأشخاص يتابعون كتب كثيره مشروح بها و لكنهم لا يستطيعون التطبيق اما مع الشرح بالصوت و الصورة فالأمر يسير جدا جدا جدا و هناك اشياء كثيره تكون اسهل فى الكلام اكثر منها بالكتابه
صديقى الفاضل
نحن نمتلك افضل و اروع برنامج لتسجيل الشروحات بالفيديو البرنامج قمه فى الروعه دقع عاليه و مساحه قليله و يمكن التسجيل باكثر من نسق فهناك تنسيق الفلاش او الفيديو avi , wvm و غيرها دقه عاليه جدا جدا جدا فى الصوت و الصورة و كذلك حجم صغير نوعا ما فقد يكون حجم الملف wvm حوالى 13 ميجا لنصف ساعه شرح
و الحمد لله مع انتشار خطوط الـdsl فى الوطن العربى لا توجد مشكله من تحميل اى منها
ولو اردت حضرتك ان تأخذ بعض العينات من اعمالنا فى ذلك المجال فممكن ان تراسلنى لأن الأعمال لم تظهر للنور بعد فنحن نود ان نعمل سيرفير مجانى شامل كل هذه الشروحات و تكون شروحات فيديو و صوت من المتخصصين فى كل مجال حتى يبدع كل منهم
معذرة للإطاله و لكنى اردت ان تحول شرحك الى شرح فيديو حتى تعم الفائده للجميع
و ذلك سواء كان الشرح هذا عملى او نظرى لأن الشرح النظرى بالصوت يقرب الفكره جدا جدا للأنسان و لا تعجب عن كيفيه الشرح النظرى فانشاء الله ممكن ان اعطيك جزء من اعمالنا لترى كيفيه الشرح النظرى و العملى بكل سهوله و الشرح النظرى باستخدام برامج رسوميه ممتازه من الممكن ان نقوم بتوفير كل الأدوات اللازمه من تصميم شاشات عرض و غيرها حتى تكون جاهزه لسيادتكم على العمل
و معذرة للإطالة
تحياتى
د. علاء عبد الرحمن
محاضر لغات برمجه
AGC


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

اهلا بك ... اهلا وسهلا ويا مرحبا .
حيا الله الدكتور علاء ^^

شكرا لمرورك , وشكرا لاطالتك .. تعبناك ويانا , واسف لتأخر ردي !!
يابوي .. لا مانع لدي .. ابدا في عرضك ...
ولكن .... انا اشتغل الان على الديال اب ..
يلزمني شهرين او شهر ... لكي اركب خدمة نت سريع ... اما ساتلايت .. او دي اس ال

5 ميقا الان كثيرة علي .. لاني بكل بساطة ... ديال اب !!
نفسي اشرح بالصوت والصورة ....
عرضك جميل يا دكتور ... ولكن .. المشكلة الديال اب ..
مارأيك .؟؟
وهل اطلعتني على عمل من اعمالكم ... ولكن ملف صغير ^^
شكرا لك يا دكتور ...
و انتظر ردك ....

يادكتور ,’,’,’,’,’,’,’,’,’

allahome
04-02-2006, 01:19 PM
السلام عليكم

و بارك الله فيك و انا انتظر خط النت حتى يصلك

يمكنك مراسلتى على

alaa_eg80@msn.com

تحياتى

The Coder
06-02-2006, 02:37 PM
السلام عليكم

و بارك الله فيك و انا انتظر خط النت حتى يصلك

يمكنك مراسلتى على

alaa_eg80@msn.com

تحياتى

السلام عليكم ....
حياك ربي .... وبارك الله فيك ..
سنلتقي قريبا ..




الاخوة القارئين
اعتذر بشدة ...
ظروف وسفريات المت بي ....
لذا سوف اتأخر اسبوع ....
اسف جدا .. مضطر لذلك ...
سلام

The Coder
15-02-2006, 05:51 AM
بسم الله الرحمن الرحيم

الدرس الثاني عشر


اسم الدرس : جملة الاستعلام select والدوال


نوع الدرس : تطبيقي


صعوبة الدرس : **** من *****


اهميــة الدرس : ****** من ***** (Over)


درجة احتراف لغةSQL المتوقعة بعد هذا الدرس : **** من ***** (شبه خبير)


الوقت المتوقع منك لفهم الدرس : ثماني ساعات .


المتوقع منك في هذا الدرس :


- الاستعلامات الفرعية

- ربط الجداول


-


- الصلاحيات





هيا لنؤركل ^^


السلام عليكم

عرفنا في دروس سابقة القيود وكيفية اضافتها على الجداول , وعرفنا ايضا تقسيم الدوال ذوات الصفوف المتعددة الى مجموعات .

سنواجه الان كم من المصائب والمشاكل والكوارث الجديدة والتي لم تنتهي بعد وحان دورنا ان نعالجها , مع العلم ان هذا الدرس .. ناقص قليلا ... وسوف اكمل النقص في درس قادم ان شاء الله ..

الان اريد ان اعرف اسماء الموظفين الذين يأخذون رواتب اكبر من راتب الاخ الفاضل .. scott


كيف نعرف ؟؟

بسيطة .....

نذهب ونوجد راتب الاخ scott


ثم نعرف راتبه كم ... ثم نكتبه في جملة استعلام اخر .....

اليك الحل :








select sal from emp where ename='SCOTT';




سوف تعرض لنا النتيجة .... كما يلي





SAL

----

3000




اذن راتب الرجل يساوي 3000

هيا لنوجد كل من راتبه اكبر من او يساوي 3000 واسمه ليس اسكوت ...





select ename ,sal from emp where sal >=3000 and ename <>'SCOTT';




الاجابة الجميلة .... :





ENAME SAL

---------- ----------

KING 5000

FORD 3000




طيب .... نريد اسماء كل من هم موجودين بقسم صاحبنا scott


والذين رواتبهم اكبر من او تساوي راتب Jones


والذين حرفهم الاول مثل اول حرف الموظف صاحب اصغر راتب !!

الان شاهد كيف سأحصل عليها ...

يريد اسماء الذين في قسم scott , ممممم ..... ماهو قسم السيد اسكوت ؟؟؟

دعني اذهب واتأكد ...








SQL> select deptno from emp where ename='SCOTT' ;



DEPTNO

----------

20




اذن ... القسم 20 !!

هيا ... لنكتشف من هم هؤلاء !!








SQL> select ename from emp where deptno=20;



ENAME

----------

SMITH

JONES

SCOTT

ADAMS

FORD




الان ..... يقول لي انه يريد من هؤلاء .. الذي راتبه اكبر من او يساوي راتب جونز ....

لنرى ذلك ... ولكن ... كم راتب جونز ؟؟؟؟

ممممم لنرى ذلك :








SQL> select sal from emp where ename='JONES';



SAL

----------

2975




اها .... 2975 , اذن ... كل من في قسم 20 وراتبه اكبر من او يساوي 2975

لقد استنتجت هذه الارقام بنفسي ....

هيا لنرى :








SQL> select ename from emp where deptno=20 and sal >=2975 ;



ENAME

----------

JONES

SCOTT

FORD




ماذا يريد بعد ؟؟

كل الموظفين الذين حرفهم الاول مثل حرف الموظف صاحب اصغر راتب !!

من هو صاحب اصغر راتب ؟؟ لا اعرف .. سوف اكتشف ذلك :










SQL> select min(sal) from emp ;



MIN(SAL)

----------

800




ممممم .... راتبه =800 ..... من هو يا ترى ؟؟ لنرى ذلك :





SQL> select ename from emp where sal=800;



ENAME

----------

SMITH




انه سميث ... مسكين سميث ... يأخذ فقط 800 دولار في الشهر ... اشفق عليه ....

اوبس .. أين وصلنا ؟؟؟

نسيت ؟؟؟ لقد تشابكت علي الدنيا ....

اها .... وصلنا عند " كل الموظفين الذين حرفهم الاول مثل حرف الموظف صاحب اصغر راتب"

سميث ... حرفه الاول S


اذن .... كأن المسئلة التي تقول :

" نريد اسماء كل من هم موجودين بقسم صاحبنا scott


والذين رواتبهم اكبر من او تساوي راتب Jones


والذين حرفهم الاول مثل اول حرف الموظف صاحب اصغر راتب !! "







هي نفسها :

" نريد اسماء كل من هم موجودين بقسم 20

والذين رواتبهم اكبر من او تساوي 2975

والذين حرفهم الاول S !! "




الان لأرى مالنتيجة . لأرى من هم هؤلاء :

The Coder
15-02-2006, 05:55 AM
SQL> select ename from emp where sal>=2975 and deptno=20 and ename like 'S%';



ENAME

----------

SCOTT




تبا لك يا اسكوت ... هل هو انت صاحب هذه المواصفات القياسية ؟؟

اووووف .. انا من ناحيتي تعبت .. ماذا عنك وانت تقرأ ؟؟

كل مافي المسئلة اشياء مجهولة لا نعرفها , ولكي نعرفها يجب ان نوجدها على انفراد ... ماهذا يا أوراكل هل بالله عليك هذا حل ؟؟

اذا كانت المسئلة الصغيرة تعمل فينا ما عملت !! فما بالك بـمسئلة اكبر قليلا , او مسئلة اعقد واكبر !!

مالحل ؟ كيف نوجد المجاهيل وعلى ضوئها نوجد الاستعلام الذي نريده ؟

اوجدنا قسم اسكوت , وراتب جونز , وصاحب اصغر راتب , وايضا حرفه الاول

هذا كثيــــــر .... كثير جدا !





- الاستعلامات الفرعية ( Sub-query):


عملنا في المسئلتين السابقة .. استعلامات خارجية صح ؟

أي ذهبنا واستعلمنا عن قسم اسكوت في استعلام خارجي ..... وهو استعلام فرعي !

أوراكل يقترح علينا استخدام الاستعلامات الفرعية والتي تجعل أوراكل يبدو ذكيا جدا ...

لنرى كيف هذه الاستعلامات وطريقة عملها .

اريد ان اعرف اسماء الموظفين الذين يأخذون رواتب اكبر من راتب scott


عرفنا جملة الاستعلام التي توجد راتب الموظف scott , اليك جملة الاستعلام الفرعية وهي تأتي بين قوسين :








SQL> select ename from emp where sal >= (select sal from emp where ename='SCOTT');



ENAME

----------

SCOTT

KING

FORD




واو .. لاحظ انه في جملة استعلام واحدة وفي خطوة واحدة عملنا كل ذلك الجهد في المسئلة الاولى ...

لاحظ جملة الاستعلام الفرعية .. والتي بين قوسين , وهي تخبر الأوراكل مايلي :

(اختر الصفوف يا أوراكل من جدول emp لكل من اسمه = اسكوت )

هل سيعرضها الأوراكل ؟؟؟ هل نستطيع رؤيتها ؟؟

لا .... لن نستطيع رؤيتها ...

جملة الاستعلام الفرعية التي بين قوسين ... كأنها لا تقول "اعرض" .. كأنها تقول "أوجد"

لاحظ جملة الاستعلام انه اختار كم عمود ؟؟ عشرة ؟؟ عشرون ؟؟

بل عمود واحد , وهو الرواتب ....

لماذا الرواتب ؟ لأننا نريد ان نقارنه مع الراتب الموجود في جملة الاستعلام الرئيسية ...

كيف ذلك ؟

سوف يوجد اولا الجملة الفرعية كما يلي :





SQL> select sal from emp where ename='SCOTT' ;



SAL

----------

3000




لاحظ انه صف واحد , وعمود واحد ..

وهي قيمة واحدة .. كم ؟ 3000

أين يضعها ؟ هل يعرضها على الشاشة ؟؟

لا بل يرسلها الى جملة الاستعلام الرئيسية !!

كيف يرسلها ؟

يستبدل القيمة الناتجة بالاستعلام الفرعي ... أي :








select ename from emp where sal >= (select sal from emp where ename='SCOTT');


يوجد اولا الاستعلام الفرعي .. ثم يحول الجملة كما يلي :


select ename from emp where sal >= (3000 );




الان فهمنا الديناميكية التي تحدث داخل أوراكل ونحن اخر من يعلم عن ذلك ؟؟؟

يا سلام يا أوراكل ... كم انت ذكي جدا !!

الان ... لو كتبنا مايلي .... فإنه سيكون خاطئ ... لماذا ياترى ؟؟ :








SQL> select ename from emp where sal >= (select sal ,ename from emp where ename='SCOTT');




هل دققت ؟ هل فكرت ؟؟

اليك السبب بلسان أوراكل :





select ename from emp where sal >= (select sal ,ename from emp where ename='SCOTT');


سوف احولها الى مايلي :


select ename from emp where sal >= ( 3000 , 'SCOTT')


اوبس ... كيف أقارن .. هل مع القيمة الاولى ام القيمة الثانية ؟؟

خطأ يا ايها المستخدم .... لا يجوز ... مع ماذا أقارن هل أقارن العمود رواتب مع 3000 او مع "اسكوت"؟؟





هل فهمت ؟

يجب ان تقارن عمود مع عمود .

الان اريد ان احل المسئلة المعقدة تلك والتي تنص على :


" نريد اسماء كل من هم موجودين بقسم صاحبنا scott


والذين رواتبهم اكبر من او تساوي راتب Jones


والذين حرفهم الاول مثل اول حرف الموظف صاحب اصغر راتب !!"


هل مستعد ..... فكر فيها قليلا .. ستجدها سهلة ...





لم تعرف ؟؟؟؟ لم تستطع ؟؟ هل هي معقدة لهذه الدرجة ؟؟

اذن حاول ان تحل المسئلة التالية وسوف نحل السابقة قريبا :

" نريد اسماء كل من هم موجودين بقسم صاحبنا scott


والذين رواتبهم اكبر من او تساوي راتب Jones "


هل تستطيع .. طبعا تستطيع ولا ضير من ذلك ...





انظر حل المسئلة ....








select ename from emp where deptno=(select deptno from emp where ename='SCOTT' )

and sal >= (select sal from emp where ename='JONES');




لاحظ كلمة AND وليست OR ... على حسب السؤال .

سهلة اعتقد ولا يوجد فيها اختراع ...

نرجع للمسئلة التي تركناها ...


" نريد اسماء كل من هم موجودين بقسم صاحبنا scott


والذين رواتبهم اكبر من او تساوي راتب Jones


والذين حرفهم الاول مثل اول حرف الموظف صاحب اصغر راتب !!"


اعتقد انك تضررت في الطلب الاخير صح ؟؟ اليك الحل يا فتى :










SQL> select ename from emp where deptno=(select deptno from emp where ename='SCOTT' )

and sal >= (select sal from emp where ename='JONES')

and ename like (select substr(ename,1,1) from emp where sal=(select min(sal) from emp) ) ||'%';





ENAME

----------

SCOTT






والجواب كان اسكوت ...

اليك خطوات الحل بلسان أوراكل نفسه ....









اولا ... سأرى الجملة كاملة :


select ename from emp where deptno=(select deptno from emp where ename='SCOTT' )

and sal >= (select sal from emp where ename='JONES')

and ename like (select substr(ename,1,1) from emp where sal=(select min(sal) from emp) ) ||'%';




ممممم ... الجمل الفرعية كثيرة هنا ... سوف اوجد الاعمق فيها ....

أي الجمل الفرعية للجمل الفرعية ....

وهي جملة الاستعلام عن اصغر راتب ...

اصغر راتب هو 800




select ename from emp where deptno=(select deptno from emp where ename='SCOTT' )

and sal >= (select sal from emp where ename='JONES')

and ename like (select substr(ename,1,1) from emp where sal= (800) ) ||'%' ;




الان ... تخلصت من الاستعلامات الفرعية الاعمق ... وسوف اتخلص من البقية .....




select ename from emp where deptno= (20)

and sal >= (2975)

and ename like ('S')||'%' ;


الان .....

'S' || '%' = 'S%'


الان ...... الجملة شكلها هكذا ....


select ename from emp where deptno= (20)

and sal >= (2975)

and ename like 'S%' ;


هه.. الان سهل الحل :




ENAME

---------

SCOTT

The Coder
15-02-2006, 06:03 AM
هل لاحظت الديناميكية ؟؟

بسيطة ... ولا تنسى ان تضع الاستعلام الفرعي بين قوسين ...

اليك مثال اخر .. من نوع اخر :

اريد عرض رقم القسم , و اصغر راتب لكل قسم , شريطة ان اصغر راتب يكون اكبر من اصغر راتب بالقسم 20

اولا خذ المسألة السابقة بالمقلوب ... اقرأ المعطى و المطلوب

اكبر من اصغر راتب بالقسم 20 .....

ما هو اصغر راتب بالقسم 20 ؟؟ سنضعه في الاستعلام الفرعي !!

ونعرض اصغر الرواتب ونقسمهم على حسب رقم القسم .... انظر الناتج وحاول ان تستنتج , ولن تستنتج طالما لم تقرأ الدرس السابق ولم تطبق .








SQL> select min(sal) ,deptno from emp

group by deptno

having min(sal) >(select min(sal) from emp where deptno=20);



MIN(SAL) DEPTNO

---------- ----------

1300 10

950 30




واو , حتى في جملة having استخدمنا الاستعلام الفرعي !!

رائع يا استعلام يا فرعي .... رائع !





الان اريد منك ان تلاحظ ان الاستعلامات الفرعية المستخدمة حتى هذه اللحظة ... ترجع بصف واحد !!

ارجع الى الامثلة التي فوق ... وشاهدها كلها ....

هل هذا يعني ان الاستعلامات الفرعية للصف الواحد ؟؟ لا لا

انا قصدت ذلك ...

الان انظر الى الجملة التالية , وهي خاطئة مئة بالمئة , لماذا يا ترى ؟؟








SQL> select ename from emp where sal =( select sal from emp ) ;



ERROR at line 1:

ORA-01427: single-row subquery returns more than one row




يقول ان الـ Subquery ترجع باكثر من صف !!

بالعقل , من الذي راتبه يساوي (رواتب جميع الموظفين ؟) ؟؟

بالله عليك قل لي واحد راتبه يساوي 3000 ويساوي 2975 ويساوي 800 ...... في نفس اللحظة ؟؟

غريب المنطق ... يمر علينا مرور الكرام ولا نفكر ابدا !!

الاستعلام الفرعي صاحب الصف الواحد يسمى Single-row subquery


الاستعلام الفرعي صاحب الصفوف المتعددة يسمى Multi-row subquery


لاحظ ان الاستعلام الفرعي ذو الصف الواحد ... به ماذا ؟

به مقارنات ... ممكن ان تكون = او تكون > او >= او <> (لا تساوي) .........

هل فهمت

اما الاستعلامات الفرعية ذو الصفوف المتعددة تستخدم ماذا ؟

تستخدم IN , ANY , ALL


اليك مثال عن المتعددة الصفوف :

اريد ان اعرض كل من راتبهم يساوي أي من رواتب الموظفين ذو الرواتب الاقل لكل قسم ..

(من هم ذوي الرواتب الاقل لكل قسم ؟؟)








SQL> select ename , sal , deptno from emp

where sal IN( select min(sal) from emp group by deptno );



ENAME SAL DEPTNO

---------- ---------- ----------

MILLER 1300 10

SMITH 800 20

JAMES 950 30






IN تعني .... أي من ....

كيف ذلك ؟ الاستعلام الفرعي سوف يرجع لنا اكثر من قيمة , اكثر من صف !! لاحظ كلمة "صف" !!

انظر كيف يفكر الأوراكل :








SQL> select ename , sal , deptno from emp

where sal IN( select min(sal) from emp group by deptno );


ممممم .... الاستعلامات الفرعية اولا ...




( select min(sal) from emp group by deptno );




سيكون الناتج ... :


MIN(SAL)

--------

1300

800

950


اذن ثلاث قيم ....


Sal IN(1300 , 800 , 950)


من هم الذين رواتبهم تساوي 800 او 950 او 1300 ؟؟ سوف اعرض اسمائهم و رواتبهم وأرقام أقسامهم ...انهم :




ENAME SAL DEPTNO

---------- ---------- ----------

MILLER 1300 10

SMITH 800 20

JAMES 950 30






هل لاحظت ان معنى IN أي (تساوي القيمة الاولى .. او القيمة الثانية .. او ..... )

هل لاحظت انها "أو" ؟؟؟

سهلة ان شاء الله .... ونعرف الان IN متى تستخدم صح ؟؟

الان اريد ان اذكرك بشيء من قبل ....

اعرض لي اسماء ورواتب واقسام الموظفين ذوي الرواتب الاقل !!

لو كتبنا الحل التالي فهو خطأ :





SQL> select min(sal) , ename from emp group by deptno ;



ERROR at line 1:

ORA-00979: not a GROUP BY expression




لماذا خطأ ؟؟ لان به عمود لم يذكر في جملة group by


العمود هو ename


ولا نستطيع ادخاله في جملة الاستعلام .... ما هو الحل ؟

لقد حللناها قبل قليل ^^ !! انها الاستعلامات الفرعية ...

للتذكير اليك الجملة التي حلت لنا المشكلة :





SQL> select ename , sal , deptno from emp

where sal IN( select min(sal) from emp group by deptno );



ENAME SAL DEPTNO

---------- ---------- ----------

MILLER 1300 10

SMITH 800 20

JAMES 950 30






رائع يا استعلام يا فرعي .. رائع !

حلال مشاكل درجة اولى .





الان استخدمنا IN


بقي علينا ALL , ANY

Any تعني "أي من"


All تعني "كل "





هذان الاثنين يستخدمان المقارنة !! يستخدمان = , > , < , <> ........

مفيدان كثيرا !

يجب ان تعلم ان استخدام IN , ALL , ANY مفيدة جدا في المقارنات الكثيرة ايضا ..

هل تذكر هذا المثال :








SQL> select ename from emp where sal IN(1000,2000,3000) ;



ENAME

----------

SCOTT

FORD




الان نستخدمها مع الاستعلامات الفرعية , وهذا رائع .

الان معنى ALL أي كل القيم ...

معنى sal>ALL(1000,2000,3000)


أي ان الراتب اكبر من 1000 و اكبر من 2000 و اكبر من 3000

أي ان ALL تستخدم الـ "و"

وسوف تعرض كل من راتبه اكبر من 3000 ... بالمنطق !!




Sal < ANY(1000 , 2000 , 3000 )


أي ان الراتب اصغر من 1000 أو اصغر من 2000 او اصغر من 3000

طبعا سوف يعرض كل من يملك راتب اصغر من 1000 دولار

The Coder
15-02-2006, 06:09 AM
اليك امثلة على ALL , ANY


وشاهد الفرق بينهما وبين IN بامثلة بسيطة ... ثم بامثلة الجمل الفرعية ... :





SQL> select ename , sal from emp where sal >= ALL (1000 , 2000 , 3000 ) ;



ENAME SAL

---------- ----------

SCOTT 3000

KING 5000

FORD 3000



SQL> select ename , sal from emp where sal <= ALL (1000 , 2000 , 3000 ) ;



ENAME SAL

---------- ----------

SMITH 800

JAMES 950



SQL> select ename , sal from emp where sal > ALL(1000 , 2000 , 3000 ) ;



ENAME SAL

---------- ----------

KING 5000



SQL> select ename , sal from emp where sal <ALL(1000 , 2000 , 3000 ) ;



ENAME SAL

---------- ----------

SMITH 800

JAMES 950



SQL> select ename , sal from emp where sal =ALL(1000 , 2000 , 3000 ) ;



no rows selected



SQL> select ename , sal from emp where sal <>ALL(1000 , 2000 , 3000 ) ;



ENAME SAL

---------- ----------

SMITH 800

ALLEN 1600

WARD 1250

JONES 2975

MARTIN 1250

BLAKE 2850

CLARK 2450

KING 5000

TURNER 1500

ADAMS 1100

JAMES 950



ENAME SAL

---------- ----------

MILLER 1300



12 rows selected.




الان اذهب وجرب نفس السابقة ولكن بـ ANY


جرب .... لمدة ثلاث دقائق ونصف !

اليك بعض الامثلة على الاستعلامات الفرعية ذوات الصفوف المتعددة :

اعرض كل من راتبه اكبر من او يساوي جميع (لاحظ كلمة جميع) معدل الرواتب لكل قسم ....










SQL> select ename , sal from emp where sal >= ANY (select AVG(sal) from emp group by deptno ) ;



ENAME SAL

---------- ----------

ALLEN 1600

JONES 2975

BLAKE 2850

CLARK 2450

SCOTT 3000

KING 5000

FORD 3000




لماذا هؤلاء ؟؟؟ لان الاستعلام الفرعي اوجد النتيجة التالية :








SQL> select AVG(sal) from emp group by deptno;



AVG(SAL)

----------

2916.66667

2175

1566.66667




من هم رواتبهم اكبر من او تساوي كل القيم التالية (2175 , 2916.66667 , 1566.66667)

وسوف يبحث عنهم صف صف , اذا كان راتبه اكبر من او يساوي 2175 و اكبر من او يساوي 2916.66667 و اكبر من او يساوي 1566.66667

فاعرضه !!

الان فكر كيف يبدأ الأوراكل تتبع كل الصفوف , ويرى الرواتب في كل صف ....

مثلا يرى الصف الاول .. به الراتب X ويقارنه .. اذا نجحت المقارنة وصارت صحيحة .. يعرضه .. واذا لم تنجح لا يعرضه .. ثم يذهب الى الصف الاخر ... وهكذا

ارجو انك بدأت تفهم كيف يتحرك الأوراكل ! وكيف يقارن ! وكيف يعرض , اتمنى ذلك

لو لم تعرف بعد هذه التحركات , اعرض علينا مشكلتك .





وبقي عليك ان تعرف ان الاستعلامات الفرعية تستخدم جداول اخرى !!

مثلا ..

اريد ان اعرض اسماء الاشخاص الذين في قسم الموجود في مدينة النيويورك !!

كيف اعرف ؟؟

من جدول dept طبعا .. انظر جمال الجملة الاستعلامية الفرعية :








SQL> select ename from emp where deptno=(select deptno from dept where loc='NEW YORK');



ENAME

----------

CLARK

KING

MILLER




هل شاهدت ؟ هل دققت ؟؟

ربط الجدولين !!

انظر مالذي حدث :





SQL> select ename from emp where deptno=(select deptno from dept where loc='NEW YORK');




الاستعلام الفرعي اولا ...


select ename from emp where deptno =(10);




وبكل سهولة :




ENAME

----------

CLARK

KING

MILLER







رائع ....

حتى الجداول ربطت بشكل فني !!





هل انتهينا من المشاكل ؟ لا لا لا .... لم ننتهي , سنحلها كلها

اليك مشكلة من العيار الثقيل , والتي يصعب فهمها قليلا ....





- الاستعلامات الفرعية ذوات الاعمدة المتعددة :


اريد عرض من اسمه و راتبه يساويان القيمة هذه ('SCOTT' , 3000 )


هل فهمت المسئلة ؟ كأنني اقول .. اعرض كل من اسمه = اسكوت , وراتبه = 3000

لاحظ انها "و" وليست "او"

الان اليك بعض الامثلة لكي يرسخ المفهوم جيدا :

The Coder
15-02-2006, 06:13 AM
SQL> select ename , sal from emp where (ename,sal) = ( ('SCOTT',3000) );



ENAME SAL

---------- ----------

SCOTT 3000




لماذا النتيجة ؟ لانه فعلا يوجد من هو اسمه اسكوت .... و ..... راتبه يساوي 3000

لاحظ انه يجب ان يكون قوسين لسبب ما , ليس مهم السبب ولكن من الخطأ وضع قوس واحد واغلاقه في أوراكل .

هل لاحظت ان ما بين الاقواس صف واحد وانه يوجد عمودين ؟؟

الان .... انظر مايلي :








SQL> select ename , sal from emp where (ename,sal) =( ('SCOTT',1000) ) ;



no rows selected




لم يعرض احد ... صحيح انه يوجد موظف يدعى بـ اسكوت !! ولكن راتبه يساوي 3000

الشرط هنا كأنه يقول ... اسمه اسكوت ..... و ..... راتبه 1000

انظر مايلي :





SQL> select ename , sal from emp where (ename,sal) IN ( ('SCOTT',3000) );



ENAME SAL

---------- ----------

SCOTT 3000






نفس المثال السابق ولكن وضعنا IN


و IN هذه تتعامل مع المتعددة الصفوف .... وهذه الجملة الصغيرة ('SCOTT',3000) ليست الا صف واحد

هيا لنجرب مجموعة صفوف مع IN , ومجموعة اعمدة








SQL> select ename , sal from emp

where (ename,sal) IN ( ('SCOTT',1000) , ('KING',5000) , ('JONES',2975) );



ENAME SAL

---------- ----------

JONES 2975

KING 5000







سهلة الفكرة المبدئية , ولاحظ تركيب الصفوف المتعددة , كم صف يوجد ؟؟؟

ثلاث صفوف ... وكم عمود يوجد ؟؟ عمودين ؟؟

متخيل الوضع ؟؟؟ يقول اعرض لي كل من اسمه وراتبه تساوي احد القيم التالية

(اسكوت , 3000) , (كنق,5000) , (اسكوت,1000)

طيب .... الان انظر كيف يكون ثلاث صفوف وثلاث اعمدة .... :








SQL> select ename , sal from emp

2 where (ename , sal , deptno) IN ( ('SCOTT',3000,20) , ('KING',5000,10) ) ;



ENAME SAL

---------- ----------

SCOTT 3000

KING 5000




ارجو انك تلاحظ الترتيب , اسم ثم راتب ثم رقم قسم !! , وان تلاحظ اننا استخدمنا IN ونستطيع استخدام ALL , ANY , ولا نستطيع استخدام المقارنة العادية لانه اكثر من صف ! لانه ... اكثر ..... من .... صف

اعتقد انك فهمت الان .... وتفهم لماذا عرضت النتيجة السابقة !

الان اريدك ان ترى كيف نستخدم الاستعلام الفرعي مع الاعمدة المتعددة ... بسيطة جدا كطريقة , صعبة جدا كمفهوم








SQL> select ename , sal , deptno from emp

where (sal,ename) IN (select sal , ename from emp where deptno=20) ;



ENAME SAL DEPTNO

---------- ---------- ----------

SMITH 800 20

JONES 2975 20

SCOTT 3000 20

ADAMS 1100 20

FORD 3000 20

ME 1000 20

WARD 950 20




هل لاحظت التركيب الخاص بالاستعلام الفرعي ؟

طبعا المثال غبي كثيرا لأننا نحصل على نفس النتيجة بواسطة الاستعلام التالي :








SQL> select ename , sal , deptno from emp

where deptno=20 ;



ENAME SAL DEPTNO

---------- ---------- ----------

SMITH 800 20

JONES 2975 20

SCOTT 3000 20

ADAMS 1100 20

FORD 3000 20

ME 1000 20

WARD 950 20




لماذا اذن نستخدمه ؟

الان سوف اعرض عليك اهميتها !!

هل تتوقع ان لها تلك الاهمية ؟؟ طبعا

انا كنت سأكتب لكم في هذا الدرس "انا شخصيا لا ارى انه مهم بالمرة ."


ولكن تفاجأت بأن هنالك نقطة نسيتها تماما !!

لذا استعد للتحدي , اريدك ان تكتشفها بنفسك , وانا ان شاء الله اساعدك واذا لم تعرف ... سوف اعلمك ^^

اريدك ان تضيف هذه الصفوف كما هي :





insert into emp values (8888,'JAVA','SALESMAN',7698,sysdate,1250,0,10);










insert into emp values (8889,'WARD','MANAGER',7698,sysdate,2800,0,20);










insert into emp values (8890,'ANY','SALESMAN',7698,sysdate,2800,0,20);







التحدي الاول :

الان لاحظ معي جيدا لصياغة المسئلة !!

مثلا .. اريد ان اعرض كل من لهم راتب يساوي راتب أي موظف يدعى WARD


ومهنتهم تساوي مهنة أي موظف يدعى WARD




والمسئلة الثانية

.. اريد ان اعرض كل من لهم راتب يساوي راتب الموظف WARD


ومهنتهم تساوي مهنة الموظف WARD




متشابهة جدا !! لا عليك من اللغويات هذه ... ولا اريد تعقيدك بها .

لكن افهم مالذي اطلبه في المسئلة الاولى والمسئلة الثانية

طبعا يجب ان ترى الجـــــــوابـيـــن !! :








SQL> select * from emp

where sal IN (select sal from emp where ename='WARD')

and job IN (select job from emp where ename='WARD') ;



EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

---------- ---------- --------- ---------- -------- ---------- ---------- ----------

8890 ANY SALESMAN 7698 14/02/06 2800 0 20

7521 WARD SALESMAN 7698 22/02/81 1250 500 30

7654 MARTIN SALESMAN 7698 28/09/81 1250 1400 30

8888 JAVA SALESMAN 7698 14/02/06 1250 0 10

8889 WARD MANAGER 7698 14/02/06 2800 0 20










SQL> select * from emp

where (job,sal) IN (select job , sal from emp where ename='WARD') ;



EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

---------- ---------- --------- ---------- -------- ---------- ---------- ----------

8888 JAVA SALESMAN 7698 14/02/06 1250 0 10

7654 MARTIN SALESMAN 7698 28/09/81 1250 1400 30

7521 WARD SALESMAN 7698 22/02/81 1250 500 30

8889 WARD MANAGER 7698 14/02/06 2800 0 20




واو ..... متشابهتين في المنطق , مختلفتين في النتائج !!

هيا .. تحرك وافتح ملف الـ WORD واكتب لي شرحك الخاص بك ... لماذا ظهرت هذه النتيجتين المختلفتين !!

وهل صحيح ان الجملتين متشابهتين منطقيا ؟ ولماذا؟

لماذا ظهر الموظف ANY في النتيجة الاولى ولم يظهر في النتيجة الثانية ؟؟

تحدي لا بأس به .... ولكنه مهم جدا !

اذا فهمت وحللت التحدي , فأنت فعلا عبقري .

The Coder
15-02-2006, 06:16 AM
طبعا عرضت النتيجة لكل من اسمه WARD


انا لا اريد أي موظف يدعى بـWARD يظهر في الشاشة !!

بسيطة .... اليك الجملة :








SQL> select * from emp

where (job,sal) IN (select job , sal from emp where ename='WARD')

and ename <> 'WARD';



EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

---------- ---------- --------- ---------- -------- ---------- ---------- ----------

8888 JAVA SALESMAN 7698 14/02/06 1250 0 10

7654 MARTIN SALESMAN 7698 28/09/81 1250 1400 30




والاخرى مثلها ! .








SQL> select * from emp

where sal IN (select sal from emp where ename='WARD')

and job IN (select job from emp where ename='WARD')

and ename <> 'WARD';



EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

---------- ---------- --------- ---------- -------- ---------- ---------- ----------

8890 ANY SALESMAN 7698 14/02/06 2800 0 20

7654 MARTIN SALESMAN 7698 28/09/81 1250 1400 30

8888 JAVA SALESMAN 7698 14/02/06 1250 0 10




الان انتهينا من الاستعلامات الفرعية المتعددة الاعمدة !! واريد ان اسمع منك التحدي الاول , لانه اهم جزء من الاستعلامات الفرعية المتعددة الاعمدة والتي لم اشرحها انا .

بقي عليك ان تعرف أين تستطيع ان تجد الاستعلامات الفرعية !


فتش عنها ... ستجدها وراء جملة where


ستجدها خلف جملة having


ستكتشف انها بعد جملة from


ستفاجأ بوجودها ايضا في جملة select نفسها !!

تخيل !! ,, حتى جمل الادخال والتعديل والحذف ايضا .. ستجدها هنالك !! ولا ننسى إنشاء الجداول !!


انظر الامثلة عن اماكن وجودها :









SQL> select *

from (select ename , sal , deptno , job from emp where deptno=20) ;



ENAME SAL DEPTNO JOB

---------- ---------- ---------- ---------

SMITH 800 20 CLERK

JONES 2975 20 MANAGER

SCOTT 3000 20 ANALYST

ADAMS 1100 20 CLERK

FORD 3000 20 ANALYST

ME 1000 20 SALESMAN

WARD 950 20 CLERK




مالذي يحدث هنا !

الم نقل العلامة * ؟؟ الا نتوقع جميع الحقول ؟؟

في الحقيقة الجملة الفرعية تعامل مثل جدول مستقل في هذا الموضع !

وهذا الجدول شكله هكذا :








SQL> select ename , sal , deptno , job from emp where deptno=20 ;



ENAME SAL DEPTNO JOB

---------- ---------- ---------- ---------

SMITH 800 20 CLERK

JONES 2975 20 MANAGER

SCOTT 3000 20 ANALYST

ADAMS 1100 20 CLERK

FORD 3000 20 ANALYST

ME 1000 20 SALESMAN

WARD 950 20 CLERK




ولما نقول له ... اعرض لنا كل حقولك يا جدول , فسوف يعرض الحقول التي يمتلكها فقط !!

هل فهمت ؟

طيب ... لنجرب ان نكتب عمود لا يوجد في هذا الاستعلام الفرعي , ويوجد في جدول emp !!







SQL> select hiredate from (select ename , sal , deptno , job from emp where deptno=20);



ERROR at line 1:

ORA-00904: "HIREDATE": invalid identifier




رفضه بتاتا , لماذا ؟ لانه لا يمت صلة بالجدول (الجدول هنا هو ناتج الاستعلام الفرعي)

طيب , انظر المثال التالي , غريب فعلا :








SQL> select (select sal from emp where ename ='KING') from dual ;



(SELECTSALFROMEMPWHEREENAME='KING')

-----------------------------------

5000




جملة الاستفسار الفرعية , كأنها عمود !


تعامل كعمود هنا ! ... لاحظ في جملة from كأنه جدول , وفي جملة select كأنه عمود !!

وطبعا يجب ان تحتوي جملة الاستفسار على صف واحد , وعمود واحد في هذا الموضع !!


انظر المثال التالي :





SQL> select (select ename from emp where sal =5000) as name ,

(select dname from dept where deptno =10) as dept_name from dual ;



NAME DEPT_NAME

---------- --------------

KING ACCOUNTING




لا تعليق !!





الان نرى في جملة الادخال , والحذف والتعديل , كيف تتمركز جمل الاستعلام الفرعية :

نعمل جدول جديد يسمى emp_temp , ولديه من الاعمدة اسم الموظف , رقم القسم , الراتب !

ونريد به المعلومات الخاصة بالموظفين في القسم 20 !! من جدول emp


انظر الى المثال , وركز في الاستعلام الفرعي ...





create table emp_temp

as(select ename as the_name , sal as salary , deptno from emp where deptno =20) ;







مارأيك الان فيما يلي :





select ename , sal , deptno from emp_temp;




وهو خطأ مئة بالمئة ! لماذا ؟؟ لأن العمودين sal , ename غير موجودين !!

لماذا ؟ لأننا اسمينا العمودين باسماء اخرى في جملة الاستعلام الفرعية , وارجعت هذه الجملة الفرعية الى جملة إنشاء الجداول اسماء الاعمدة الجديدة !!

انظر :





SQL> select * from emp_temp ;



THE_NAME SALARY DEPTNO

---------- ---------- ----------

SMITH 800 20

JONES 2975 20

SCOTT 3000 20

ADAMS 1100 20

FORD 3000 20

ME 1000 20

WARD 950 20




هل شاهدت الاعمدة ؟؟؟

الان اريد إضافة معلومات الموظفين في القسم 10 والموجودين في جدول الموظفين emp


طبعا نذهب هناك , ونستعلم , ونعرف معلوماتهم , وننسخها يدويا !!

لا لا .. بطريقة الاستعلامات الفرعية , الامر سريع بلمح البصر كما شاهدنا في إنشاء الجداول مع الاستعلامات الفرعية !

هيا انظر الى الاستعلام الفرعي مع جملة الادخال :








insert into emp_temp valuse (select ename , sal , deptno from emp where deptno=10);




والان انظر الجدول .. وبه معلومات كل الموظفين بقسمي 10 و 20

The Coder
15-02-2006, 06:18 AM
SQL> select * from emp_temp ;



THE_NAME SALARY DEPTNO

---------- ---------- ----------

SMITH 800 20

JONES 2975 20

SCOTT 3000 20

ADAMS 1100 20

FORD 3000 20

ME 1000 20

WARD 950 20

CLARK 2450 10

KING 5000 10

MILLER 1300 10

WARD 1000 10




في لمح البصر , أضفنا اربع صفوف , تخيل ان موظفي القسم 10 به ألف موظف , سوف يضافون وبسرعة الضوء .

للاسف ان التعديل محدود القوى , لأن طبيعته الحدودية ,, كيف ؟

يجب ان يكون الاستعلام الفرعي في التعديل , استعلام ذو صف واحد !!

مثلا نريد ان نعدل كل الموظفين في القسم 10 , مثل معلومات الموظف KING مثلا , والموجود في نفس الجدول !!

ولاحظ الاستعلام الفرعي يستخدم نفس الجدول في مثالنا





update emp_temp

set (the_name , salary , deptno )

= (select the_name , salary , deptno from emp_temp where the_name='KING')

where deptno=10;




اهم شيء في الاستعلام الفرعي في امثلتنا ان يطابق الاعمدة الموجودة به الاعمدة التي بالخارج

مثلا نقول في مثالنا السابق كتبنا في الاستعلام الرئيسي : the_name , salary , deptno


وفي الاستعلام الفرعي ... كتبنا بنفس الترتيب اعمدة مطابقة يعني ماذا مطابقة ؟ يعني نفس النوعية , ونفس الحجم !!

حتى لو عمودين مختلفين !!ومن جدولين مختلفين !!

اهم شيء اذا كان رقم وحده مثلا خانتين ... يجب ان يكون هناك رقم وحده خانتين ...

وهكذا !! ...... هل فهمت الفكرة الرئيسية ؟؟

رائع الان نرى التعديل :








SQL> select * from emp_temp;



THE_NAME SALARY DEPTNO

---------- ---------- ----------

SMITH 800 20

JONES 2975 20

SCOTT 3000 20

ADAMS 1100 20

FORD 3000 20

ME 1000 20

WARD 950 20

KING 5000 10

KING 5000 10

KING 5000 10

KING 5000 10




وكل ما يجب ان تعرفه في جملة التعديل ... يجب ان يكون ذو صف واحد مفهوم ؟ لماذا ؟ فكر انت !! هذا تحدي !!

التحدي يقول .... لماذا في جملة التعديل يجب ان يكون الاستعلام الفرعي .... ذو صف واحد ؟؟


يظهر ان تحديات اليوم , كلها تفسيرات !! اسف جدا , ولكن هذا الموجود .

الان الحذف , واعتقد انه الان بسيط جدا , سنحذف كل من هم في القسم الذي يدعى بقسم المحاسبة :








delete emp_temp

where deptno=(select deptno from dept where dname='ACCOUNTING');







بقي مكان اخير للاستفسارات الفرعية لم ادقق لك فيه , و لن أقوله الان .....





- ربط الجداول :


اولا اريد ان احدثك بشيء يدعى "بالتقارير" !! Reports احفظ الكلمة جيدا ...

هذه التقارير هي مجرد جداول ... بها اعمدة وتأتي اما على ورق او على الشاشة !!

مافائدة التقارير ؟ اذا لم نستفد من فائدة التقارير .. فنحن لم نستفد من قواعد البيانات وانشائها اصلا ..

فهي التي تجعلنا نخطط ونتخذ القرارات الصحيحة ,,,راجع الدرس الخامس ....

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

حينما نعمل جملة استعلام , فنحن ننشئ تقرير على الشاشة ..

لاحظ ان معظم تقاريرنا ان لم نقل كلها .. من جدول واحد .... أي انه لا يوجد لدينا اعمدة من جدول ما , واعمدة من جدول اخر في نفس جملة الاستعلام , صح ؟ وهذا ما تعودناه ...

من العنوان .. فإنه يوجد طريقة لربط الجداول مع بعضها ....

ارى ان الربط في المناهج سيء للغاية , وغير معقد !! لذا سوف اخترع بعض التعقيدات اللازمة التي تجعلك تترك هذا الدرس أو ان تتمتع به .

الان ... اريد عرض اسماء الموظفين , واسماء الأقسام التي هم فيها كيف ؟

بسيطة ... ننظر الى جدول dept ثم الى جدول emp ثم نعرف ...

ولكن صعبة اذا كانت البيانات ضخمة صح ؟

هيا لتتعلم الربط ..

انواع الربط :

1- الربط بالتساوي Equijoin


2- الربط بعدم التساوي Non-Equijoin


3- الربط الخارجي Outer join


4- الربط الداخلي Inner join


افففف ... تسميات وحفظ و طفش .....




هل حفظتها جيدا عن ظهر قلب ؟؟ على فكرة .. كانو يقولون ان جملة العرب "حفظ عن ظهر قلب" خاطئة جدا

وان الحفظ مركزه الدماغ ,, وهذا ما نعرفه في العلم حديث ...

اتضح مؤخرا ان في القلب عقل , وانه المسئول عن الحفظ وعن العقل الباطن !! حينما تحضر احدهم الوفاة , فان اتصاله مع عقله ينقطع , فتجده متصل مع قلبه , اذا كان ممن يقرؤون القران فسوف تجده يقرأه وهو يحتضر , وان كان من الضالين , فستجده في ضلالته ..... اللهم ثبت قلوبنا على الإيمان , وزينه لنا يا رب ...





1- الربط بالتساوي Equijoin


مجرد ربط جدولين مختلفين عن طريق تساوي عمود من الجدول الاول , مع عمود من الجدول الاخر !!

اكرر تساوي .... عمودين .... متشابهين في المظهر .... يعني ايش متشابهين ؟ يعني اذا كان الاول رقمي و عدد خاناته 10 ... الاخر مثله تماما .

مثال بسيط جدا عليه ؟؟؟

اريد ان اعرض اسماء الموظفين واسماء الأقسام ... انتبه لم اقل ارقام ... بل اسماء الأقسام التي يعملون بها في تقرير واحد ....

هيا لنعمل ذلك :





select emp.ename , dept.dname

from emp , dept

where emp.deptno=dept.deptno ;




بسيطة هاه ... ومألوفة لدينا ,,,

انظر العمود الاول ... emp.ename


يعني بالعقل ما معناها ؟ يعني احضر العمود الذي اسمه ename من الجدول الذي يدعى emp


هذا معناه !

الان العمود الثاني يدعى dept.dname


نفس المفهوم ... احضر العمود dname من الجدول dept كعمود في تقريرنا هذا ....

انظر الى جملةfrom , ستجد الجدولين مذكورين هنا ... وهذه هي الفكرة ...

فإننا نقول للاوراكل .. هيا واحضر العمود dname ثم احضر العمود الذي اسمه ename من الجدولين emp و dept


حتى هنا مفهوم .... وسوف اعمل نفسي انني لم الاحظ السطر الاخير من الجملة ....

انظر الى النتيجة :





ENAME DNAME

---------- ------------

CLARK ACCOUNTING

KING ACCOUNTING

MILLER ACCOUNTING

SMITH RESEARCH

ADAMS RESEARCH

FORD RESEARCH

SCOTT RESEARCH

JONES RESEARCH

ALLEN SALES

BLAKE SALES

MARTIN SALES

JAMES SALES

TURNER SALES

WARD SALES




هل تشاهد جمال النتيجة ؟

هل تشاهد هذا المنظر ؟؟؟

وهذه من اروع جمل الاستفسارات نتيجة ... ولكن ..... اغلاها ثمنا ....

انظر الى السطر الاخير ... غريب جدا ....





where emp.deptno=dept.deptno ;




ما شأن هذان العمودين في التقرير ؟؟ لم يعرضا اصلا !! فلماذا استخدمناهما ؟؟

هراء .... هيا لنحذف الجملة كلها ...







select emp.ename , dept.dname

from emp , dept ;

The Coder
15-02-2006, 06:23 AM
ENAME DNAME

---------- -------------

SMITH ACCOUNTING

ALLEN ACCOUNTING

WARD ACCOUNTING

JONES ACCOUNTING

MARTIN ACCOUNTING

BLAKE ACCOUNTING

CLARK ACCOUNTING

SCOTT ACCOUNTING

KING ACCOUNTING

TURNER ACCOUNTING

ADAMS ACCOUNTING

JAMES ACCOUNTING

FORD ACCOUNTING

MILLER ACCOUNTING

SMITH RESEARCH

ALLEN RESEARCH

WARD RESEARCH

JONES RESEARCH

MARTIN RESEARCH

BLAKE RESEARCH

CLARK RESEARCH

SCOTT RESEARCH

KING RESEARCH

TURNER RESEARCH

ADAMS RESEARCH

JAMES RESEARCH

FORD RESEARCH

MILLER RESEARCH

SMITH SALES

ALLEN SALES

WARD SALES

JONES SALES

MARTIN SALES

BLAKE SALES

CLARK SALES

SCOTT SALES

KING SALES

TURNER SALES

ADAMS SALES

JAMES SALES

FORD SALES

MILLER SALES

SMITH OPERATIONS

ALLEN OPERATIONS

WARD OPERATIONS

JONES OPERATIONS

MARTIN OPERATIONS

BLAKE OPERATIONS

CLARK OPERATIONS

SCOTT OPERATIONS

KING OPERATIONS

TURNER OPERATIONS

ADAMS OPERATIONS

JAMES OPERATIONS

FORD OPERATIONS

MILLER OPERATIONS



56 rows selected.




اعرف ان النتيجة كبيرة نوعا ما ..

ولكن وضعتها لكي تتفرج ... لاني كلي ثقة انك لن تجرب .. اذا لم اجرب انا

تفرج في عدد الصفوف .... فبدلا من 14 صف كعدد الموظفين المتوقع ...

طلع لنا 56 صف ...

كيف فين ليه ليش Why How لماذا .... ؟؟؟؟

لماذا ظهرت هكذا ؟؟ ولماذا بالذات 56 صف ؟؟

اولا كم عدد الصفوف في جدول dept ؟؟ اربع صفوف

والان كم عدد الصفوف في emp ؟؟ 14 صف


4 * 14 = 56


كيف ؟

اريدك الان ان تعمل جدول خاص بموظفي القسم 10 فقط ...

مارأيك ؟








create table emp_10 as(select * from emp where deptno=10);




الان هذا الجدول به كم صف ؟ لنرى :





SQL> select * from emp_10;



EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

---------- ---------- --------- ---------- -------- --------- ---------- -------

7782 CLARK MANAGER 7839 09/06/81 2450 10

7839 KING PRESIDENT 17/11/81 5000 10

7934 MILLER CLERK 7782 23/01/82 1300 10

7999 WARD SALESMAN 7689 13/02/06 1000 0 10




اربع صفوف ....

اريدك ان تعمل الثلاث التعديلات التالية :





SQL> update emp_10 set deptno=20

2 where ename='KING';



1 row updated.



SQL> update emp_10 set deptno=30

2 where ename='MILLER';



1 row updated.



SQL> update emp_10 set deptno=40

2 where ename='WARD';



1 row updated.




فقط عدلنا كل موظف لكل قسم ....

الان انظر الى الجدول بعد التعديل , لكل شخص قسم خاص ... (مجرد مثال)





SQL> select * from emp_10 ;



EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

---------- ---------- --------- ---------- -------- ---------- ---------- ----------

7782 CLARK MANAGER 7839 09/06/81 2450 10

7839 KING PRESIDENT 17/11/81 5000 20

7934 MILLER CLERK 7782 23/01/82 1300 30

7999 WARD SALESMAN 7689 13/02/06 1000 0 40






الان لنطبق الربط بالتساوي ... مع جدول dept ...


انا اسمي هذا الشرط ... "شرط الربط "... مفهوم ؟





SQL> select emp_10.ename , dept.dname

from emp_10 , dept

where emp_10.deptno=dept.deptno;



ENAME DNAME

---------- --------------

CLARK ACCOUNTING

KING RESEARCH

MILLER SALES

WARD OPERATIONS




عرضنا اسم الموظف واسم القسم الذي يعمل فيه ...


الان نكتب بدون "شرط الربط" ...







SQL> select emp_10.ename , dept.dname

2 from emp_10 , dept;



ENAME DNAME

---------- --------------

CLARK ACCOUNTING

KING ACCOUNTING

MILLER ACCOUNTING

WARD ACCOUNTING

CLARK RESEARCH

KING RESEARCH

MILLER RESEARCH

WARD RESEARCH

CLARK SALES

KING SALES

MILLER SALES

WARD SALES

CLARK OPERATIONS

KING OPERATIONS

MILLER OPERATIONS

WARD OPERATIONS



16 rows selected.




والنتيجة .. 16 صف .... ناتج ضرب 4 صفوف من جدول الموظفين الذي عملناه .. في 4 صفوف من جدول الأقسام





ماهي الفكرة ؟

The Coder
15-02-2006, 06:33 AM
انظر الصورة .... (الصورة 1200) وهي الصورة الخاصة بجملة الاستعلام بدون شرط الربط :


http://img6.picsplace.to/img6/14/1200.jpg


في الصورة ستجد علاقات متعددة ...

نحن قلنا ... (بدون شرط الربط)

"عزيزي أوراكل ... لو سمحت ... اعرض جميع اسماء الموظفين من جدول الموظفين ... و ... اعرض جميع اسماء الأقسام من جدول الأقسام ...لاحظ الترتيب يا أوراكل ... اولا اسماء الموظفين .. ثم اسماء الأقسام ..."

الأوراكل صحيح ذكي ويفهم !! .. ولكنه غبي لا يستنتج ....


- فيأتي ويرى الجدولين هل هما موجودين ... ثم يختار جدول الأقسام اولا .. لا اعرف لماذا ولكن انا شخصيا اعتقد انه يرى الجدول الاب ... أي الجدول الذي به المفتاح الرئيسي (deptno ) ثم يذهب الى الجدول الابن الذي به المفتاح الأجنبي (deptno) ...


- يذهب لأول صف من جدول الأقسام ... فيجده القسم ACCOUNTING

- فيقول في نفسه ... "مع أي موظف اضع هذا القسم؟ هل مع الموظف الاول ؟ الثاني ؟؟؟؟؟ لا لا .... سوف اضعه معهم جميعا "

- ويبدأ يقول ....


CLARK ACCOUNTING

KING ACCOUNTING

MILLER ACCOUNTING

WARD ACCOUNTING




"هكذا افضل ...

هيا الذي بعده ... "


- يذهب الى القسم الذي بعد ACCOUNTING ويجده RESEARCH


- بنفس الصورة ...


CLARK RESEARCH

KING RESEARCH

MILLER RESEARCH

WARD RESEARCH


وهكذا ... حتى تصير 16 صف ..

هذه الديناميكية التي يعمل بها الأوراكل ...





انظر الصورة .... (الصورة 1201) وهي الصورة الخاصة بجملة الاستعلام بشرط الربط :


http://img7.picsplace.to/img7/10/1201.jpg





سوف يجد شرط غريب ... الأوراكل لا يعرف طبعا لماذا وضعناه ..

وهو شرط الربط ... where emp_10.deptno = dept.deptno


- طبعا سوف يستعرض رقم القسم في جدول الموظفين

- ويستعرض رقم القسم في جدول الأقسام

- ويبدأ بجدول الأقسام ... (لانه على ما اظن الجدول الأب )

- سوف يرى اول صف .... ACCOUNTING ويقول .. "مع من اضعه من الموظفين ؟؟

اها .. يوجد شرط .. ماهو الشرط ؟؟

يجب ان يكون رقم الأقسام في جدول الأقسام يساوي رقم الأقسام في جدول الموظفين .. "

- ويبدأ يبحث عن كل الموظفين الذين رقم قسمهم يساوي رقم قسم ACCOUNTING


ورقم قسم ACCOUNTING يساوي 10

- يذهب .. ويفتش في جدول الموظفين عن أي موظف في القسم 10

- يجد احدهم ويدعى CLARK في القسم 10 ( deptno=10 في جدول الموظفين )


- يطابقهما ويعرض اول نتيجة في تقريرنا :


CLARK ACCOUNTING




ويبدأ هكذا حتى تصبح النتيجة ...


ACCOUNTING CLARK

RESEARCH KING

SALES MILLER

OPERATIONS WARD


اعتقد انك فهمت ....

مجرد احتمالات ... والسر في شرط الربط ...

وشرط الربط هذا .. هو الذي يخبر الأوراكل ان يعرض كل موظف بقسمه !! (الموظف صاحب رقم قسم = س مع القسم بنفس الرقم س ) , هذا كل شيء ...

هذا النوع بسيط وسهل , وهو الربط بالتساوي ....

هيا لنذهب الى النوع الاخر , شأنه اعظم .





2- الربط بعدم التساوي Non-Equijoin





قبل البدء ... يوجد جدول لم نستخدمه ... انظر شكله كيف ..








SQL> select * from salgrade ;



GRADE LOSAL HISAL

--------- ---------- ----------

1 700 1200

2 1201 1400

3 1401 2000

4 2001 3000

5 3001 9999




هذا الجدول , يبين ان الذي يقبض راتب ما بين 700 و 1200 فهو في الدرجة الاولى من سلم الرواتب ...

والذي يقبض راتب اكبر من 1200 و اصغر من 1401

فهو في الدرجة الثانية ...


والذي يقبض 9999 دولار في الشهر .. فهذا في درجة الخمس نجوم !!

اذا لم تجد الجدول عندك ... فأعمله الان وضع به هذه البيانات ...

الان يوجد سوال صعب قليلا .... بل كثيرا ....

اريد تقرير عن الموظفين , ودرجات رواتبهم .. اكرر ... درجات رواتبهم وليس رواتبهم ...








ENAME SAL GRADE

---------- ---------- ----------

SMITH 800 1

JAMES 950 1

WARD 950 1

ADAMS 1100 1

MARTIN 1250 2

MILLER 1300 2

TURNER 1500 3

ALLEN 1600 3

CLARK 2450 4

BLAKE 2850 4

JONES 2975 4

SCOTT 3000 4

FORD 3000 4

KING 5000 5




واو .. نتيجة مذهلة ...

اليك الحل ..

ولا شيء غير ان ترى الحل ...





select emp.ename , emp.sal , salgrade.grade

from emp , salgrade

where emp.sal >= salgrade.losal

and emp.sal <= salgrade.hisal ;




ندخل في شرط الربط مباشرة ..

يقول حينما يكون الراتب من جدول الموظفين .. اكبر من او يساوي (الراتب الاصغر في جدول درجات الرواتب)

ويكون اصغر من او يساوي (الراتب الاكبر في جدول درجات الرواتب)

صعبة قليلا على البعض ..

لكن ركز وامشي خطوة خطوة ..

سوف يأتي الى جدول درجات الرواتب ...


سوف يجد اول صف ... :


1 700 1200


ويبحث في صفوف جدول الموظفين ..

من الذي راتبه بين 700 و 1200 ؟؟

هل هو KING صاحب الراتب 5000 ؟؟ لا

هل هو WARD صاحب الراتب 950 ؟؟ نعم ..

اعرض WARD :


WARD 950 1


ثم يبحث في جميع الموظفين .. حتى تصبح النتيجة :


SMITH 800 1

JAMES 950 1

WARD 950 1

ADAMS 1100 1


انتهو ...

الان ينتقل الى الصف الثاني من جدول salgrade


يجده :


2 1201 1400


من من الموظفين ذو راتب بين 1201 و 1400 ؟؟

هل هو WARD ؟؟؟ (لاحظ انه غبي ...ولا يعرف ان WARD قد وضعناه من الدرجة الاولى .... صحيح انه غباء ولكن من الممكن ان يكون ذكاء ... ممكن يكون الصف الثاني نفس الصف الاول , وبالتالي سوف يضع WARD مرة اخرى .... )


لا ليس WARD ...


هل هو KING ؟؟ لا ليس KING


ويبدأ هكذا حتى ينتهي من جدول الموظفين ... ثم الصف الثالث من جدول درجات الرواتب .... حتى ينتهي منها جميعا ..

هل رأيت ان هذا النوع نفس فكرة النوع السابق من الربط ولكن ليس المساواة ؟؟؟

اشير الى اننا نستطيع ان نستخدم دالة BETWEEN كما يلي :





select emp.ename , salgrade.grade

from emp , salgrade

where emp.sal between salgrade.losal and salgrade.hisal;







بما اننا نملك جداول ضعيفة غير معقدة , فلا اعتقد انه يوجد على هذا النوع المزيد من الامثلة بهذه الجداول الغبية !!


فكر انت بجداول , وحالات اخرى ممكن ان تستخدم فيها هذا النوع من الربط ..

من الممكن ان يكون الربط بعلامة <> لا تساوي ... ويمكن ان تكون اصغر من فقط ... او ماشابه ... اهم شيء انه ليس يساوي .

The Coder
15-02-2006, 06:37 AM
3- الربط الخارجي Outer join








نرجع لجدولنا emp_10








وكلي رجاء انك لم تمسحه بعد ..

















هيا لنعدل معلومة به .. :












update emp_10 set deptno=null

where deptno=40 ;









فقط عدلنا كل من هو في القسم 40 ونضعه في القسم 30 ... انظر الى الجدول الان :




















SQL> select * from emp_10;







EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO



---------- ---------- --------- ---------- -------- ---------- ---------- ----------



7782 CLARK MANAGER 7839 09/06/81 2450 10



7839 KING PRESIDENT 17/11/81 5000 20



7934 MILLER CLERK 7782 23/01/82 1300 30



7999 WARD SALESMAN 7689 13/02/06 1000 0








والان سوف نعرض اسماء الموظفين مع اسماء الأقسام التي يعملون فيها ..




















SQL> select emp_10.ename , dept.dname from emp_10,dept



where emp_10.deptno=dept.deptno;







ENAME DNAME



---------- ---------



CLARK ACCOUNTING



KING RESEARCH



MILLER SALES








مالجديد ؟


مع شرط الربط ... يوجد قسم ليس متصلا مع احد الموظفين ..

بمعنى اخر .. يوجد صف ... لم يتلائم مع صف اخر .. على ضوء شرط الربط ..

بمعنى ثالث .. القسم رقم 40 .. لا يوجد به موظف يعمل عليه ..

وايضا الموظف WARD لا يعمل تحت أي قسم !!
















هذا مجرد صف واحد من الأقسام .. وصف واحد من الموظفين ... تخيل اريد ان اعرضهما ؟؟ وهذه هي فكرة الربط الخارجي ..


وهي ان نضع صفوف ليس لها علاقة بشرط الربط ...







مثلا ... اريد هذه النتيجة :












ENAME DNAME

---------- -----------

CLARK ACCOUNTING

KING RESEARCH

MILLER SALES

OPERATIONS









ارجو ان تتضح الفكرة ... الفكرة ان يتم عرض الصفوف التي لم تظهر في العلاقة ...وسؤال الناتج السابق ..








اعرض لي اسماء الأقسام جميعها ... واسماء الموظفين الذين يعملون بها ... إن وجد موظفين !!










سوال اخر ..


اعرض لي اسماء الموظفين جميعهم ... مع اسماء اقسامهم .. ان وجدت !!

هذا ناتجه :











ENAME DNAME

---------- ----------

CLARK ACCOUNTING

KING RESEARCH

MILLER SALES

WARD









هل فهمت الفكرة ؟


انظر الى الصورة 1203







http://img4.picsplace.to/img4/20/1203.jpg










الان لكي نعرض اسماء الأقسام جميعها وأسماء الموظفين ان وجدوا ... هذا هو الحل ...




















SQL> select emp_10.ename , dept.dname from emp_10,dept



where emp_10.deptno(+)=dept.deptno;







ENAME DNAME



---------- --------------



CLARK ACCOUNTING



KING RESEARCH



MILLER SALES



OPERATIONS








وضعنا العلامة (+) في شرط الربط ؟؟؟


واين وضعناها ؟؟؟... في emp_10.deptno(+) !!







لو وضعناها في الجهة المقابلة .. فسوف نحل السوال الثاني والذي ينص ..


"اعرض لي كل الموظفين واقسامهم ان وجدت اصلا اقسام "



















SQL> select emp_10.ename , dept.dname from emp_10,dept



where emp_10.deptno=dept.deptno(+);







ENAME DNAME



---------- --------------



CLARK ACCOUNTING



KING RESEARCH



MILLER SALES



WARD








أين نضع علامة الزائد ؟؟


ومتى نضع هذه العلامة ؟؟

اذا قلنا ... "اعرض كل الموظفين واسماء اقسامهم ان وجدت"

أي عرض الموظفين جميعهم ... واقسامهم ... سواء كانو يعملون في قسم ... ما او لا ..

اذا لا .. اعرض اسم الموظف واعرض قيمة خالية في عموده ..

في هذه الحالة نضع علامة الزائد عند العمود الذي نتوقع ان يكون خالي .. أي انه زيادة ...

أي نضعه هنا في مثالنا عند dept.deptno لاننا نتوقع هذا العمود ان يصبح خاليا ..

ووو ....... ممممم .....

حاول ان تفهم بطريقتك ..... او حتى احفظها كما هي .
















4- الربط الداخلي Inner join








لا تنزعج من التسميات ..


الربط الداخلي هو ربط الجدول مع نفسه ...

اريدك ان تنتبه لشيء مهم !!

هل تذكر العلاقات ؟؟

علاقات الجداول .... هل نسيتها ؟؟؟







......








اذا لم تزل تذكرها .. مارأيك بعلاقة الجدول بنفسه ؟


مثلا جدول الموظفين ...

يوجد علاقة الادارة ...

فالموظف الواحد من الممكن ان يدير مجموعة موظفين ..

وان الموظف الواحد .. يدار من قبل موظف واحد (يدار من قبل مدير واحد)

أي العلاقة واحد الى متعدد ..

اي اننا يمكننا ان نشاهد جدولين في جدول واحد ..

جدول المدراء ... وجدول الموظفين .... انظر :





















SQL> select * from emp



2 where job='MANAGER';







EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO



---------- ---------- --------- ---------- -------- ------- ---------- ------



7566 JONES MANAGER 7839 02/04/81 2975 20



7698 BLAKE MANAGER 7839 01/05/81 2850 30



7782 CLARK MANAGER 7839 09/06/81 2450 10







SQL> select * from emp



2 where job <> 'MANAGER';







EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO



---------- ---------- --------- ------ ---------- ----- ------- --------



7369 SMITH CLERK 7902 17/12/80 800 20



7499 ALLEN SALESMAN 7698 20/02/81 1600 300 30



7521 WARD SALESMAN 7698 22/02/81 1250 500 30



7654 MARTIN SALESMAN 7698 28/09/81 1250 1400 30



7788 SCOTT ANALYST 7566 19/04/87 3000 20



7839 KING PRESIDENT 17/11/81 5000 10



7844 TURNER SALESMAN 7698 08/09/81 1500 0 30



7876 ADAMS CLERK 7788 23/05/87 1100 20



7900 JAMES CLERK 7698 03/12/81 950 30



7902 FORD ANALYST 7566 03/12/81 3000 20



7934 MILLER CLERK 7782 23/01/82 1300 10








تجاهل الموظف KING .... لانه لا يوجد علاقة رئاسة, ولو وجدت فإن له جدول خاص .. ونسميه مثلا جدول الرؤساء ... لأنه الرئيس .. مدير المدراء !! أي اننا نشاهد ثلاث جداول في جدول واحد !


الان ... المفتاح الأجنبي في جدول الموظفين والذي هو مفتاح رئيسي في جدول المدراء .. ماهو ؟

انه mgr , كمفتاح أجنبي ... وهو المفتاح الرئيسي في جدول المدراء ..

وايضا mgr في جدول المدراء مفتاح أجنبي في جدول الرؤساء !!

هل لاحظت ذلك ؟

وضعنا كل الجداول هذه في جدول واحد لتشابه الصفات !! اكرر لتشابه الصفات

ولأنهم كيان واحد ... ولأنهم جميعا موظفين ...

ولا يجوز الفصل بينهم .. الا اذا كان هنالك حقول في جدول المدراء مثلا ... ليست موجودة في جدول الموظفين ...

هل فهمت الوضع ؟ فكر وانت ترى بعض الجداول ..

فكر وانت تريد ان تصمم قواعد البيانات ... فكر في ان تكون الكيانات المتطابقة تماما .. كيان واحد ..

الان جدول الموظفين به المدراء والرؤساء , وضربنا علاقة بين جدول الموظفين مع نفسه ... وهي علاقة الادارة ..

وتوجد علاقة اخرى الرئاسة !!

يوجد بعض التعقيد للبعض ... ولكن .. انظر الى الربط الداخلي والذي يربط الجدول بنفسه ..

اسمع اسمع السوال .... نريد عرض اسماء الموظفين ... واسماء مدرائهم !! في تقرير واحد !!

قبل ان ابدأ بالحل ..

اريد ان اعلمك انه يوجد بعض الامور والتي تعمدت تجاهلها ....

تخيل انه لديك جدول اسمه .... ABCDEFGHIJKLMNOPQRSTUVWXYZ







وبه عمود ... وليكن اسمه col








كيف يتم كتابته في جملة الاستعلام التي بها شرط الربط ؟؟


سيكتب هكذا .. ABCDEFGHIJKLMNOPQRSTUVWXYZ.col







أي اسم الجدول , ثم العمود .. صح ؟؟


اريد ان اختصر اسم الجدول ... لكي يسهل علي كتابة وقرائة جملة الاستعلام !!

انظر الى المثال فبدلا ان نقول :



















select emp.ename , dept.dname



from emp , dept



where emp.deptno=dept.deptno;








نقول ما يلي .. نسمي جدول الموظفين بـ e وجدول الأقسام بـ d مثلا .. :




















select e.ename ,d.dname



from emp e , dept d



where e.deptno = d.deptno;












هل فهمت الفكرة !! ... انظر جيدا .... ولاحظ أين وضعنا التسميات .. في جملة from ...








واستخدمناها عادي جدا !!










الان نرجع الى الربط الداخلي ...


مارأيك ان يكون جدول المدراء اسمه m وجدول الموظفين .. اسمه w ؟

لنرى ذلك ...











select w.ename , m.ename

from emp m, emp w

where w.mgr =m.empno;









هل رأيت بعض التعقيد ؟

The Coder
15-02-2006, 06:44 AM
شرط الربط غريب جدا !!

الان ركز .... جدول الموظفين قسمه في خيالك الى قسمين ...

جدول موظفين عاملين Worker وجدول للمدراء Manager


نسمي جدول العاملين بـ w


ونسمي جدول المدراء بـ m


الان ... انظر الى شرط الربط ...

اعرض كل من .... رقم مديره من جدول العمال .... يساوي ..... رقم الموظف من جدول المدراء !!

لم تفهم ؟ طيب

المفتاح الأجنبي للعلاقة مابين العاملين والمدراء ماهو ؟؟ انه الـ mgr


صحيح تسميته تختلف عن empno , ولكنه مطابق للمواصفات !

أي ان mgr مفتاح أجنبي في جدول الموظفين ..

وان مفتاحه الرئيسي هو deptno في جدول الموظفين نفسه !!

اعرف ان رأسك يدور الان عكس عقارب الساعة , ولكن .. قارن بين هذه الحالة مع حالة عرض اسماء الموظفين واسماء الأقسام ... ستجدها نفس الفكرة ... نفس المفهوم ... صدقني ....

اليك ما سوف يعرض ....





ENAME ENAME

---------- ------

FORD JONES

SCOTT JONES

JAMES BLAKE

TURNER BLAKE

MARTIN BLAKE

WARD BLAKE

ALLEN BLAKE

MILLER CLARK

ADAMS SCOTT

CLARK KING

BLAKE KING

JONES KING

SMITH FORD




الان تخيل انني اريد ان اعرض تقرير ...

التقرير هذا ... يحتوي على ...

اسم الموظف .. اسم مديره ... اسم القسم الذي يعمل به ...

سوف تلاحظ اننا سوف نضطر الى ربط ثلاث جداول !

اسم الموظف ... من جدول الموظفين ..

اسم القسم .. من جدول الأقسام

اسم المدير من نفس جدول الموظفين .. كرابط داخلي ...







select e.ename , m.ename , d.dname

from emp e , emp m , dept d

where e.mgr=m.empno

and e.deptno = d.deptno ;




واو .. بدأت تتشعب يا شعب !!

ثلاث جداول ...

ركز انه يوجد شرطين للربط ...

شرط الربط الاول .. لكي نعرض اسم الموظف و اسم مديره

والشرط الاخر لكي نعرض اسم الموظف واسم القسم !!

انتبه !! جرب لو حذفت الشرط الثاني ... هل تتوقع مالذي سوف يحدث ؟

مصائب , وسوف يتكون لدينا جميع الاحتمالات !!

الان ... لكي تفهم اكثر واكثر ....

اريد ان اعرض اسم الموظف .. واسم القسم الذي يعمل به ..

واريد ايضا ان اعرض في نفس التقرير اسم مديره , واسم قسم مديره !!

هو بالعقل طبعا قسم المدير نفس قسم الموظف الذي يدار بواسطة هذا المدير !! ولكن ليس كل الاحوال !!

ولكن ... تخيل ان الموظف في قسم .. وان مديره في قسم اخر .... فكر في الحل ...

انظر اليه :








select e.ename "EMP_NAME" , d.dname "HIS_DEPT" , m.ename "HIS_MANAG" , dm.dname "MANAG_DEPT"

from emp e,emp m , dept d, dept dm

where e.deptno = d.deptno

and e.mgr = m.empno

and m.deptno = dm.deptno ;








EMP_NAME HIS_DEPT HIS_MANAG MANAG_DEPT

---------- -------------- ---------- ----------

CLARK ACCOUNTING KING ACCOUNTING

JONES RESEARCH KING ACCOUNTING

BLAKE SALES KING ACCOUNTING

MILLER ACCOUNTING CLARK ACCOUNTING

SMITH RESEARCH FORD RESEARCH

ADAMS RESEARCH SCOTT RESEARCH

SCOTT RESEARCH JONES RESEARCH

FORD RESEARCH JONES RESEARCH

ALLEN SALES BLAKE SALES

JAMES SALES BLAKE SALES

TURNER SALES BLAKE SALES

MARTIN SALES BLAKE SALES

WARD SALES BLAKE SALES




اليك تحدي ... لا بأس به ..


اريد عرض تقرير به الاعمدة التالية :

اسم الموظف , اسم قسمه , درجة راتبه , اسم مديره , درجة راتب المدير





انتهى درس اليوم ...

في الدرس القادم ....

سوف اتعمق في بعض الامور الادارية , وبالتالي ننتهي من الـ SQL ان شاء الله .

The Coder
19-02-2006, 04:13 AM
بسم الله الرحمن الرحيم

الدرس الثالث عشر


اسم الدرس : جملة الاستعلام select والدوال


نوع الدرس : تطبيقي


صعوبة الدرس : **** من *****


اهميــة الدرس : ****** من ***** (Over)


درجة احتراف لغةSQL المتوقعة بعد هذا الدرس : ***** من ***** (خبير الا شعرة !!)


الوقت المتوقع منك لفهم الدرس : ثماني ساعات .


المتوقع منك في هذا الدرس :

- لتنتهي من شر الـ SQL





هيا لنؤركل ^^


السلام عليكم





سوف اطلعك اليوم ان شاء الله على بعض الامور البسيطة والتي ارى انه لا يوجد فيها أي تعقيد ...

ما رأيك ان نعرض من هم يملكون رواتب اكبر من معدل رواتب قسمهم ..

اولا ما هو معدل رواتب الأقسام ؟؟ اليك جملة مبسطة :










SQL> select avg(sal) , deptno

2 from emp

3 group by deptno ;



AVG(SAL) DEPTNO

---------- ----------

2916.66667 10

2175 20

1566.66667 30




عرفنا ما هي معدلات رواتب الأقسام ..

الان كيف نعرف اسماء الموظفين الذين يملكون رواتب اكبر من معدل رواتب قسمهم !!

اكرر معدل رواتب قسمهم هم .. يعني الموظف scott ما هو قسمه ؟؟ قسمه هو القسم 20 ... هو يأخذ راتب 3000 دولار .. هل راتبه اكبر من معدل رواتب قسمه ؟؟ نعم !! ... اذن اعرضه !!

قليلا صعبة وتحتاج لبعض التفكير ... لوكتبنا مثلا هذا الحل الغبي ... :







select avg(sal) , deptno ,ename

from emp

where sal > avg(sal)

group by deptno ;






فهذا خطأ !! .... لانه يوجد دالة متعددة الصفوف .... وقد درسناها سابقا .

حللنا احد الامثلة الشبيهة ... بربط جدولين مع بعضهما .... ارجع للدرس السابق وتأكد !!

اليك حل اخر غبي ...








SQL> select ename , sal , deptno from emp

2 where sal >any (select avg(sal) from emp group by deptno) ;



ENAME SAL DEPTNO

---------- ---------- ----------

ALLEN 1600 30

JONES 2975 20

BLAKE 2850 30

CLARK 2450 10

SCOTT 3000 20

KING 5000 10

FORD 3000 20




هنا يكمن الغباء أين ؟

انه سوف يقارن مع راتب الموظف ومع جميع الأقسام !! وليس قسمه !!

اذن نحتاح لرابط يربط كل شخص وراتبه .... مع قسمه فقط !!

الان خذ الحل ... ولم اعرض هذا المثال الا لأنني شاهدت فيه نوع من الصعوبة في فهمه !!

قبل ان ترى الحل انظر الناتج لعل وعسى تستطيع ان تحلها بنفسك ... وانا اعتقد انك لا تستطيع :





ENAME SAL DEPTNO SALAVG

---------- ---------- ---------- ----------

ALLEN 1600 30 1566.66667

JONES 2975 20 2175

BLAKE 2850 30 1566.66667

SCOTT 3000 20 2175

KING 5000 10 2916.66667

FORD 3000 20 2175




الحل لا اعتقد انك تعرفه جيدا لاني لم اقترح عليك حلا مشابه ...

الا وهو ... الاستعلام الفرعي في جملة from ...


انظر الى الحل ...





select a.ename , a.sal ,a.deptno ,b.salavg

from emp a , (select deptno , avg(sal) salavg from emp group by deptno) b

where a.deptno=b.deptno

and a.sal>b.salavg;




هل شاهدت جملة الاستعلام الفرعية .. عاملناها تماما مثل الجدول .. وسميناها بـ b واستخدمنا احد اعمدتها !!

سمينا العمود avg(sal) بـ salavg واستخدمناه في جملة الاستعلام الرئيسية بـمسمى :b.salavg ,,,


وكأنه جدول !!

متى نستخدم مثل هذا الحل ؟ اذا اردنا جدول لا نملكه ... مثلا هل يوجد جدول جاهز به المعلومات التالية ؟؟:





MAX(SAL) MIN(SAL) DEPTNO

-------- --------- ----------

5000 1300 10

3000 800 20

2850 950 30




طبعا يجب ان نعمله من جملة استعلام .. صح ؟

هل تتخيل الموقف ؟ هل تتخيل الوضع ؟ هل تصدق انني اعطي هذا الحل صعوبة 9 من 10 ؟؟؟

هل عرفت فائدة الاستعلام الفرعي والذي يكمن انه يأتي بالنتائج التي نريدها والتي لا نعرفها ؟

هل عرفت فائدة ربط الجداول مع بعضها وكيف ان نضع أي عمود في العالم وندمجه مع عمود من عالم اخر ؟

هل عرفت ان المثال السابق استخدم فائدة الجداول الفرعية و فائدة ربط الجداول؟؟

احببت ان اراجع معك ما اخذناه بمثال رائع واكثر من رائع ... تنبه !!





الان .. اود ان اعرف شيء مهم في البرمجة .. مهم جدا ,

اريدك ان تفرق بين الذاكرة الرام والقرص الصلب ..

الذاكرة هي من نوع الذاكرة المؤقتة , والقرص الصلب هو الذاكرة الدائمة !

الرام يحتوي على معلومات موجودة به , وتختفي متى ؟ اذا اطفأنا الجهاز ... اذا انقطع التيار ..

أي ان الرام تحفظ بشكل مؤقت طالما ان التيار موجود ..

ولكن القرص الصلب موجودة به المعلومات سواء اطفأنا الجهاز او لا ... الا اذا جاء فيروس محترم ومسح مافيه !

الان , لماذا نستخدم الرام ؟ ولماذا نستخدم القرص الصلب ؟

الرام للمعلومات التي نريدها للحظة معينة , ثم لا نكترث لها !!

القرص الصلب للمعلومات المهمة التي لا نريدها ان تمحو من ذاكرتنا ,

فمثلا قواعد البيانات ... تحفظ في القرص الصلب ... لاننا نحتاج المعلومات التي به دائما وابدا

الان .. لماذا الرام ؟؟ بإمكاننا ان نخزن ما نريد في القرص الصلب , ثم نحذفه اذا طفشنا منه !!


وايضا التخزين على القرص الصلب يؤمننا من انقطاع التيار , يعني نطفئ الجهاز ونرجع نشغله غدا ونرى كل ما كان بالامس موجود اليوم ... فلماذا الرام ؟

وايضا نجد ان القرص الصلب رخيص جدا بالمقارنة مع الرام ... يمكننا ان نحصل على سعة تخزين هائلة تتكلم بالجيجا بايت , بينما الرام اذا وصل الجيجا , يرتفع ثمنه ... فلماذا الرام ؟

في الحقيقة اهم الاسباب هي .. سرعة الرام الخيالية , والتي تقدر بسرعة الضوء (سرعة انتقال الالكترونات)


حيث ان القرص الصلب ذو حركة ميكانيكية في اغلب الامر , والرام سرعة الكترونية !

وسوف يأتي العهد القريب بأن يصبح القرص الصلب بسرعة الرام , وهذا ما نشاهده في كرت الفلاش التخزيني (المتصل بالـ USB والمعروف بصغر حجمه مع كبر سعته التخزينية!!)





المهم , مثلا كتبنا الجملة التالية :










SQL> select ename from emp where deptno=10;



ENAME

----------

CLARK

KING

MILLER




فانه يحدث ما يلي ..

يذهب لمرة واحدة الى القرص الصلب ... طبعا المعالج ينتظر النتائج من القرص الصلب ... وجده ؟ نعم وجد الجدول الخاص بالموظفين .. يأخذ المعالج المعلومات بسرعة البرق ويخزنها في الرام بسرعة البرق , ويعمل الحسابات اللازمة والشروط .. بسرعة البرق ... ويعرض الناتج امامنا .. وبسرعة البرق ...

الان .. اريدك ان تتعلم شيء يعتبر استخداما للرام , كيف ؟


اعلمك المتغيرات !!

المتغيرات هي اوعية تحتوي على بيانات بها ! يمكن ان تكون هذه المتغيرات .. متغيرات نصية او رقمية او ماشابه ..

المتغيرات لها عنوان على الرام , أي اننا نقول المتغير س به العدد 10 ... فهذا المتغير س , موجود في الرام , واذا اطفأنا الجهاز ... ذهب المتغير س , وذهب العدد 10 .

لماذا المتغيرات ؟ لكي نسترجع بعض البيانات والقيم , فمثلا اقول لك .... 2 + 6 + 10 كم الناتج ؟

طبعا عقلك به رام حيوي , يأتي عقلك ويأخذ الـعدد 2 ويخزنه بالرام الحيوي (الذاكرة القصيرة المدى)... وانت لا تعلم ...

ويأخذ العدد 6 ويخزنه في الذاكرة (متغير حيوي) وايضا العدد 10 يخزنه بالذاكرة .. وانت لا تعلم ...

يقوم بقراءة العلامة + ... ولأنه يفهم انها زائد ويفهم قواعدها .. فيقوم بأخذ العدد اثنين من المتغير , ويأخذ العدد ستة من المتغير , ويجمعهما سوية ويخزن الناتج وهو العدد 8 ... في متغير جديد ... يسترجع العدد 10 ويسترجع العدد 8 مرة اخرى , ثم يجمع العددين ويخزنهما في الذاكرة ... ويأمر العقل .. اليد بكتابة 18 على الورق !

وكل هذا وانت لا تعلم ... لماذا لا تعلم ؟ لأن الحسابات هذه بسرعة الضوء !

البرمجة مثل هذه الفكرة , عندما نبرمج , فإننا نكتب خطوات كهذه , خطوة خطوة , وبطريقة منتظمة , وبها متغيرات تخزينية .

ارجو انك تنتبه للمتغيرات وفائدتها العظيمة , وكلي ثقة انك فهمت ما معنى متغير ... أي ان الهدف منها واضح ...

وعبر امثلتنا سوف تفهم هذا الهدف ....

The Coder
19-02-2006, 04:14 AM
الان تخيل انك تكتب جملة استعلام ... ولما تنفذ هذه الجملة ... يطلبك البرنامج ان تدخل قيمة معينة ... لم تفهم صح ؟ انظر الى المثال :

اريد ان اعرض كل من في قسم انا اختاره ...








select ename , sal , deptno

from emp

where deptno=&d1;




هل شاهدت علامة غريبة ؟ وكلمة غريب استخدامها ؟


&d1 , ماذا تعني ؟

يقول اعرض معلومات الموظف الذي يعمل بقسم &d1


وما هو قسم &d1 ؟؟

للعلم ان &d1 هو متغير ... موجود به رقم لا نعرفه ...

من أين ندخل هذا الرقم ؟؟ انا اخبرك .. حينما ننفذ البرنامج :





Enter value for d1:




يقول ادخل قيمة في الـ d1 .. ولاحظ ان علامة & اختفت !!

انا سوف اكتب 10 .....








Enter value for d1: 10




وستكون الناتج :





ENAME SAL DEPTNO

---------- ---------- ----------

CLARK 2450 10

KING 5000 10

MILLER 1300 10




هل فهمت شيء ؟


&d1 متغير , وعاء رقمي , لا يوجد به شيء ...

الأوراكل يرى هذا المتغير , ويجده مسكين لا يملك قيمة !!

يأتي ويقول "ارجوك ... اعطي قيمة للمتغير الذي يدعى بــ d1 : "


وتأتي انت .. وتعطيه عشرة ريالات .. ااقصد تكتب القيمة 10 بداخله ... الان الاوراكل ينظر الى ما بداخل هذا الوعاء , أي مابداخل هذا المتغير الذي يدعى d1 ويجده عشرة يستبدل الـ &d1 في جملة الاستعلام بالقيمة عشرة ..

فتصبح من :





select ename , sal , deptno

from emp

where deptno=&d1;






الى الشكل النهائي :





select ename , sal , deptno

from emp

where deptno=10 ;






هل فهمت الان ؟؟ ثم ينفذ الجملة كما هي ...

هيا لنعقد الموضوع قليلا !!





select ename , sal , deptno

from emp

where deptno=&d1

and sal>(select max(sal) from emp group by deptno having deptno=&d2);




الان هل يتأكد الأوراكل ما اذا كانت الجملة صحيحة او لا ؟؟ طبعا لا !!

اول ما يفكر فيه .. هو المتغيرات !! هل بها قيم او لا !!

اذا لم يجد قيم .. يقول لك "اعطي قيمة لـفلان من المتغيرات :"

هيا لننفذ البرنامج , وهو عرض كل من راتبه اكبر من (اكبر راتب ) في قسم انا اختاره (d2) ... وفي قسم معين انا ايضا اختاره !! (d1)







Enter value for d1: 10




لقد كتبت عشرة في المتغير الاول ...





Enter value for d2: 20




كتبت عشرين في المتغير الثاني ...

والان سوف تحول الأوراكل هذه المتغيرين الى قيم ... يعني ماذا ؟ يعني أي متغير يسمي نفسه d1 ضع بداله القيمة 10 , و أي متغير يسمي نفسه d2 , نضع بداله القيمة 20 ....

انظر الى الجملة بعد التنقيح :





select ename , sal , deptno

from emp

where deptno=10

and sal>(select max(sal) from emp group by deptno having deptno=20);




خلاص .. سوف ينفذها كما هي .... ويعرض النتائج ... وانتبه لعلامة & وتعني ان الاسم الذي بعدها متغير ,

سمي ما شئت , d1 , d1000 , deptno_of_emp ,


أي اسم تريده ..

مثلا تريد ان يكون المتغير :deptno_10 به قيمة دائمة , وتريد ان تستخدمها كثيرا ..

مثلا به القيمة 10 .... ولا تريد تغيير القيمة بداخله ... انظر المثالين :





SQL> select deptno , ename

2 from emp

3 where deptno=&&deptno_10;





Enter value for deptno_10: 10



DEPTNO ENAME

---------- ----------

10 CLARK

10 KING

10 MILLER




الان المتغير به 10 , ولن يسألك ثانية هل تريد ان تضع به قيمة او لا ...

والسبب اننا وضعنا علامتي && , هيا لنستخدمه مرة ثانية





SQL> select ename from emp where deptno=&deptno_10;



ENAME

----------

CLARK

KING

MILLER




اوتوماتيكي سوف يعرف ان المتغير deptno_10 به العدد عشرة , مع العلم انها علامة واحدة & في مثالنا الاخير .

وسواء علامة او علامتين , فهو مخزن به الرقم عشرة ....

اعتقد انها سهلة وبسيطة ولا تحتاج الى تطويل الموضوع ولكن لتبرئة الذمة , انظر الى المتغيرات النصية والتاريخية كيف نكتبها :





SQL> select ename from emp

2 where job='&select_job';

Enter value for select_job: ANALYST



ENAME

----------

SCOTT

FORD




المتغيرات ايضا في الشروط وفي الترتيب وفي اجزاء اخرى في جملة الاستعلام :





select ename , sal

from &any_table

where &any_condition

or &any_condition_2

order by &any_order ;




وعند التنفيذ انظر ماذا كتبنا :





SQL> select ename , &col_name

2 from &any_table

3 where &any_condition

4 or &any_condition_2

5 order by &any_order ;

Enter value for col_name: sal

Enter value for any_table: emp

Enter value for any_condition: sal>2000

Enter value for any_condition_2: sal<1000

Enter value for any_order: sal



ENAME SAL

---------- ----------

SMITH 800

JAMES 950

CLARK 2450

BLAKE 2850

JONES 2975

SCOTT 3000

FORD 3000

KING 5000




مسلية هاه ^^ ..... كل ما عمله الأوراكل هو استدبل القيم التي ادخلناها .. لتصبح الجملة كما يلي :





select ename , sal

from emp

where sal>2000

or sal<1000

order by sal ;






هذه الفكرة ..

اسف على تطويل موضوع المتغيرات ولكن لأهميته برمجيا , وليس هنا !! هنا للاستخدام التفاعلي والعرضي فقط .

بقي جملتين تدعيان define و Accept ,, نفس الفكرة للمتغيرات ولا اخفيك مدى غبائهما , لذا لو اردتهما ابحث عنهما او راسلني .

The Coder
19-02-2006, 04:15 AM
- عرض التقارير :

















تخيل شكل هذا التقرير (الصورة 1300)

http://img6.picsplace.to/img6/14/1300_000.JPG



















هل تريد حينما تكتب الامر :












Select * from emp ;









على سبيل المثال ,, ويظهر لك شكل تقرير ومرتب كصفحة بطريقة منظمة ؟؟


الان اعلمك شيء للعرض والتسلية فقط , اكتب الجمل التالية كما هي : وسوف اشرح معنى كل جملة منها ...

وتذكر ان الهدف من هذه الأوامر هي الاعداد !! ,,, اعداد ماذا ؟ اعداد الصفحة لكي تبدو وكأنها تقرير وبشكل كما في الصورة السابقة !! , أي انك اذا اعددت الصفحة , ثم عملت أي استفسار .. فسوف تعرض كما اعددتها ...

لا تنسى هدفنا .... الا وهو اعداد الصفحة ...











set pagesize 37









يقول : اضبط حجم الصفحة يساوي 37 , أي 37 سطر للصفحة الواحدة ... وسترى ما معناها .












set linesize 60









يقول : اضبط طول السطر الواحد ... كم حرف ؟ 60 حرف ... وانا من قبل كنت اضع 10000 حرف , لكي تعرض الاستفسارات كما اريد ...












set feedback off









اضبط عرض عدد الصفوف للاغلاق .. هل تذكر حينما نكتب جملة استفسار , يعرض لنا عدد الصفوف في اخر العرض ؟ أي يعرض مثلا : no row selected .. او يقول : 6 rows selected هل تذكرها ؟


اذا قلنا set feedback off , يعني لا تعرض هذه الرسالة .. اذا قلنا set feedback on فمعناه اعرض الرسالة تلك

















ttitle 'employee|report|^^'






عنوان الصفحة .. الذي يأتي في رأس الصفحة .. فوق في المنتصف ....


وضعت رسالة غريبة نوع ما ... لقد كتبت employee ثم علامة | والتي تعني السطر التالي ... ثم كتبت report ثم كتبت العلامة | أي السطر التالي . ثم ^^

انظر الصورة السابقة 1300 .... وسوف تفهم قصدي ....











btitle 'confidential'









العنوان الذي يأتي في اسفل الصفحة ..... اكتب ماشئت , مع العلم ان العلامة | تعني السطر التالي ...












break on job









هذه تعمل تصنيف .... تصنيف على حسب عمود المهنة.... انظر الصورة السابقة ... سوف ترى ان النتائج مقسمة على حسب عمود المهنة ... ولاحظ عدم تكرار المهنات .... لو اردنا على حسب رقم القسم ؟ ماذا نكتب ؟؟ نفس الشيء .. نكتب break on deptno









column job heading 'job|actegory' format a15






امر column الذي يضبط الاعمدة .. فهنا يقول ... اضبط كل عمود يدعى بـ "مهنة" و اجعل عنوانه (عنوان العمود) يساوي الجملة 'job|actegory' ولاحظ العلامة | أي السطر التالي .


يوجد كلمة format أي شكل النتائج كيف ؟ قلنا له a15 أي ... ان حده 15 حرف ..

انظر الصورة السابقة وانظر في عمود المهنة , كيف عرض , وكيف عرضنا العنوان الخاص به ....

















column sal heading 'salary' format $99,999.99






يظهر انه نفس السابق , ولكن تعامل مع عمود الراتب , والذي اعطاه العنوان salary وجعل شكله بهذا الشكل :








$99,999.99 والتي قد اخذناها سابقا , وما معناها وما معنى $00,000,.00 صحيح ؟


راجع درس الدوال الرقمية ....











column ename heading 'Employee' format a15









خمسة عشر حرفا لكل عمود يدعى بـ ename و عنوانه يجب ان يكون Employee








الان ..





















انتهينا من الاعدادات ... هيا لنجرب مالذي سوف نراه ...












select job , sal , ename

from emp

where sal>2500

order by job;









انظر الى الناتج ... مع العلم انني ضبطت ثلاث اعمدة وهي "المهنة" و "الرواتب" و "اسم الموظف" ,


وعرضت هذه الثلاث اعمدة ... لاحظ انني قلت رتب على حسب المهنة , لأنني قلت سابقا "صنف على حسب المهنة"













page 1

employee

report

^^



job

actegory salary Employee

--------------- ----------- ---------------

ANALYST $3,000.00 SCOTT

$3,000.00 FORD

MANAGER $2,975.00 JONES

$2,850.00 BLAKE

PRESIDENT $5,000.00 KING



















confidential









الان نجرب عمود لم نضبطه :












page 1

employee

report

^^



job

actegory salary Employee EMPNO

--------------- ----------- --------------- ----------

ANALYST $3,000.00 SCOTT 7788

$3,000.00 FORD 7902

MANAGER $2,975.00 JONES 7566

$2,850.00 BLAKE 7698

PRESIDENT $5,000.00 KING 7839









confidential









الان .. لنجرب حذف order by job








هيا ....


















select job , sal , ename , empno

from emp

where sal>2500 ;






page 1

employee

report

^^



job

actegory salary Employee EMPNO

--------------- ----------- --------------- ----------

MANAGER $2,975.00 JONES 7566

$2,850.00 BLAKE 7698

ANALYST $3,000.00 SCOTT 7788

PRESIDENT $5,000.00 KING 7839

ANALYST $3,000.00 FORD 7902











confidential






هل شاهدت تكرار بعض المهن ؟ لانها غير مرتبة ..


اذن ... تصنف على حسب العمود الذي ترغبه باستخدام break on ثم في جملة الاستفسار تكتب order by لنفس العمود المصنف به . ونقصد بالتصنيف أي الترتيب والتقسيم , وهي للعرض فقط ...

The Coder
19-02-2006, 04:17 AM
طيب .. لو عندنا عمود به بيانات خالية ولا نريدها ان تظهر خالية بل بدلا عنها رسالة ... انظر الجملة :





SQL> column mgr format 999999999 null 'no manager'




انظر الى الصورة السابقة .. وسترى ان احدهم كان يملك قيمة خالية ولكنها استدبلت بالرسالة no manager


ولاحظ اننا قلنا 9999999999 .... لماذا ياترى ..

جرب وضع اقل من هذه ... ضع خمس تسعات وانظر مالذي يحدث ....

الان .. انا فعلا نسيت كم جعلت طول عرض العمود رواتب .. كيف اعرف ؟ اها انظر :





SQL> column sal



COLUMN sal ON

HEADING 'salary'

FORMAT $99,999.99




فقط column ثم العمود الذي ترغب ...

عرض لك ثلاث نتائج ... الاولى انه مرئي او لا .... وهو مرئي ON


الثانية العنوان ... وهو salary


الثالثة الشكل الخاص به .. كما تشاهد ...

الان اريد احذف هذا الضبط على عمود job .... كيف ؟ انظر





SQL> column sal clear




الان تأكد انه حذف ضبط العمود job ولا تنسى ما نعنيه بالضبط .. وهو ضبط العرض ليس الا ...





SQL> column sal

SP2-0046: COLUMN 'sal' not defined




خطأ ... يقول انه لا يوجد له ضبط ...

طيب ... انا لا اريد أي ضبط على كل الاعمدة ... ماهو الامر ؟ اليك الامر :





SQL> clear column

columns cleared

SQL> column ename

SP2-0046: COLUMN 'ename' not defined




اول سطر ... قلنا امسح الضبط على كل الاعمدة ... وفي السطر الثاني قال حاضر .. تم المسح

السطر الثالث قلت اعرض لي ضبط العمود ename


وفي السطر الرابع يقول ... لا يوجد ضبط ...... هذا كل شيء ...

قد تلاحظ انني اشرح من دون نفس .... لان البرنامج اصلا ليس لغرض العرض الجميل والتقارير الجميلة ..

بل لاغراض التجريب , وله مأرب اخرى ,,,

فبرنامج sql pluse ضعيف جدا من ناحية العرض , والتعامل والتحرير ... لذا انا لا اهتم لبرنامج SQL plus, بل اهتم لنفس SQL ومفاهيمه ...

الان اذهب وجرب بعض الاعدادات والضبط للصفحة , وحاول ان تعمل ما تريد .





الان اتينا الى ما هو مهم جدا ....

الاوبجيكت .. هل تذكره ... Object


أي ملف موجود على القرص الصلب ... يسمى عادة بـ اوبجيكت .

يعني حينما نأخذ البيانات من اوبجيكت , هي اخذ البيانات من ملف في القرص الصلب (ذاكرة دائمة).

الان ماهي انواع الاوبجيكت في الأوراكل ... عذرا لكلمة اوبجيكت ... فمعناها بالعربي "شيء" ولها معنى اخر وهو "غرض" , معنى ثالث "جسم" .....

فصراحة لا اعتقد ان هذه المعاني ... تصلح في موضعنا هذا ... سميها اشياء .. سميها اجسام .. سميها اوبجيكت ... لك ما تشاء ...


الان انواع الاوبجيكت هي :

- الجداول tables.


- المناظر views


- السلسلة sequences


- الادلة index


- المرادفات synonym




لا تكرهني بسبب التسميات .....





1- الجداول tables.


نعرف هذا الاوبجيكت جيدا .... نحن تعاملنا معه على مر عصور من دروسنا ... ولا يسعني ان اذكر لك غير انه ملف موجود على القرص , به البيانات نفسها ....


2- المناظر views


هذه مالم نتكلم عنه ... وهي المناظر ... اعرف ان الترجمة هي الاخرى سيئة للغاية ولكن اسف ... فلنسميها في منهجي المناظر ... المنظر ....

من اسمها ... منظر .. حينما نقول منظر ... ماذا نقصد ؟ نقصد شيء نراه .... ممكن يكون حقيقي فعلي .. وممكن تكون صورة ...

الان المناظر هذه هي جداول ... جداول معنوية ... تراها امامك بعين اليقين , ولا تفرق بينها وبين الجداول ...


هي في الحقيقة ... وعلى ما اعتقد انه ملف يحتوي على جملة استعلام ... كيف ؟ انا اخبرك ..

المناظر فكرتها انك تريد ان تعرض جدول الموظفين + اسماء الأقسام ... يعني كما يلي :





SQL> select e.ename ,d.dname

2 from emp e , dept d

3 where e.deptno = d.deptno

4 and e.sal>2900;



ENAME DNAME

---------- --------------

KING ACCOUNTING

JONES RESEARCH

FORD RESEARCH

SCOTT RESEARCH




الان ... انا كتبت الجملة ... ثم نفذتها ...

في اليوم التالي .. اريد نفس الجملة .. اااقصد نفس النتيجة .. اريد ان اعرض اسماء الموظفين واسماء اقسامهم للكل من راتبه اعلى من 2900

في اليوم الثلاث مئة , وخمس وستون ... اردت نفس الاستفسار , ولكن اريد ان اضيف عليه شرط اخر ....

في اليوم الالف وخمس مئة و سبعة واربعون .. اردت نفس الاستفسار ولكن بشرط رابع ....


ماذا اعمل ؟؟ هه بسيطة .. اكتب جملة الاستعلام نفسها ..... ويظهر لي الناتج ... مع تغيير ما يلزم ...

طيب ... بالله عليك لو كان هناك جملة استعلام ..... ذو عشرين سطر او خمسين سطر (..... وليست اربع سطور كما في هذه السابقة !!) وتعتمد على اثنى عشر جدول يجب ان اربط بينهم

وانا ارغب في عرضها مئة مرة في اليوم .. وطبعا مع تغيير بعض الامور البسيطة ..

بالله عليك اجلس كما انا عليه ؟؟ او اجعل هذا الاستفسار في جدول جديد ؟؟ مارأيك نعمل جدول له ونخلص .... ويصير اقول


Select * from this_table ;


طيب ... يوجد لدي انا عشر جداول اضافية غير الجداول الرئيسية .. ويوجد لدى الموظف الاخر عشرون ...

ويوجد في الشركة الف موظف .... يعني يوجد عشرات الالاف من الجداول التي من الممكن ان تؤثر على كفاءة النظام ...

مالحل ؟ نحن نعمل بيانات مكررة في جداول اخرى !! ولماذا تعبنا وقسمنا الجداول وعملنا قوانين السيد كود على قواعد البيات ؟؟

من الغباء جدا ان نعمل جداول مكررة .... وهذا رأيي انا !

الحل هي المناظر ,,, تخيل معي ان المنظر هو ليس الا صورة ... ولا شيء غير الصورة ....

صورة من ماذا ؟؟ من الجداول ...

هل ننسخ الجداول ؟؟ لا لا ننسخ الجداول .. مجرد ملف صغير جدا يشير الى الجداول التي نريدها !!

ماهي الفكرة اذن ؟ وكيف نعمل المنظر ؟ انظر الامثلة ....

مثلا اريد ان اكون منظر .. لموظفي القسم 30 !

يعني بالعقل البيانات لموظفي القسم 30 موجودة في جدول الموظفين .. لماذا اعمل جدول اخر ويصير تكرار ؟

بعض الاحيان نحتاج هذا التكرار فعلا , مثلا نريد التجربة على جدول الموظفين ... نعمل جدول اخر مثل الموظفين .. ونقعد نجرب فيه ونحذف ونضيف .... وما الى ذلك بدون ان يتأثر الجدول الأساسي ... اما اذا كنت اريده للعرض فقط ... فنعمل المنظر ... ولنسميه emp_30 ..





SQL> create view emp_30

as select ename , deptno , sal

from emp

where deptno=30 ;



View created.




كيف نستعلم من المنظر هذا ؟ عادي جدا ... كالجداول تماما !! :





SQL> select * from emp_30 ;



ENAME DEPTNO SAL

---------- ---------- ----------

ALLEN 30 1600

WARD 30 1250

MARTIN 30 1250

BLAKE 30 2850

TURNER 30 1500

JAMES 30 950



6 rows selected.




طيب .... بالله عليك لو عملنا جدول ما بيكون نفس الشيء ؟

يعني منظر .... جدول .... كلها لاتفرق .. كلها تأخذ مساحة ...

هنا سوف اعرض لك الفرق .... سوف يرى الأوراكل انك تريد عمل منظر ...

سوف لن يعمل ملف جديد ويضع فيه البيانات الخاصة بالموظفين !! لا ...

بل سوف يعمل ملف صغير جدا ... وبه جملة الاستفسار فقط !!

ما هي جملة الاستفسار في مثالنا ؟

The Coder
19-02-2006, 04:25 AM
انها هذه :





select ename , deptno , sal

from emp

where deptno=30 ;






التي عملنا المنظر منها !! سوف يخزنها في ملف لا يتعدى الواحد كيلو بايت ..

ثم تأتي انت وتقول .. يا أوراكل ... اريد ناتج الاستفسار التالي :





select * from emp_30 ;






يقول لك اوراكل : " لحظة ... "

يذهب ويبحث عن جدول يدعى بـ emp_30


لا يجد متهم بهذا الاسم ... يقول الأوراكل في نفسه "ممممم لا يوجد جدول ... اكيد هذا منظر !!"

يأتي الى الملف الصغير الذي انشأه اول مرة .... يرى واذا باسم المنظر emp_30


يقول له .. تعال يا ايها المنظر ....

ثم يفتح الملف ... ماذا يجد فيه ؟؟ يجد فيه رسالة مكتوب فيها :





select ename , deptno , sal

from emp

where deptno=30 ;






يقول الأوراكل .... حسنا ...

يذهب ويطبق الاستفسار .... أي يذهب الى جدول الموظفين ... ويحمله على الذاكرة المؤقته ... ثم يختار الصفوف التي رقم القسم فيها ... يساوي 30 !!

ثم يعرض لنا الناتج ....

يعرضه وكأنه هو الجدول !!

الان نحذف هذا المنظر ... انظر كيف نحذفه :





SQL> drop view emp_30 ;



View dropped.




ياسلام .. نفس فكرة الجدول ....

الان .... سوف اريك عيوبه .. او بالاصح اثاره الجانبية ... الا وهي التعديل فيه ..

اذا عدلت فيه .. فأنت لا تعدل في بيانات المنظر .. بل في الجدول الذي يستمد المنظر منه !!


لم تفهم .... طيب .. سوف نرى :





create table emp_30 as

select ename , sal from emp

where deptno=30;




نعمل جدول .. وليس منظر .... الان الجدول الذي اسمه emp_30 به بيانات حقيقية ... وموجودة بالقرص الصلب !

هل هي نفسها الموجودة بجدول emp ؟؟ لا لا .... هل تصدق ؟؟ الا زلت غير مصدق ؟ هيا لنتأكد ...








SQL> select * from emp_30 ;



ENAME SAL

---------- ----------

ALLEN 1600

WARD 1250

MARTIN 1250

BLAKE 2850

TURNER 1500

JAMES 950




ما رأيك ان نعدل في الجدول ؟ هيا لنعدل ونرى هل تتعدل البيانات ايضا في جدول الموظفين emp ؟؟

لنرى .....





update emp_30 set sal=9999

where ename ='JAMES';




لا تفرح يا JAMES .... لم نرقيك ولكن .. نجري بعض التجارب ..

هيا لنعرض المعلومات من الجدولين .. ونرى هل تغيرت في الجدولين ؟ انظر :





SQL> select ename , sal from emp_30;



ENAME SAL

---------- ----------

ALLEN 1600

WARD 1250

MARTIN 1250

BLAKE 2850

TURNER 1500

JAMES 9999



6 rows selected.



SQL> select ename , sal from emp ;



ENAME SAL

---------- ----------

SMITH 800

ALLEN 1600

WARD 1250

JONES 2975

MARTIN 1250

BLAKE 2850

CLARK 2450

SCOTT 3000

KING 5000

TURNER 1500

ADAMS 1100



ENAME SAL

---------- ----------

JAMES 950

FORD 3000

MILLER 1300



14 rows selected.


هل تعدلت في جدول الموظفين الاصلي ؟ طبعا لا ... لماذا ؟ لان كل جدول منهما مستقل عن الاخر !!

كل ما فعلناه هو نسخنا ووضعنا نسخة جديدة في جدول الموظفين emp_30


هذا كل شيء ...

الان لنعمل منظر من الجدول emp_30 .. وليكن نفس المعلومات ...





create view view_30

as select * from emp_30;




الان يسمى الجدول emp_30 بالنسبة للمنظر view_30 الجدول الاساس ...

أي الجدول الذي يستمد المنظر منه الطاقة ... يستمد البيانات .... هل فهمت ؟ اسف على غبائي ... تركت المنظر هو نفس الجدول !! ... المفترض ان المنظر يكون ذو استفسار اعقد واعقد من هذا الاستفسار .... لكي تكمن فائدته !!








SQL> select * from emp_30;



ENAME SAL

---------- ----------

ALLEN 1600

WARD 1250

MARTIN 1250

BLAKE 2850

TURNER 1500

JAMES 9999



6 rows selected.



SQL> select * from view_30;



ENAME SAL

---------- ----------

ALLEN 1600

WARD 1250

MARTIN 1250

BLAKE 2850

TURNER 1500

JAMES 9999



6 rows selected.





هل شاهدت انه صورة منه ؟

The Coder
19-02-2006, 04:28 AM
الان لو عدلنا في الجدول الاساس .. هل سيؤثر في المنظر ؟؟؟

لنرى ذلك ... هيا لنغير اسم BLAKE الى ABC ... طبعا من الجدول الاساس وليس المنظر ....










update emp_30 set ename='ABC'

where ename='BLAKE';










SQL> select * from emp_30;



ENAME SAL

---------- ----------

ALLEN 1600

WARD 1250

MARTIN 1250

ABC 2850

TURNER 1500

JAMES 9999



6 rows selected.



SQL> select * from view_30;



ENAME SAL

---------- ----------

ALLEN 1600

WARD 1250

MARTIN 1250

ABC 2850

TURNER 1500

JAMES 9999



6 rows selected.




ممممم .. واضح ان التغيير حصل ايضا في المنظر ... المنظر ليس الا شارة ... reference


أي شيء يشير الى جدول ما !

الان دعنا نعدل في المنظر ...لنغير كل من راتبه فوق 1250 الى اسم XYZ


هيا لنغير في المنظر . وليس الجدول !!





update view_30 set ename='XYZ'

where sal>1250;




هيا هيا لنرى النتيجة ...





SQL> select * from emp_30;



ENAME SAL

---------- ----------

XYZ 1600

WARD 1250

MARTIN 1250

XYZ 2850

XYZ 1500

XYZ 9999



6 rows selected.



SQL> select * from view_30;



ENAME SAL

---------- ----------

XYZ 1600

WARD 1250

MARTIN 1250

XYZ 2850

XYZ 1500

XYZ 9999



6 rows selected.




غير معقول ... لقد تغيرت ايضا البيانات في الجدول !!

طيب ... صراحة التعديل في المنظر او الحذف بواسطة المنظر ... شيء غير مستحب ... او غير عملي ... او انه مخيف نوعا ما .. واضافة البيانات ايضا اليه ... من الممكن في كثير من الاحيان غير منطقي !! لماذا ؟

لانه يؤدي الى كسر قواعد واساسيات السيد كود !! كيف ذلك ؟؟ انظر الى الامثلة





create view temp

as select ename , sal , deptno

from emp

where sal > 1100 ;




عملنا منظر من جدول الموظفين emp ... أي ان الجدول الاساس الخاص بالمنظر temp هو الجدول emp


الان لنضيف أي بيانات الى المنظر ...








SQL> select * from temp ;



ENAME SAL DEPTNO

---------- ---------- ----------

ALLEN 1600 30

WARD 1250 30

JONES 2975 20

MARTIN 1250 30

BLAKE 2850 30

CLARK 2450 10

SCOTT 3000 20

KING 5000 10

TURNER 1500 30

FORD 3000 20

MILLER 1300 10




الان نضيف ...





SQL> insert into temp values ('A',1250,30);









ERROR at line 1:

ORA-01400: cannot insert NULL into ("SCOTT"."EMP"."EMPNO")




يوجد خطأ ... لندرسه ..

يقول .. انت لم تضف بيانات الى العمود رقم الموظفين ... والذي يعتبر مفتاح أساسي لجدول emp ..


في الحقيقة حينما اقول انني سوف اضيف الى المنظر ... أين تذهب الاضافة ؟؟ في المنظر ؟؟ لا طبعا

المنظر ليس الا ملف به استفسار فقط !!

اذا اضفنا الى المنظر .. فسوف تضاف البيانات اوتوماتيكيا الى الجدول الاساس .... صح ؟

طيب ... المنظر به الاعمدة التالية :





SQL> select * from temp;



ENAME SAL DEPTNO

---------- ---------- ----------

ALLEN 1600 30

WARD 1250 30

JONES 2975 20

MARTIN 1250 30

BLAKE 2850 30

CLARK 2450 10

SCOTT 3000 20

KING 5000 10

TURNER 1500 30

FORD 3000 20

MILLER 1300 10




أي ان به اسم الموظف , الراتب , رقم القسم ...

حينما نقول ... اضف المعلومات الى المنظر .. فسوف ينفذ الأوراكل ما يلي :

- يأتي وينظر الى جملة الاضافة التي كتبناها للتو ... يجد انه لا يوجد جدول باسم temp


- يبحث عن المناظر .. هل يوجد منظر بهذا الاسم ؟ نعم !!

- يرى الاستفسار الذي بداخله ... ويجد الجدول emp هو الجدول الاساس .....


- سوف يضيف اوتوماتيكيا الى المنظر ؟؟؟ لا الى الجدول الاساس ... وهو جدول الموظفين ..


- يريد ان يضيف اسم A والراتب 1250 ورقم القسم 30 .. فقط


-يقوم بالتنفيذ ... ويجد انه لم يضف الى العمود رقم الموظفين شيء !! أي انه اضاف قيمة خالية! وهو مفتاح لا يقبل الخالي ولا يقبل التكرار !!


- يصدر الخطأ السابق ...





هذا ما حدث بالفعل ... ولن تجد كتاب يعلمك مالذي حدث ... فانتبه جيدا لهذه المعلومات .... والتي بإمكانك استنتاجها اصلا !





الان رأينا ان الاضافة .. الحذف .. والتعديل في المناظرغير عملية .. ولها مشاكل جمة ...

فما بالك اذا كان المنظر يستمد بياناته من عشرة جداول !! ماذا تقول في هذا !!

طبعا ستكون شبه مستحيلة .. ويمكن ان تكون مستحيلة التعامل معاه ...

انا شخصيا لا ارى المنظر الا للعرض فقط ... و اختصار سكة الاستفسارات المتكررة الطلب والمعقدة ... هذا ليس الا ... ولا ننكر ان هذا مفيد جدا جدا جدا .... وحفظ للمال والوقت والجهد .

الان ما هي انواع المناظر ؟ لا تخف .. مجرد تسميات ..

منظر معقد .... ومنظر بسيط ..

المنظر المعقد يستمد بياناته من اكثر من جدول .... بينما البسيط من جدول واحد

في جملة استفسار المنظر المعقد يوجد دوال و ايضا يوجد بيانات مقسمة من قبل group by


بينما البسيط لا يحتوي عليها .

المنظر المعقد لا يمكننا ان نعمل أي من اوامر الـ DML من حذف وتعديل واضافة في الغالب !! .. بلغة اخرى نادرا ما نستطيع ....بينما المنظر البسيط في الغالب نستطيع ذلك ...

The Coder
19-02-2006, 04:40 AM
الان انظر الى الجدول emp_30 وانظر الى المنظر view_30 ,





SQL> select * from emp_30;



ENAME SAL

---------- ----------

XYZ 1600

WARD 1250

MARTIN 1250

XYZ 2850

XYZ 1500

XYZ 9999



6 rows selected.



SQL> select * from view_30;



ENAME SAL

---------- ----------

XYZ 1600

WARD 1250

MARTIN 1250

XYZ 2850

XYZ 1500

XYZ 9999




كما رأينا سابقا ... انه يستمد بياناته من جدول emp_30 ,,


لو حذفنا emp_30 ؟؟ لنرى ماذا يحصل في المنظر view_30





SQL> drop table emp_30;



Table dropped.



SQL> select * from view_30;





ERROR at line 1:

ORA-04063: view "SCOTT.VIEW_30" has errors




بعد حذف الجدول الاساس للمنظر view_30 ... وبعد اصدار امر عرض هذا المنظر ... يقول ان المنظر فيه خطأ !! .. لا يهتم الأوراكل ما هذا الخطأ انما ... يقول انه خطأ وفقط ..... وهذا المهم بالنسبة له ..... , اما بالنسبة لنا .. فإننا نعرف ان الخطأ يكمن ان احد جداول الاساس للمنظر ... محذوف وغير موجود اصلا ..... صح ؟

طيب الان دعنا نعمل منظر view_29 والذي يستمد بياناته من الجدول المرحوم emp_30 ... هل نستطيع ؟ لنجرب ذلك :








SQL> create view view_29 as

select * from emp_30 ;



ERROR at line 2:

ORA-00942: table or view does not exist




هنا يتدخل الأوراكل بكل حزم وقوة .... ويقول انه خطأ ... وان الجدول (او المنظر !!) اصلا غير موجود ...

الان دعك من هذا الخطأ وركز في (المنظر) ....

هل تصدق ان المنظر بإمكانه ان يستمد بياناته من منظر اخر ؟؟ مسألة معقدة في التركيب سهلة الفهم .. سوف نتطرق إليها بعد ... 10 دقائق من الان ان شاء الله ....

الان اريد ان اعمل المنظر view_29 ..... ولا اريد الأوراكل ان يتدخل ....

انا اريد ان اعمل هذا المنظر .... وغدا اعمل الجدول الأساس ... انا حر .... لا اريد ان يتدخل الأوراكل !! كيف؟؟








SQL> create force view view_29 as

2 select * from emp_30;



Warning: View created with compilation errors.




أضفت كلمة جديدة ... force ... ما معنى هذه الكلمة ؟

معناها بالقوة .. بالغصب .... انا أغصبك يا أوراكل ان تعمل المنظر ولا تتدخل في شؤوني العائلية !!

هنا يصبح الأوراكل ضعيفا ويعمل المنظر ... ويعرض باستحياء ... لك رسالة يقول فيها بكل أدب ..


"تحذير يا سيدي .... المنظر عملته ولكن به بعض أخطاء "


حتى انه لم يقل هذه الاخطاء ... ونحن نعرف الاخطاء وهي عدم وجود الجدول الأساس ...


الان هل عرفت كيف تجبره ؟ جميل ..... لاحظ أين تضع كلمة force ...


الان ... دعنا نغير اسماء الاعمدة للمنظر !!

مجرد تغيير للأسماء , وفائدته تكمن في العرض ليس الا .... ولكن الاعمدة اصلا تستمد بياناتها من الجدول الأساس ولا يوجد أي تغيير في البيانات نفسها .





create view view_10 as

select ename as "Name" , sal as "Salary"

from emp where deptno=10;




في الحقيقة اكتشفت شيء بالصدفة , لم اجربه من قبل ...

الان انظر الى اسماء الاعمدة :





SQL> select * from view_10;



Name Salary

---------- ----------

CLARK 2450

KING 5000

MILLER 1300




هل شاهدت اسماء الاعمدة كيف تغيرت ؟؟ مع العلم ان البيانات لم تتغير ولا نوعها !! مجرد اسم العمود .....

هيا ... انظر لو كتبنا مايلي :





SQL> select salary from view_10;





ERROR at line 1:

ORA-00904: "SALARY": invalid identifier




يقول انه لا يوجد عمود بهذ الاسم !! يا عالم اقسم انني اسميته هكذا !!

حققنا في الامر , ووجدنا العمود المتهم لا يحمل اسم salary ,,,,,


انما يحمل اسم Salary وكتبنا ما يلي :





select "Salary" from view_10;




هل لاحظت الوضع ؟

يفضل اذا عملت الاعمدة ... اعملها هكذا ... ولاحظ الفرق :





create view view_100 as

select ename emp_name , sal salary

from emp where deptno=10;




هل لاحظت التسميات ؟ اخذناها سابقا ... ول اردنا عمل اسماء كما هي ... ضعها بين علامتي تنصيص ثنائية "Salary"


ولا انصح بذلك طبعا ....

الان لنغير المنظر view_10 ونستبدل اسماء لاعمدته ... هيا بنا :








SQL> create view view_10 as

select ename emp_name , sal salary

from emp where deptno=10 ;



ERROR at line 1:

ORA-00955: name is already used by an existing object




نسيت !!

لقد عملناه سابقا ولا يمكننا ان نعمله مرة ثانية بنفس اسمه !

هيا لنستبدله بأمر replace ,,,, أي اذا لم يجد الأوراكل المنظر .. اعمله ..

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





SQL> create or replace view view_10 as

select ename emp_name , sal salary

from emp where deptno=10 ;



View created.




وهكذا عملناه ....

ياسلام ... على امر الاستبدال .. or replace


الان اريد ان اعمل المنظر view_29 .... هل تذكره ؟؟ ذلك المنظر الذي يحتوي على جدول غير موجود !! ارجع عدة سطور ... وستشاهده ... واننا غصبنا الأوراكل !!

هيا لنستبدله .... بجدول اخر لا يوجد في الاصل ...





SQL> create or replace view view_29

as select * from emp_10000 ;



ERROR at line 2:

ORA-00942: table or view does not exist




عملية الاستبدال قبلها , ولكن لم يقبل ان يكون هناك جدول غير موجود !!

هيا لنجبره على ذلك .. ولحظ تركيب الجملة كاملة ... ولاحظ لماذا انا أعيد الأمثلة !! طبعا لكي اعملها هذه المرة مجتمعة .. انظر الى الاستبدال أين يأتي , واين يأتي الاجبار force ... تعلم يا رجل !





SQL> create or replace force view view_29

2 as select * from emp_10000;



Warning: View created with compilation errors.

The Coder
19-02-2006, 04:43 AM
أضفت كلمة جديدة ... force ... ما معنى هذه الكلمة ؟


معناها بالقوة .. بالغصب .... انا أغصبك يا أوراكل ان تعمل المنظر ولا تتدخل في شؤوني العائلية !!


هنا يصبح الأوراكل ضعيفا ويعمل المنظر ... ويعرض باستحياء ... لك رسالة يقول فيها بكل أدب ..


"تحذير يا سيدي .... المنظر عملته ولكن به بعض أخطاء "


حتى انه لم يقل هذه الاخطاء ... ونحن نعرف الاخطاء وهي عدم وجود الجدول الأساس ...


الان هل عرفت كيف تجبره ؟ جميل ..... لاحظ أين تضع كلمة force ...


الان ... دعنا نغير اسماء الاعمدة للمنظر !!


مجرد تغيير للأسماء , وفائدته تكمن في العرض ليس الا .... ولكن الاعمدة اصلا تستمد بياناتها من الجدول الأساس ولا يوجد أي تغيير في البيانات نفسها .






create view view_10 as


select ename as "Name" , sal as "Salary"


from emp where deptno=10;





في الحقيقة اكتشفت شيء بالصدفة , لم اجربه من قبل ...


الان انظر الى اسماء الاعمدة :






SQL> select * from view_10;





Name Salary


---------- ----------


CLARK 2450


KING 5000


MILLER 1300





هل شاهدت اسماء الاعمدة كيف تغيرت ؟؟ مع العلم ان البيانات لم تتغير ولا نوعها !! مجرد اسم العمود .....


هيا ... انظر لو كتبنا مايلي :






SQL> select salary from view_10;








ERROR at line 1:


ORA-00904: "SALARY": invalid identifier





يقول انه لا يوجد عمود بهذ الاسم !! يا عالم اقسم انني اسميته هكذا !!


حققنا في الامر , ووجدنا العمود المتهم لا يحمل اسم salary ,,,,,


انما يحمل اسم Salary وكتبنا ما يلي :






select "Salary" from view_10;





هل لاحظت الوضع ؟


يفضل اذا عملت الاعمدة ... اعملها هكذا ... ولاحظ الفرق :






create view view_100 as


select ename emp_name , sal salary


from emp where deptno=10;





هل لاحظت التسميات ؟ اخذناها سابقا ... ول اردنا عمل اسماء كما هي ... ضعها بين علامتي تنصيص ثنائية "Salary"


ولا انصح بذلك طبعا ....


الان لنغير المنظر view_10 ونستبدل اسماء لاعمدته ... هيا بنا :









SQL> create view view_10 as


select ename emp_name , sal salary


from emp where deptno=10 ;





ERROR at line 1:


ORA-00955: name is already used by an existing object





نسيت !!


لقد عملناه سابقا ولا يمكننا ان نعمله مرة ثانية بنفس اسمه !


هيا لنستبدله بأمر replace ,,,, أي اذا لم يجد الأوراكل المنظر .. اعمله ..


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






SQL> create or replace view view_10 as


select ename emp_name , sal salary


from emp where deptno=10 ;





View created.





وهكذا عملناه ....


ياسلام ... على امر الاستبدال .. or replace


الان اريد ان اعمل المنظر view_29 .... هل تذكره ؟؟ ذلك المنظر الذي يحتوي على جدول غير موجود !! ارجع عدة سطور ... وستشاهده ... واننا غصبنا الأوراكل !!


هيا لنستبدله .... بجدول اخر لا يوجد في الاصل ...






SQL> create or replace view view_29


as select * from emp_10000 ;





ERROR at line 2:


ORA-00942: table or view does not exist





عملية الاستبدال قبلها , ولكن لم يقبل ان يكون هناك جدول غير موجود !!


هيا لنجبره على ذلك .. ولحظ تركيب الجملة كاملة ... ولاحظ لماذا انا أعيد الأمثلة !! طبعا لكي اعملها هذه المرة مجتمعة .. انظر الى الاستبدال أين يأتي , واين يأتي الاجبار force ... تعلم يا رجل !






SQL> create or replace force view view_29


2 as select * from emp_10000;





Warning: View created with compilation errors.





الان هل ما زلت تذكر المنظر temp ؟


هيا لننظر ما بداخله :






SQL> select * from temp;





ENAME SAL DEPTNO


---------- ---------- ----------


ALLEN 1600 30


WARD 1250 30


JONES 2975 20


MARTIN 1250 30


BLAKE 2850 30


CLARK 2450 10


SCOTT 3000 20


KING 5000 10


TURNER 1500 30


FORD 3000 20


MILLER 1300 10





الان انا استخدم معلومات كل من رقم قسمه يساوي 30 ... أي بمعنى اخر ... اريد ان اعمل منظر اخر ..


به نفس معلومات المنظر temp ولكن لكل من رقم قسمه يساوي 30


ما رأيك ان نعمل منظر اساسه منظر اخر وليس جدول !!


طبعا لديك الخيار .. من جدول او من منظر :






create view temp2 as


select ename , sal from temp


where deptno=30 ;





بسيطة هاه ... اخترنا عمودين من المنظر temp واخترنا بعض الصفوف .... أي بعض المعلومات ...


قلنا سابقا ان المنظر temp .... هو ناتج استعلام التالي :






select ename , sal , deptno


from emp


where sal > 1100 ;





صحيح ؟ طيب ... استعلام المنظر temp2 ماهو ؟؟ أي الاستعلام الذي بداخله ... أي هو ناتج من الاستعلام التالي


انظر اليه :






select ename , sal from temp


where deptno=30 ;





صحيح ؟


ماذا سوف يفعل الأوراكل اذا شاهد جملة الاستفسار هذه ؟ ؟ ؟






SQL> select * from temp2 where sal >1250;





ENAME SAL


---------- ----------


ALLEN 1600


BLAKE 2850


TURNER 1500





كيف عرف النتيجة ؟ ما هي الخطوات الخفية ؟؟ فكرو يا عالم .. كيف يشتغل الأوراكل ..


انا اذا قلت لك خطوات خفية يعني الخطوات التي عملها أوراكل .... انا في الحقيقة لا اعرفها !! ولكن استنتجها دائما !! هل تتصور ؟ بامكانك ان تستنتجها انت ايضا ... الان انظر اذا يحدث في رأيي ...


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









select * from temp2 where sal >1250;





- يرى هل الجدول موجود ؟


طبعا لا ...


-يرى هل هو منظر ؟؟


نعم ... هو منظر ... ... سوف يضع النقطة أ في هذه الخطوة ...


- يفتح ملف هذا المنظر الذي يسمى بـ temp2


يجد فيه استعلام ... مكتوب هكذا :






select ename , sal from temp


where deptno=30 ;








- يقول ... "سوف انفذ هذه الجملة ..."


- يرى هل الجدول temp موجود ؟؟ طبعا لا ..


- يرى هل هو منظر ؟؟ نعم يجده منظر ... وسوف يضع نقطة ب في هذه الخطوة ....


- يفتح الملف الذي يدعى بالمنظر temp


- يجد به استفسار ... وهو :






select ename , sal , deptno


from emp


where sal > 1100 ;











- يقول في نفسه : " سوف انفذ هذا الاستفسار ..."


-هل الجدول emp موجود ؟؟ طبعا موجود .... ينفذه ويخزن الناتج ...


وكان الناتج هو مايلي :






ENAME SAL DEPTNO


---------- ---------- ----------


ALLEN 1600 30


WARD 1250 30


JONES 2975 20


MARTIN 1250 30


BLAKE 2850 30


CLARK 2450 10


SCOTT 3000 20


KING 5000 10


TURNER 1500 30


FORD 3000 20


MILLER 1300 10

The Coder
20-02-2006, 08:57 PM
- يأتي ويرجع بالنتيجة الى النقطة ب ....


- يرى الاستفسار الخاص بـالمنظر temp2 .... هل يتذكره ؟؟ نعم ... انه هذا الاستفسار :





select ename , sal from temp

where deptno=30 ;








- ياسلام ... هو لديه الناتج الخاص بالمنظر temp2 مخزن !! صح ؟

الان من هم الذين في قسم 30 في الناتج التالي ؟؟:





ENAME SAL DEPTNO

---------- ---------- ----------

ALLEN 1600 30

WARD 1250 30

JONES 2975 20

MARTIN 1250 30

BLAKE 2850 30

CLARK 2450 10

SCOTT 3000 20

KING 5000 10

TURNER 1500 30

FORD 3000 20

MILLER 1300 10






- سوف ينتقي كل من هو في القسم 30 في النتيجة السابقة للتو ..

انهم مايلي :





ENAME SAL

---------- ----------

ALLEN 1600

WARD 1250

MARTIN 1250

BLAKE 2850

TURNER 1500






- الان يرجع بالنتيجة للنقطة أ


- هنالك ... يجد انه طلب من هذه النتيجة السابقة كل مم راتبه اكبر من 1250

أي في جملة الاستفسار تلك هل تذكرها ؟؟ :





select * from temp2 where sal >1250;




- سوف ينتقي من الناتج الاخير كل من راتبه فوق 1250

وسوف يكون الناتج الاخير هكذا :





ENAME SAL

---------- ----------

ALLEN 1600

BLAKE 2850

TURNER 1500







ركز وارجع اقرأ الخطوات كيف !!

كل مافي الامر ... يذهب الى استفسار ويرجع بناتجه ... حتى الاستفسار الاصلي ....هذا كل شيء ...

طبعا سوف يخزن كل نتيجة في متغيرات !! ....

هل شاهدت كم هي متعبة على أوراكل هذه المناظر ؟ بالرغم من انها سهلة لنا ..

فما بالك ان نستعلم من منظر .. اساسه منظر اخر ... وهذا المنظر الاخر اساسه منظر ثالث ... والمنظر الثالث اساسه منظر عاشر ....... الخ

سوف يتعب الأوراكل مسكين .. ولكن سوف يأتي بالنتائج بسرعة لا تحس بها في اغلب الاحيان ...

انظر الى هذا المنظر المعقد التالي ... ولاحظ ان به طريقة اخرى غير التي درستك اياها قبل قليل ... في تسمية الاعمدة :










create view v1 (the_name , the_depart , the_sal , the_grade_sal)

as select e.ename , d.dname ,e.sal ,s.grade

from emp e,dept d ,salgrade s

where e.deptno=d.deptno

and e.sal between s.losal and s.hisal

and e.sal >=1250 ;




انظر اليه عن كثب :





SQL> select * from v1 ;



THE_NAME THE_DEPART THE_SAL THE_GRADE_SAL

---------- -------------- ---------- -------------

WARD SALES 1250 2

MARTIN SALES 1250 2

MILLER ACCOUNTING 1300 2

TURNER SALES 1500 3

ALLEN SALES 1600 3

CLARK ACCOUNTING 2450 4

BLAKE SALES 2850 4

JONES RESEARCH 2975 4

SCOTT RESEARCH 3000 4

FORD RESEARCH 3000 4

KING ACCOUNTING 5000 5




ولاحظ انه في إنشاء المناظر لا يوجد شيء اسمه order by


برأيك لماذا ؟؟ لماذا ممنوع استخدام order by في جملة إنشاء المناظر ؟؟؟

فكر فيها ... واجعلها تحدي ... التحدي الاول !! ....





الان .. قلنا انه سوف يفتح ملف المنظر .... عدنا هذه المقولة كثيرا !!

أين يوجد هذا الملف ؟ في الحقيقة انه مخزن في قواعد بيانات !! ملف قواعد بيانات ...

بالتحديد في Data dictionary هل تذكرها ؟ التي تحتوي على مجموعة جداول تخص الأوراكل والتي يتعامل معها الأوراكل .... اعتقد انك تذكر هذه المجموعة جداول !!

ما اسم الجدول الذي يحتوي المناظر الخاصة بنا ؟؟








SQL> select * from user_views;



VIEW_NAME TEXT_LENGTH TEXT

--------------- ----------- -------------------------------------

VIEW_20 64 select ename employee_name , sal salary

from emp where deptno=10



VIEW_100 59 select ename emp_name , sal salary

from emp where deptno=10



VIEW_2 39 select "ENAME","SAL","DEPTNO" from temp

TEMP2 46 select ename , sal from temp

where deptno=30



V1 150 select e.ename , d.dname ,e.sal ,s.grade

from emp e,dept d ,salgrade s

where e.d



TEMP 54 select ename , sal , deptno

from emp

where sal > 1100



VIEW_30 32 select "ENAME","SAL" from emp_30

VIEW_29 23 select * from emp_10000

VIEW_10 60 select ename emp_name , sal salary

from emp where deptno=10




اسف على العرض السيء ....

يوجد هنالك بعض العيوب والغباء في برنامج sql plus


انظر في جملة الاستعلام الخاصة بالمنظر V1


كأنها ناقصة كثيرا !!

لماذا يا ترى ؟؟ لا اعلم !!

مجرد عيب في البرنامج نفسه !!





الان اليك التحدي الخياري الثاني ..


انا كنت اشرح الخطوات الخفية لأوراكل ... وكنت أقول ... يفتح ملف المنظر الفلاني ... ويفتح ملف المنظر الفلاني ..

انا علمتك أين هو هذا الملف .... الان اعد خطوات الشرح نفسها .. ولكن بطريقتك ... ولا اريد منك ان تقول "سوف يفتح الملف الفلاني" !! .... اريدك ان تشرح لي كيف يفتح الملف هذا .. وكيف يستخرج جملة الاستعلام منه ... اعرف ان الشرح ممل ... ولكن لك الخيار في حل السؤال او لا ... و انا اعذرك ان لم تحل .. فأعرف انك فاهم ولكن لا تملك الوقت ... واذا لم تكن فاهم .. فهي فرصتك !!





الان سوف نعمل جدول ... يدعى emp_100 , وهو جدول اساس لمنظر نعمله ويدعى v2







SQL> create table emp_100

as select ename , sal , deptno

from emp where sal>1250 ;



Table created.



SQL> select * from emp_100;



ENAME SAL DEPTNO

---------- ---------- ----------

ALLEN 1600 30

JONES 2975 20

BLAKE 2850 30

CLARK 2450 10

SCOTT 3000 20

KING 5000 10

TURNER 1500 30

FORD 3000 20

MILLER 1300 10



9 rows selected.



SQL> create view v100 as

select * from emp_100

where deptno=20;



View created.



SQL> select * from v100;



ENAME SAL DEPTNO

---------- ---------- ----------

JONES 2975 20

SCOTT 3000 20

FORD 3000 20






الان المنظر v2 ناتج من الاستعلام التالي :








select * from emp_100

where deptno=20;




صح ؟

The Coder
20-02-2006, 09:03 PM
طيب ... لو عملنا ترتيب order by ... مالذي يحدث ؟ انظر !!





SQL> select rownum , ename , sal from emp

2 order by sal ;



ROWNUM ENAME SAL

---------- ---------- ----------

1 SMITH 800

12 JAMES 950

11 ADAMS 1100

3 WARD 1250

5 MARTIN 1250

14 MILLER 1300

10 TURNER 1500

2 ALLEN 1600

7 CLARK 2450

6 BLAKE 2850

4 JONES 2975

8 SCOTT 3000

13 FORD 3000

9 KING 5000




مشكلة هاه .. اريد ان يكون ترتيب على حسب الراتب !! كيف ؟ انظر الى حل ممتاز :








SQL> select rownum , ename , sal

2 from (select ename , sal from emp order by sal) ;



ROWNUM ENAME SAL

---------- ---------- ----------

1 SMITH 800

2 JAMES 950

3 ADAMS 1100

4 WARD 1250

5 MARTIN 1250

6 MILLER 1300

7 TURNER 1500

8 ALLEN 1600

9 CLARK 2450

10 BLAKE 2850

11 JONES 2975

12 SCOTT 3000

13 FORD 3000

14 KING 5000




لا تعلم مالفكرة ؟ فكر فيها ...

في الحالة الاولى اوجد الأوراكل الناتج ... وحسب قيم دالة الـ rownum


ثم رتب الناتج .. وتلخبطت بيانات العمود rownum


في الحالة الثانية ... اعطينا الدالة ... جدول مرتب ومنظم يعني جاهز ... (الاستفسار الفرعي ويعامل كجدول !!)

وهو في النهاية حسب قيم الدالة ..

اعرف انها تلخبط .... ولكن تمرس عليها قليلا وجرب قليلا .. واتعب قليلا ..

اعرف ان الاجابة في رأسك ....

وعليك ايجادها .











3- السلسلة sequences


السلسلة عبارة عن اوبجيكت ... محفوظ لغرض ما ..

غرضه غريب قليلا , وهو لتوليد ارقام للمفتاح الأساسي ...

ما معنى توليد ؟؟ إنشاء اوتوماتيكي ... اختراع ارقام جديدة بطريقة منتظمة .......

ولماذا نستخدمها ؟ انا عندي الف قسم .. في جدول الأقسام ... مارأيك لو يكون عندي مولد للارقام بطريقة منتظمة ؟؟

تخيل انك لا تعرف اخر قسم ماهو ... كم رقمه ... مثلا رقم اخر قسم اضفناه هو 150 .. الذي بعده ماهو ؟ على حسب .. يمكن احدهم يرغب بزيادة واحد .. واخر يرغب بزيادة عشرة ...

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





create table dept1 as

select * from dept ;




الان جدولنا الجديد هو dept1 ....


نلاحظ ان المفتاح الأساسي في هذا الجدول يتزايد بشكل منتظم صح ؟؟ انظر ... انه يزيد في كل مرة ب 10 :





SQL> select * from dept1;



DEPTNO DNAME LOC

---------- -------------- ------------

10 ACCOUNTING NEW YORK

20 RESEARCH DALLAS

30 SALES CHICAGO

40 OPERATIONS BOSTON




10 ثم 20 ثم 30 ثم 40 ........ مارأيك في العدد القادم ؟؟ اكيد 50 .... انه يتزايد بطريقة منتظمة ...

ما معنى منتظمة ؟ أي بشكل لا يتغير ... هنا زيادة عشرة في كل مرة ..

اذا رغبت في احد اعمدة جدولك اكرر .. احد اعمدة جدولك ... بهذه الصورة المنتظمة ... فانصحك بالسلسلة ... وعلى حسب ما تريد ....

لأنه في بعض الاحيان نحتاج برنامج يولد لنا ارقام المفتاح الأساسي !! مثلا بعضهم يريد رقم الموظف ان يكون مكون من اول ثلاث ارقام من رقم الهوية , اول رقمين من تاريخ ميلاده , اول ثلاث حروف من اسمه ... هذا مجرد مثال ...

هيا لنعمل مولد ارقام منتظم ..... اليك امر عمل السلاسل ..:





SQL> create sequence dept1_deptno_seq

2 increment by 10

3 start with 50

4 maxvalue 150

5 nocache

6 nocycle;




واو ... يظهر انه طويل قليلا ..

الان اريدك ان تنتبه الى هدفنا ... وهو إنشاء سلسلة .. إنشاء مولد ارقام .... له موصفات قياسية ..

انا اريد هذه المواصفات ما يلي ... ان يبدأ المولد بـ50 , ويصل الى 150 اخر حد له ... لانني اعرف ان الأقسام مهما كثرت لن تزيد عن 15 قسم ..... اريد ان يزيد العدد ب 10 ارقام .. أي ان الاول 50 .. الثاني يصبح 60 ... وهكذا ...




اول سطر .. يقول اعمل لي .... سلسلة تدعى بـ dept1_deptno_seq..... مجرد اسم .. انا اخترته بنفسي

يا عالم ... سمو المتغيرات , والجداول .. وسمو السلاسل , وسمو المناظر .... وحتى سمو ابنائكم باسماء تشير الى شيء وتعني لكم شيء ... تخيل واحد سمى جدول الموظفين a ؟؟؟؟ وبعد شهرين ... افتكر يا صاحبي ... ماهو اسم الجدول .... وقد نسيه فعلا !! .. انا سميت dept1_deptno_seq لانه يشير الى اسم الجدول ثم اسم العمود ثم يشير الى اول ثلاث حروف من كلمة السلسلة .. اعرف انها تسمية عبيطة .. لكن بالنسبة لي اعتقد انني لن انساها ان شاء الله ... لاني اسمي الاشياء بهذا الشكل .

الان ... السطر الثاني يقول ... زد على القيمة الحالية 10 في كل مرة .... مثلا كنا 50 .... في المرة القادمة تصير 60 ...

اعرف انك لا تعرف مالذي اتحدث انا عنه ...


السطر الثالث .... يقول نبدأ بكم ؟؟ بـ50 كما اتفقنا ...

السطر الرابع اكبر قيمة يمكن ان يكون بها المولد كم ؟؟ 150 كما اتفقنا ..

السطر الخامس لست افهم ما معناها , لم توضح لي الرؤية فيها .. اسف !!

السطر السادس ... كتبت انا فيه nocycle ... أي اذا وصل اكبر قيمة .. خلاص .... لا ترجع من الاول ... انا اريد حياتك تنتهي يا مولد الارقام dept1_deptno_seq ..... لو اردته ان يرجع ويولد من جديد نفس الارقام .. اكتب cycle


طبعا يا رجل كيف تقول ... cycle مع المفتاح الأساسي !! سوف تتكرر أي اننا وصلنا مثلا 150 .... فسوف يرجع الى 50 !! أي اننا سوف نضيف 50 مرة ثانية وهي قيمة موجودة ....والمفتاح الأساسي لا يقبل التكرار !!


اذن هذا الخيار لا يصلح مع المفتاح الأساسي .... يصلح مع عمود اخر ..

الان دعنا نستخدم هذه السلسلة ... تستخدم في اماكن عدة ... هيا لنرى في امر إضافة صف :








insert into dept1 values

(dept1_deptno_seq.nextval ,'MARKETING','SAN DIEGO');




هل رأيت اسم السلسلة ؟ يوجد شيء وكأنه دالة ... nextval ... وهي اختصار لـ next value معناها القيمة التالية ...

السلسلة سوف تبدأ بـ 50 ...... سوف تضع خمسين ....

أي بمعنى اخر .... اضفنا صف ... واضفنا قيم ... اسم القسم MARKETING , وموقعه SAN DIEGO


ورقم القسم كم ؟؟ انه 50 .... لاننا اول مرة نستخدم السلسلة ... انظر الناتج للتأكد ...





SQL> select * from dept1;



DEPTNO DNAME LOC

---------- -------------- -----------

10 ACCOUNTING NEW YORK

20 RESEARCH DALLAS

30 SALES CHICAGO

40 OPERATIONS BOSTON

50 MARKETING SAN DIEGO




الان نريد ان ندخل المزيد ... فلنرى هل يتغير الـ 50 ؟؟؟

انظر ... سوف اضيف مرات عديدة لنفس الجملة :





SQL> insert into dept1 values

2 (dept1_deptno_seq.nextval ,'MARKETING','SAN DIEGO');



1 row created.



SQL> insert into dept1 values

2 (dept1_deptno_seq.nextval ,'MARKETING','SAN DIEGO');



1 row created.



SQL> insert into dept1 values

2 (dept1_deptno_seq.nextval ,'MARKETING','SAN DIEGO');



1 row created.



SQL> insert into dept1 values

2 (dept1_deptno_seq.nextval ,'MARKETING','SAN DIEGO');



1 row created.



SQL> insert into dept1 values

2 (dept1_deptno_seq.nextval ,'MARKETING','SAN DIEGO');

(dept1_deptno_seq.nextval ,'MARKETING','SAN DIEGO')

*

ERROR at line 2:

ORA-01438: value larger than specified precision allows for this column



اضفتها اربع مرات .. والخامسة رفض ؟؟

The Coder
20-02-2006, 09:05 PM
لنرى لماذا .. :





SQL> select * from dept1 ;



DEPTNO DNAME LOC

---------- -------------- -----------

10 ACCOUNTING NEW YORK

20 RESEARCH DALLAS

30 SALES CHICAGO

40 OPERATIONS BOSTON

50 MARKETING SAN DIEGO

60 MARKETING SAN DIEGO

70 MARKETING SAN DIEGO

80 MARKETING SAN DIEGO

90 MARKETING SAN DIEGO




اها ... يظهر ان السلسلة وصلت الرقم 100 , وهو مرفوض في العمود deptno لان حده خانتين فقط ...

انظر الى القيمة الحالية التي تقف السلسلة عليها ... باستخدام دالة اخرى تدعى بـ currval اختصارا لـ current value أي القيمة الحالية ..





SQL> select dept1_deptno_seq.currval from dual;



CURRVAL

----------

100




انظر لهذه .. وصل للمئة ... هيا لنحذف السلسلة ....





SQL> drop sequence dept1_deptno_seq ;



Sequence dropped.




لقد حذفناها ... ولكن هل ستحذف معها القيم التي وضعتها ؟؟ انظر :





SQL> select * from dept1;



DEPTNO DNAME LOC

---------- -------------- -----------

10 ACCOUNTING NEW YORK

20 RESEARCH DALLAS

30 SALES CHICAGO

40 OPERATIONS BOSTON

50 MARKETING SAN DIEGO

60 MARKETING SAN DIEGO

70 MARKETING SAN DIEGO

80 MARKETING SAN DIEGO

90 MARKETING SAN DIEGO




لم تحذف ... لسبب بسيط وانت تعرفه ..

هي دالة تعطينا قيم وتمشي ... يعني اننا حينما قلنا سابقا :





insert into dept1 values

(dept1_deptno_seq.nextval ,'MARKETING','SAN DIEGO');






وكانت مثلا القيمة الحالية 80 .... فهي تضع 80 في الصف , وتخزن 90 بداخلها كقيمة حالية .... واذا استخدمناها ثانية .. تضع قيمة 90 وتخزن بداخلها 90+10=100 .... وهكذا

السلسلة ليست الا ملف ... اوبجيكت .... يعني شيء مخزن ... وعملها اعطائنا ارقام منتظمة ... ليس الا ,,,

ارجو ان تكون فاهم انها ليست بتلك التعقيد .





الان مثال اخر لكي نفهم بعض خصائص هذه السلاسل ...

دعنا نحذف سلسلتنا لهذا الصباح ...





drop sequence dept1_deptno_seq ;










delete dept1;




لنعمل سلسلتين ....واحدة لرقم القسم والاخرى لاسم القسم ... مثلا اريد اسماء اقسام وليكن ارقام ... مثلا يعني ...

والان لننظر كيف يصبح الوضع ...








SQL> create sequence dept1_depno_seq

2 increment by 1

3 start with 5

4 maxvalue 40

5 nocache

6 nocycle;



Sequence created.



SQL> create sequence dept1_dname_seq

2 increment by 2

3 start with 6

4 minvalue 0

5 maxvalue 12

6 nocache

7 cycle;



Sequence created.










SQL> insert into dept1 values

2 ( dept1_depno_seq.nextval , dept1_dname_seq.nextval ,'any');



1 row created.



SQL> insert into dept1 values

2 ( dept1_depno_seq.nextval , dept1_dname_seq.nextval ,'any');



1 row created.



SQL> insert into dept1 values

2 ( dept1_depno_seq.nextval , dept1_dname_seq.nextval ,'any');



1 row created.



SQL> insert into dept1 values

2 ( dept1_depno_seq.nextval , dept1_dname_seq.nextval ,'any');



1 row created.



SQL> insert into dept1 values

2 ( dept1_depno_seq.nextval , dept1_dname_seq.nextval ,'any');



1 row created.



SQL> insert into dept1 values

2 ( dept1_depno_seq.nextval , dept1_dname_seq.nextval ,'any');



1 row created.



SQL> insert into dept1 values

2 ( dept1_depno_seq.nextval , dept1_dname_seq.nextval ,'any');



1 row created.



SQL> insert into dept1 values

2 ( dept1_depno_seq.nextval , dept1_dname_seq.nextval ,'any');



1 row created.



SQL> insert into dept1 values

2 ( dept1_depno_seq.nextval , dept1_dname_seq.nextval ,'any');



1 row created.



SQL> select * from dept1;



DEPTNO DNAME LOC

---------- -------------- -------------

5 6 any

6 8 any

7 10 any

8 12 any

9 0 any

10 2 any

11 4 any

12 6 any

13 8 any



9 rows selected.




فكر قليلا ... لماذا النتيجة الاخيرة اصبحت هكذا ... انا اخص اسم القسم ....

لماذا يا ترى صارت هكذا ؟؟ بدأت بستة , وانتهت الى ال 12 , ومن ثم رجعت صفر !!

لماذا لم ترجع ستة ؟ لاننا قلنا minvalue تساوي صفر ... ولماذا يا ترى حينما وصلنا القيمة الكبرى رجعت من جديد ؟ لاننا قلنا cycle , وهل يجب ان يكون start by اكبر من او يساوي minvalue ؟؟ طبعا يجب .. والا سوف يعطينا الأوراكل خطأ ....





الان تحدي ..... فسر ما الذي حصل في هذه الأوامر التالية :





SQL> select * from dept1;



DEPTNO DNAME LOC

---------- -------------- -------------

5 6 any

6 8 any

7 10 any

8 12 any

9 0 any

10 2 any

11 4 any

12 6 any

13 8 any



9 rows selected.



SQL> update dept1 set dname=dept1_dname_seq.nextval ;



9 rows updated.



SQL> select * from dept1;



DEPTNO DNAME LOC

---------- -------------- -------------

5 10 any

6 12 any

7 0 any

8 2 any

9 4 any

10 6 any

11 8 any

12 10 any

13 12 any



9 rows selected.

The Coder
20-02-2006, 09:19 PM
بقي عليك ان تعرف متى نستطيع استخدامها ومتى لا نستطيع ... نستطيع في الاستعلام الرئيسي .. نستطيع في الاستعلام الفرعي الذي يأتي مع جملة insert ... نستطيع مع جملة Insert ... نستطيع مع جملة update ...


لا نستطيع مع جملة الاستعلام التي تأتي مع إنشاء المناظر , لا نستطيع اذا اتت كلمة distinct .. والتي تلغي التكرار يا سادة ...... ولا نستطيع مع جملة الاستعلام اذا كان فيها أي من group by , having , order by


ولا نستطيع مع جملة الاستعلام الفرعية التي تأتي مع جملة select او تاتي مع جملة delete او حتى تأتي مع update


وطبعا لا نستطيع ان نستخدمها مع جملة ALTER او CREATE ....


كتبت هذه السطور إبراء للذمة ...

ونسيت ان هنالك جدول في الـ Data Dictionary يسمى user_sequences






SQL> select * from user_sequences;




SEQUENCE_NAME MIN_VALUE MAX_VALUE INCREMENT_BY C O CACHE_SIZE LAST_NUMBER

------------------------------ ---------- ---------- ------------ - - ---------- -----------

DEPT1_DNAME_SEQ 0 12 2 Y N 0 14

DEPT1_DEPNO_SEQ 1 40 1 N N 0 14











4- الادلة او الفهارس index


تفيدنا الفهارس في كل كتاب ... سرد العناوين للوصول السريع للمعلومة صح ؟

طيب .. يوجد طريقة تسرع من استرجاع البيانات ... بجملة select .... طبعا انا اتكلم عن النظام ... يعني هذه الطريقة تسرع النظام .. طبعا نحن نعمل على جدول صغير جدا جدا جدا ...... مقارنة مع جداول الشركات والتي لما رأيت احدها ... اصابني القشعريرة ...

حينما نكتب select * from …. فإننا نحصل على المعلومات بسرعة .. لكن لو كانت الجداول كبيرة جدا ... فسوف تلاحظ الفرق في الزمن ... هذا وانت تعمل لوحدك على جهاز ... فما بالك بموظفين متعددين يعملون على جهاز سيرفر واحد ؟؟ طبعا السيرفر بيخدم هذا الموظف.... وينتهي بسرعة منه ويتوجه بسرعة الى الاخر .. وينتهي بنصف عمل الاخر .. ويتوجه الى ثالث .. ويعود الى الثاني .... وهكذا .. طبعا السيرفرات خارقة , ولكن بعض الاحيان الضغط يتغلب على قوته ....





الان يوجد طريقة من الممكن ان تكون مفيدة , تسرع استرجاع البيانات بشكل ملحوظ .. ونستطيع عمل هذه الطريقة على الاعمدة .. وليست على الجدول .. أي نعمل فهرسة على الاعمدة ....

لكن هذه الطريقة محدودة في شروط .. ما هي الشروط ؟ انظر اليها :

1- ان يكون الجدول كبير ... وان يكون المتوقع من استخدام جملة select ان نحصل على 2-4% من عدد الصفوف الكلي .. أي اذا كان لدينا 10000 صف ... لو كنا نسترجع عادة .. 400 صف .... 350 صف ... او 200 صف او حتى اقل ... فنستخدم الطريقة هذه .. والا فلن تحس بالفرق .


2- ان يكون العمود الذي سنعمل له الفهرسة ..يكون ذو خانات ضخمة ... أي مثلا هو رقم .. يكون هكذا مثلا number(20) .. مجرد مثال , مفيدة الطريقة مع هذا الشرط ..

3- ان يحتوي هذا العمود على قيم فارغة كثيرة ...

4- ان يستخدم هذا العمود .. في جملة where كثيرا ,, أي نضعه كشرط كثيرا .. لاننا اذا وضعنا أي عمود في جملة الشرط , فإنه سوف يقرأ كل قيمه موجودة به . فإذا عملنا فهرسة ... فلن يقرأه كله .. بل بطريقته الخاصة .. سوف يطبق الشرط بأسرع ما يكون ....

5- اذا كانا عمودين ... يجب ان تنطبق عليهما الشروط السابقة ... وايضا يزيدان شرط وهو ان نستخدمهما بكثرة في الـربط join




اعرف انك مللت ولم تفهم لماذا هذه الشروط ..

لو لم تنطبق هذه الشروط .... فإن الطريقة لا تصبح نافعة .. بل بالعكس .. تبطئ العمل !!!

صراحة حتى لو نفعت الطريقة .... فإن عملية الحذف والتعديل .. تصبحان بطيئتان .. لكن لا يهم لاننا نستخدم select اكثر بكثير من التعديل والحذف ... لذا فهي طريقة ممتازة .

انا لا استطيع استنتاج مالذي يحدث بالفعل داخل الأوراكل , ولا اريد ان استنتج شيء من الممكن ان يكون خاطئ .





كل ما اريدك ان تعرفه هو ان الفهرسة تبطئ عمليات اوامر DML وتسرع عملية استرجاع البيانات

والذي درس تقنية البرمجة ودرس مادة Data structure كاملة ... سوف يستطيع تخيل واستنتاج مالذي يحدث .

الان كيف نعمل هذه الفهرسة ؟ او هذا الدليل ؟

لنسميها ادلة .. جمع دليل ..

الادلة ننشأها بطريقتين ...

طريقة اوتوماتيكية وتسمى هذه الادلة .. بالدليل الفريد او الوحيدunique index


والطريقة اليدوية وتسمة بالدليل الغير وحيد ... nonunique index


الطريقة الاوتوماتيكية ... أوراكل يعملها اوتوماتيكي .. متى ؟ اذا وجد القيد unique والقيد primary key ...


يعني اذا عملنا جدول , ووضعنا مفتاح أساسي او عملنا unique !! فسوف تعمل اوتوماتيكي ..

لا ادري حينما ينصحني أي برنامج قواعد بيانات ... ويقول "ينصح وبشدة عمل مفتاح اجنبي" .... يقولها حتى لو لم احتاجها ... من الممكن ان المفاتيح الأساسية تسرع من عملية استرجاع البيانات ؟ لعل وعسى ...





المهم الطريقة اليدوية .. والتي غرضها تسريع عملية استرجاع البيانات بالشروط التي ذكرتها سابقا ...

هيا لنعمل على جدول الموظفين .. دليل .. وبالتحديد على عمود اسماء الموظفين ....








SQL> create index emp_ename_idx

2 on emp(ename);




واضحه هاه .. اعمل دليل اسمه emp_ename_idx وضعه أين ؟؟ على emp(ename) أي على عمود ename الذي يقطن في جدول emp ... بس ...

لست مستعد ان اجرب السرعة ... ولست مستعد ان اضع 10000 صف او اكثر ...

اذا كنت فاضي .. اعمل سلسلة توليد الارقام , وانسخ .. و ابدأ الصق الصق الصق الصق ....

حتى تكون مجموعة هائلة من الصفوف ..... اعمل استرجاع البيانات بوجود الدليل وبعدمه .. ولاحظ الفرق ان اردت ,,,,









SQL> select ename, sal from emp

2 where ename like '%S%' or ename like '%A%' ;



ENAME SAL

---------- ----------

SMITH 800

ALLEN 1600

WARD 1250

JONES 2975

MARTIN 1250

BLAKE 2850

CLARK 2450

SCOTT 3000

ADAMS 1100

JAMES 950




هنا جدولين يضمان كل معلومات الادلة الموجودة ...


User_indexes , user_ind_columns







SQL> select ic.index_name ,ic.column_name , ic.column_position,ix.uniqueness

2 from user_indexes ix , user_ind_columns ic

3 where ic.index_name =ix.index_name

4 and ic.table_name ='EMP';



INDEX_NAME COLUMN_NAME COLUMN_POSITION UNIQUENESS

-------------------------- ----------------------- -------------------- ---------------

PK_EMP EMPNO 1 UNIQUE

EMP_ENAME_IDX ENAME 1 NONUNIQUE







لو اردت حذف الدليل ... اليك الامر :








drop index emp_ename_idx ;







5- المرادفات synonym


اردت ان تقول "اعداد" .. بالانجليزي ... Preconditioning واو ... يظهر انها كلمة .. طويلة جدا ... مالعمل ؟؟

يا تحفظها وانا لله وانا اليه راجعون .. او انك تبحث عن مرادفات اخرى للكلمة .... وتكون بسيطة ... مثلا وجدنا كلمة setting أي اعداد ... نفس المعنى ... ولكن كلمة اخرى ... ماذا تفضل ؟؟ طبعا السهلة ....

ولاحظ ان لكل كلمة من الممكن ان لا يكون لها الا مترادفة واحدة .. او اكثر من مترادفة .... صح ؟؟

الان في الأوراكل .. توجد المرادفات و فائدتها فقط في تسمية الجداول المعقدة الاسم ...

يعني مثلا ... جدول طويل الاسم ... ونحن نريد ان نختصره ... ولكن نريد ان يبقى اسمه المعقد ... نستخدم مرادفات ..

واريد ان اشير ... انه ليس للجداول فقط !! بل لكل شيء يدعى اوبجيكت ..

بمعنى اخر .. تستطيع ان تستخدم المرادفات للمناظر , جداول , الادلة , السلاسل ....

صراحة انا اكره الاسماء المعقدة والمركبة ... ولكن يجب استخدامها لكي .. مثلا بعد فترة من الممكن ان تنسى الاسماء البسيطة ,,, لكن المركبة لن تنساها اذا كنت تتبع نمط واحد للتسميات ...

الان اذكر ذلك الدليل !! كان اسمه EMP_ENAME_IDX


بغيض جدا الاسم !!

هيا لنسميه a ... ما رأيك نسميه اسم اخر ؟؟ وليكن ss ... مترادفات ... اكثر من مترادفات .. يا سلام ...








SQL> create synonym ss

2 for EMP_ENAME_IDX;



Synonym created.



SQL> create synonym a

2 for EMP_ENAME_IDX;



Synonym created.




صراحة لا ارى فائدة للمترادفات الا في الجداول , السلاسل , والمناظر ...

لاننا نستخدمها بكثرة ... في الاستعلامات ... واوامر الـ DML

The Coder
20-02-2006, 09:35 PM
لنعمل مترادفة لأي جدول مثلا .... جدول emp ,,







SQL> create synonym s

2 for emp ;



Synonym created.




سميناه s ... هيا اذهب وانظر الى هذا الجدول :





SQL> select ename , sal , deptno from s where deptno=10;



ENAME SAL DEPTNO

---------- ---------- ----------

CLARK 2450 10

KING 5000 10

MILLER 1300 10




وكأنه emp .... هو نفسه انما اسم اخر ..

طبعا اسم emp جميل وصغير ولا يحتاج الى مترادفات ....

قبل ان ننتقل الى درس الصلاحيات وما شابه ..

اشير الى اننا من اول الدروس .. نعمل تحت حساب scott ...


أي اننا نعمل في جداول الحساب الخاص ب scott .....


ما معنى حساب ؟ وما معنى جداول هذا الحساب ؟

يوجد موظف افتراضي اسمه scott ..... كنا نستخدم حساب هذا الموظف ,

له رقم سري خاص .. صحيح ؟؟

هل تصدق اننا نستطيع عمل حساب اخر ؟ ونسميه ما نشاء ؟

لو عملنا حساب يسمى بـ hamzah .... وله كلمة سر خاصة ...

ودخلنا بهذا الحساب .. ماذا سيحدث اذا قلنا :





SQL> select * from emp ;




؟؟؟ الذي يحدث ان الأوراكل سيخبرنا ان الجدول غير موجود !! هل تصدق !!

مالعمل لكي نستخدم جدول موظف اخر له حساب اخر ؟؟ اليك حل :








SQL> select * from scott.emp;




ولكي نستخدم عمود ما في جدول ما تحت حساب احدهم ... نقول ما يلي ...





SQL> select scott.emp.ename from scott.emp ;




صدقني ... شكلها جميل جدا ... ولكنها طويلة جدا ....

هيا لنعمل مرادف للجدول !!





SQL> create synonym q

for scott.emp ;




الان .. اذا دخل الموظف XYZ ,, واراد ان يستخدم جدول الموظف scott ,,,فسوف يكتب مايلي ...





select q.ename from q ;




هذا كل شيء ,’,’,’

نستعرض كل ما عملناه صباح هذا اليوم ....





SQL> select * from user_synonyms ;



SYNONYM_NAME TABLE_OWNER TABLE_NAME DB_LINK

------------------------------ -------------------- ----------------------- -------

S SCOTT EMP

SS SCOTT EMP_ENAME_IDX

A SCOTT EMP_ENAME_IDX

Q SCOTT EMP




انتهى ,

....
الان .......
بقي الصلاحيات .....
انتظرو ....

The Coder
23-02-2006, 12:29 AM
سلام عليكم >< ..
سوري عالتأخير .....
نكمل الدرس للصلاحيات ....






- مستخدمون و صلاحيات :


نحن الان نعمل على جهاز واحد , أي سيرفر واحد ... ما معنى سيرفر ؟ هو برنامج خادم ... أي يخدمنا ...

يخدمنا بماذا ؟؟ يخدمنا بالذهاب الى المصادر ... او الموارد resources , مثل ماذا هذه الموارد ؟

أي شيء نحتاجه من اوبجيكت من جداول , بيانات , معلومات , واخرى ... هذه تسمى بالموارد ...


طيب ... أين هذه الموارد ؟؟ موجودة على القرص الصلب ... قرص صلب من ؟ القرص الصلب الخاص بالكمبيوتر الذي به برنامج السيرفر ...

هذه بعض الامور المزعجة ... لكن يجب ان تعرفها ...

اصلا السيرفر هو اسم يطلق على أي برنامج يحضر لنا الموارد ... ركز جيدا ...

أجهزة السيرفر .. هي أجهزة بها برامج السيرفر ... كمبيوترات عملها احضار الموارد ....

الان اذا سمعت احدهم يقول "سوف اشتري سيرفر" , صحيح انه خطأ , ولكن صارت اجهزة السيرفر تطلق عليها سيرفرات ...جمع سيرفر Server أي الخادم .. أي الملقم ...

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

جهازه هو العميل !! Client كلاينت ... الكلاينت هو البرنامج الذي يطلب من السيرفر ..

عادة يوجد سيرفر واحد , وعدة كلاينتات .... (جمع كلاينت اسف على الكتابة بالعربي ... ولكن حفاظ على الوقت ولكي تحفظ الكلمة ..)

الان كم المسافة بين الكلاينت والسيرفر ؟؟ لا نعرف ... يمكن متر .. يمكن الف ... يمكن في كوكب اخر ...

لا تضحك .. فهذه حقيقة !! .. ويجب ان تعرف اننا نستطيع ان نجعل البرنامجين في جهاز واحد أي ان المسافة بينهما هي ... لا شيء !! وهذا النوع يدعى بالسيرفر المحلي انتبه .. السيرفر المحلي !!

طيب ... اجهزة الكلاينت اجهزة تعتبر غبية ... لماذا ؟ لانها تطلب وتعرض فقط بدون ان تتعب وتبحث عن المعلومات .... هي ليست الا للعرض , وللطلب ... أي انها تكلم المستخدم وتفهم منه الطلب .. وتذهب بطريقتها الخاصة الى برنامج السيرفر ... وتطلبه !

طريقة الاتصال بين الكلاينت والسيرفر .... متعددة , واذكر هنا الانترنت احدها !! و أرخصها سعرا .. واسوأها امنا !!

طيب ... لماذا سيرفر .؟ ولماذا كلاينت ؟؟ ولماذا سيرفر وكلاينت اصلا !!

هي طريقة تنظيمية .. ليس الا ..

انها تنظم العمل ... تجعل بعضهم له صلاحية دخول الموارد , واخر لا ... توحد الموارد .. أي تجعلها واحدة ! هل معقول ان كل مستخدم لديه جدول موظفين خاص به ؟؟ جدول الموظفين خاص بالشركة ! وهو في الحقيقة جدول واحد ....





الان كيف طريقة العمل ؟

سوف اشرح طريقة السيرفر المحلي .. و نحن شغالين عليه ..

نحن حملنا سيرفر الأوراكل !!

سيرفر الأوراكل هو البرنامج الذي يدير و يخدم ويتعامل مع قواعد البيانات ...

أي اننا الان نعمل على سيرفر محلي !! اذ اجهزتنا هي الكلاينت ... وهي نفسها السيرفر ...

نطلب ... ويذهب الطلب الى برنامج السيرفر , وسوف ترجع لنا النتيجة ... وبيئتنا بيئة احادية المستخدم ... لاحظ .. ان جهازك يعتبر سيرفر بنفسه ...

يعني لو عملنا شبكة مكونة من جهازين مثلا ... ووصلناهما على جهازك .... فإن الجهازين هذين يعتبران كلاينت ....

وجهازك السيرفر ... وبالتالي فإننا نعتبر هذه البيئة .. بيئة متعددة المستخدمين .. اكرر بيئة متعددة المستخدمين ..لا يوجد صعوبة في فهم الموضوع ....





طيب ...

في الشركات .... بيئتهم هي بيئة متعددة المستخدمين ... ما معنى هذا الكلام المبهم ؟

هذه البيئة .. طبيعتها ان يدخل اكثر من مستخدم .. ولنقل مئة مستخدم ..كلهم في الوقت نفسه ... يدخلون من اجهزتهم التي تعتبر كلاينتات ... ويطلبون الموارد من سيرفر واحد !!

يعني ... كلهم يريدون ان يستعرضون اسماء الموظفين في القسم 10 مثلا !!

مئة موظف يطلبون من سيرفر واحد ... في وقت واحد ... يالله .... ماذا يفعل السيرفر المسكين ؟؟

هل يخدم هذا او ذاك ... او يرمي زهور النرد ويختار احدهم ليخدمه ؟ او يختار المدراء ؟؟؟؟؟ ماذا يفعل ؟؟

ليس مسكينا .. بل خارق ....

انا لا اتكلم عن اجهزة شخصية مثل جهازي وجهازك ...

توجد اجهزة جبارة وقوية وذات ذاكرة جبارة وسعة تخزين هائلة .... وهي الاجهزة السيرفر ...

ويطلق عليها السيرفر لانها جديرة بأن تكون هي حاملة برنامج السيرفر ... وهي حاملة الموارد !!

اذن أين الموارد ؟ في اجهزة السيرفر ..

أين برنامج السيرفر ؟ في اجهزة السيرفر

من يحضر لنا الموارد ؟ اجهزة السيرفر ..

من يطلب الموارد ؟ اجهزة السـير... اسف ... اجهزة الكلاينت !!

لا اريد ان اخوض اكثر من ذلك ..

لكن كل ما في الامر ان بيئة المتعدة المستخدمين .. بها سيرفر واحد .... ومن الممكن يوجد بجانبه مجموعة سيرفرات مساعدة اخرى ... على حسب ... المهم انه يتصل في نفس اللحظة مستخدم او اكثر .....

كيف ينتبه السيرفر لطلبات الزبائن المتعددين ؟؟؟ سوف يخدم اول من طلبه .. وبسرعة الضوء يذهب ويخدم الاخر .. الثالث .. ويرجع للأول .. ووو ... صحيح انه تعب ... لكن عليه لا تعب ... هل الطريقة بطيئة ؟ من ناحية انها بطيئة بطيئة جدا .. لكنها لنا كبشر .. لا نحس بها !!!!اجزاء من الثانية ويمكن اجزاء الاحزاء من الثانية .....





الان عرفنا بعض هذه المفاهيم ....

والان .... هل كل المستخدمين لهم نفس الصلاحيات ؟ بمعنى هل يستطيع الموظف المسكين احمد والذي يتقاضى راتب 1500 ريال ... ان يحذف جدول مكون من ملياري صف , ومئة وعشرون عمود ... بكبسة زر ؟؟

هل يعقل ان نعطيه هذه الصلاحية ؟؟ لو بالخطأ اعطيناه 1490 ريال ... سوف يغضب ... ويحقد ..

وسوف يحذف الجدول بكامله ...... ولا عليه دخل السجن او لا ...

والخاسر الاكبر هو .... الشركة ... باجملها !

اذن نعطيه صلاحية صغيرة جدا .. يعني ايش صلاحية ؟ يعني حق !! نعطيه بعض الحقوق التي له ..

مثل ... يعرض المعلومات من جدول ما .... يعرض بعض اعمدة جدول اخر ... وليس كلها

اما المدير الاكبر في الشركة .. نعطيه صلاحية يعمل مستخدمين جديدين ... يعمل جداول .. يعدل .. يضيف .. يحذف ... يمحو ... يسوي صلاحيات جديدة , يمنع الموظف scott من الوصول الى جدول الموظفين ! , يمنع موظف اخر من التعديل على جدول الأقسام , وغيرها الكثير .......







دعنا نتقمص شخصية المدير العام ... لقواعد البيانات ... ويسمى DBA اختصارا لـ database administrator


مدير قواعد البيانات هو الموظف صاحب الصلاحية الأعظم ...


الان هل تذكر حينما كنت اقول لك ... ادخل تحت حساب scott وكلمة السر ****** أين كانت هذه الكلمة السر ..

لكن ادحل الان ... بحساب الموظف system وبكلمة السر التي اقترحتها انت ...

اذا واجهتك مشكلة في الدخول بهذا الحساب ... استفسر ... او اعد تحميل الأوراكل .. وضع كلمة سر لحساب system ..... واعتقد انني اقترحت عليك ان تكون نفس كلمة السر الخاصة بـ scott


الان حينما تدخل بحساب system ... وتكتب الامر التالي /أايب










Select * from emp;




فسوف يقول لك ... لا يوجد جدول بهذا الاسم !!

فتقول له ....





Select * from scott.emp ;




وهكذا ... سوف تعرض لك بيانات جدول الموظفين .... والذي يخص حساب او يخص الموظف scott


الان ... يوجد مصطلح اريدك ان تعرفه .. ويجب ان تعرفه ... وهو schema


لم اجد له مرادف بالعربي ... ولكن وجدت لهذه الكلمة المشابهه له . scheme


ومعنى الثانية مخطط ..... واكتشفت فيما بعد ان الاولى هي ايضا مخطط ....





طيب لنركز على الاولى schema


وتعني "مجموعة من الاوبجيكت من جداول و مناظر وغيرها ... والتي يمتلكها شخص واحد "

مثل جدول الموظفين .... والمنظر emp10 والمنظر view_30 ..... وجدول الأقسام .... وغيرها ..

يمتلكها الموظف scott ..... ونسمي schema الخاص بالموظف scott بنفس اسم الموظف ..

أي scott schema


ولكي نستخدم schema الخاص بscott


نكتب scott.the_schema


مثل .. scott.emp , scott.dept …… ..... وغيرها

الان لنعمل مستخدم ... او مايسمى بحساب ... مثل SCOTT


لكن نريد اسمه .... King , وكلمة السر مثلا ..... boss


انظر الى الامر ...







create user king

identified by boss;




يقول : اعمل مستخدم يدعى king واجعل كلمة السر هي boss


الان لنجرب وندخل حساب هذا الشخص الذي يدعى بـ king


لاحظ امر الدخول الى حساب أي شخص ... وهو conn





SQL> conn king

Enter password: ****

ERROR:

ORA-01045: user KING lacks CREATE SESSION privilege; logon denied





Warning: You are no longer connected to ORACLE.




يقول ان المستخدم موجود وكلمة السر صحيحة ولكن لا يمكنني ان ادخل في حسابه ؟

لانه لا يملك صلاحية الدخول على قواعد البيانات !!

الم يكن من المفروض ان تعمل هذه الصلاحية اوتوماتيكيا ؟؟

المفترض ولكن لاغراض امنية لم تعمل !!

طيب طيب ... اسمع ماذا يقول في السطر الاخير :

تحذير : انت الان ضايع ولم تعد في حساب احدهم !! ... ولم تعد متصلا باوراكل !!





SQL> select * from scott.emp;

SP2-0640: Not connected




يقول ... لست متصلا ؟؟؟

طيب .... يعني اذا فشل في الاتصال باحد المستخدمين ..... سوف تفقد الاتصال ...

نرجع لاتصالنا القديم ...





SQL> conn system

Enter password: ******

Connected.




يا سلام ... رجعنا لحساب مدير قواعد البيانات ...

The Coder
23-02-2006, 12:31 AM
الان لنستذكر .. مالذي حصل ؟؟

عملنا مستخدم وهو غير مفعل !! غير مسموح له الان .... كيف نسمح له ؟؟

نعطيه صلاحية الاتصال بقواعد البيانات ..

الان امر اعطاء الصلاحيات .. هو grant ..... طيب امر حذف الصلاحيات ..هو revoke


هيا لنعطي king صلاحية الاتصال بقواعد البيانات ....





SQL> grant create session

to king ;



Grant succeeded.




اعطيناه الصلاحية create session ......


وهي الصلاحية الخاصة بالاتصال بقواعد البيانات أوراكل .....

الان لنتأكد :





SQL> conn king

Enter password: ****

Connected.




نعم .... أي والله .... اتصلنا ....

والله روعة ^^

هيا لنستعرض جدول الموظفين الخاص بالمستخدم scott





SQL> select * from scott.emp;

select * from scott.emp

*

ERROR at line 1:

ORA-00942: table or view does not exist




يقول ... لا يوجد شيء بهذا الاسم ..؟؟

لا يوجد .. ولكن ليس لنا صلاحية نحن للوصول الى الجدول ....

طيب طيب.....

هيا لنعمل جدول خاص بنا ...





SQL> create table a

(no number );



ERROR at line 1:

ORA-01031: insufficient privileges




هاه ؟؟ لا اسمع ؟؟ ماذا تقول ؟؟ لا يوجد صلاحية كافية !!!!!

حتى في عمل الجداول والمناظر صلاحيات ؟؟؟؟ ما هذا الامن المتشدد ؟؟ وكم صلاحية موجودة امامنا ؟؟؟

يقال انها اكثر من 80 صلاحية .... لا اعرف كيف حسبوها الاوراكليين ..... ولكن ... هي اكثر من 80 !!


صراحة .. اريد اعطاء الموظف المسكين king كل الصلاحيات التي في بالي ....

هيا لنعمل صلاحية ...





SQL> grant create table , create view , create sequence , create procedure

to king ;



ERROR at line 1:

ORA-01031: insufficient privileges




غريبة ؟؟؟ لا يوجد صلاحية "اعطاء الصلاحيات "؟؟؟؟

اوه نسيت . ما زلت متصل تحت حساب المستخدم king







SQL> conn system

Enter password: ******

Connected.

SQL> grant create table , create view , create sequence , create procedure

2 to king ;



Grant succeeded.




اعطيت الموظف king الان اربع صلاحيات اساسية ..

هي عمل الجداول , عمل المناظر , عمل سلاسل , عمل الإجراءات !!

إجراءات ؟ وما هي هذه الإجراءات ؟؟؟

سوف تعرفها في لغة الـ PLSQL !!


وما هي لغة الـ PLSQL ؟؟

هي لغة برمجة .. خاصة بالاوراكل ....

وما معنى لغة برمجة ؟؟ وما الفرق بينها وبين الـ SQL


ستعرف قريبا ....

أين وصلنا ؟ نعم نعم .. صلاحية عمل الإجراءات ,

المهم .. ان king يستطيع عمل هذه الاربع .... ياسلام .... رائع ...

الان هذه الصلاحيات الخمس .... تسمى صلاحيات النظام .... اكرر صلاحيات النظام .. وهي :


Create session , create table , create view , create procedure , create sequence


صلاحيات مهمة .....

الان هل يوجد صلاحيات غير صلاحيات النظام ؟؟؟

طبعا !!


مثلا الموظف king ليس لديه صلاحية الوصول الى جداول الاخرين ....

لماذا لا نعطيه صلاحية الوصول الى جداول معينة ولا نعطيه الوصول الى جداول اخرى ؟؟

اولا ما معنى وصول ؟؟ ماذا يقصد المؤلف الذي امامك بكلمة الوصول ؟؟

يصل اذا وصل وصول ... يعني يتعامل مع, يعرض من , يحذف او يضيف الى , يعدل في ,

أي جدول ......

هل فهمت ؟ يعني اذا لم يملك صلاحية وصول .. فان الجدول لا يكون موجود في نظره ... .

الان.. قبل ان نبدأ في النوع الاخر من الصلاحيات ...

دعنا نعدل كلمة السر الخاصة بالموظف king ,,,


ماذا نعطيه ؟؟ ما رأيك the_boss ؟؟؟








SQL> alter user king

identified by the_boss;



User altered.




اردت ان اعرفك على امر التعديل ... ليس الا .... خاصة اذا نسيت كلمة السر ...

اذهب الى مدير قواعد البيانات , وقل له "ضيعت كلمة السر .... اريدها ان تكون the_boss " وهو يغيرها ^^





الان لنعمل مستخدم جديد .. ونعطيه بعض صلاحيات النظام ...





SQL> create user smith

2 identified by not_boss;



User created.



SQL> grant create session , create table , create view

2 to smith ;



Grant succeeded.




الان ... عندنا جدول emp والذي عند الموظف scott , هذا الجدول اريد ان يستطيع جميع الموظفين ان يستعرضوه ... ماذا نفعل ؟؟؟

اذن النوع الثاني من الصلاحيات هي صلاحيات الاوبجيكت ...

على فكرة .... كلمة صلاحيات هي privilege .... احفظها جيدا ...


Object Privileges


وهي صلاحيات الوصول الى الاوبجيكت بانواعها ,

الان كما قلنا اريد ان اعطي جميع الموظفين صلاحية استعراض جدول الموظفين الخاص ب scott


اليك الامر :





grant select

on scott.emp

to public ;




انظر كلمة public ..... أي عام ... أي للكل .... سميها ما شئت ,,,

سوف يستطيعون جميعهم ان يستعرضوا جدول الموظفين ....

الان لاحظ انني المستخدم system مدير قواعد البيانات ..

لاحظ ان الامر السابق ... من يستطيع تنفيذه ؟؟ اثنين .... يا صاحب الاوبجكت ....او أي شخص يملك صلاحية اعلى من صاحب الاوبجكت ...

أي بمعنى اخر ..... يا scott او system في مثالنا هذا ...





سوف نعطي صلاحية الحذف من جدول الموظفين ... وايضا صلاحية تعديل اسماء الموظفين و ارقام اقسامهم .. ل king و smith !!









grant delete , update (ename , deptno )

on scott.emp

to king , smith ;




الان ... جدول الموظفين ... مثلا يوجد به بيانات مهمة جدا ليست قابلة للتعديل من قبل أي شخص الا


Scott , system ..... وهي العمود sal مثلا .. اريد ان لا يعدلها احـد غير scott و system


وهو تحدي !! أي ... يستطيع كل الموظفين التعديل في جدول الموظفين ... ولكن لا يستطيعون التعديل على عمود الرواتب الا scott , system

The Coder
23-02-2006, 12:34 AM
الان ..... اريد ان اعطي صلاحية ل smith و king ان يعطي صلاحية تعديل بيانات جدول الموظفين ....


أي ... ان الموظف king يستطيع ان يكتب الامر التالي او له الصلاحية ان يكتب الامر التالي :











grant delete , update (ename , deptno )

on scott.emp

to smith ;









لانه لو كتب الان الموظف king الامر السابق ... فانه ليس له الصلاحية ابدا ..... لكن الان اليك الامر الذي يمنح هذه الصلاحية الإضافية :











grant delete , update (ename , deptno )



on scott.emp



to king , smith



with grant option ;








لاحظ الجملة with grant option








أي انه يستطيع ان يمنح هذه الصلاحية (delete , update (ename , deptno) لشخص اخر ....


تريد ان تسحب الصلاحية ؟ تريد ان تحذفها ؟؟

سوف نحذف صلاحية التعديل من الموظف SMITH على جدول الموظفين

وفي الامر الثاني سنحذف كل الصلاحيات من الموظف smith على جدول الموظفين ..











SQL> revoke update

2 on scott.emp

3 from smith ;



Revoke succeeded.



SQL> revoke all

2 on scott.emp

3 from smith ;



Revoke succeeded.














الان لديك صلاحيات الاوبجيكت الممكنة : صورة 1301








http://img9.picsplace.to/img9/7/1301.jpg








كيف تستخدم الصورة ؟


انا اخبرك ... يوجد كلمات yes yes yes في مناطق متعددة ...

مثلا .... ALTER ... هو امر تعديل للاوبجيكت ... لأي اوبجكت هو يصلح ؟؟

لنبحث في كلمات الـyes .................







اها ... للtable و sequence ..... أي للجداول والسلاسل ....


فقط .....
















وايضا انظر الى execute .. فهي لا تصلح هذه الصلاحية او هذا الامر الا للاجراءات procedure ..








سوف نأخذها فيما بعد .... Don’t worry










الان مثال على اثنتين منهما ...






















SQL> grant index



2 on scott.emp



3 to king ;







Grant succeeded.







SQL> grant references



2 on scott.emp



3 to king ;








... ارجو ان يكون واضح .. مع العلم انني نسيت او لا اعرف هذا الشيء references ...








سوف ابحث عنها فيما بعد ..... فالمعذرة .....


الان لو قلت ....











SQL> grant execute

2 on scott.emp

3 to king ;

on scott.emp

*

ERROR at line 2:

ORA-02224: EXECUTE privilege not allowed for tables









لماذا اعطانا هذه الرسالة :"صلاحية (تنفيذ execute ) لا تصلح مع الجداول !! "


انظر الى الصورة السابقة 1301

وهل يوجد yes .... في ملتقى execute و table ؟؟؟ هل عرفت الان كيف تستخدم الصورة ؟؟ هيا ... شد حيلك ..
















في شيء اخير ... نختم به منهجنا ... ونرتاح قليلا من SQL ,,,,








انها الادوار ..ROLES








يا اخي ... فكر معي ... كم احتمال نستطيع ان نعمله .... مع الصلاحيات وجدول الموظفين فقط ... بمعنى


ان جدول الموظفين ... نستطيع ان نعمل له الصلاحيات التالية بشكل عشوائي ....

صلاحية العرض ...

صلاحية التعديل ..

صلاحية الحذف ...

صلاحية العرض والحذف

صلاحية التعديل والحذف والعرض ..

صلاحية الفهرسة والعرض

صلاحية تعديل عمود الرواتب ... إضافة الى صلاحية الحذف ...







.....










عدد هائل من الاحتمالات ...


هذا اذا قلنا انه جدول واحد .. فما بالك .. بمجموعة اوبجكت .... من جداول ومناظر ... الخ

الان يوجد طريقة جميلة وترتب التفكير في الصلاحيات ...

يعني تخيل لدينا ثلاث مدراء ... الاول سميث والثاني اسكوت والثالث كنج ....







لكل واحد فيهم .... صلاحيات ... المشكلة ان الشركة تقول ... صلاحيات المدراء واحدة وهي ..


عرض select, تعديلupdate , حذف delete, وتعديل بناء alter....







كلهم ... متشابهون في الصلاحيات ...


انظر كيف سوف نعطيهم هذه الصلاحيات ... انظر الصورة 1302 :





http://img9.picsplace.to/img9/7/1302.jpg




طبعا ... شربكة ... ولهم نفس الصلاحيات ؟؟ مشكلة عويصة ....


لماذا مشكلة عويصة ؟؟ لاننا نقول ... انهم فقط ثلاثة , و اربع صلاحيات ... فما بالك بخمسين صلاحية ....

وستة مدراء مثلا ...؟؟؟؟؟

الاوراكليين .... (الاوراكليين جمع اوراكلي ...و هم اصحاب الأوراكل , ومبرمجيه ) قالوا ...

"يجب ان نبسط هذا الموضوع , ونضيف خاصية الـ Roles "







وما هي خاصية الادوار يا اوراكليون ؟؟


هي خاصية تنظيمية .. مثلا نسمي هذه الصلاحيات (عرض select, تعديلupdate , حذف delete, وتعديل بناء alter.) بصلاحيات المدراء ....

ثم أي مدير ... يأتي جديد ... لا نقول له ...." لك صلاحية العرض ... لك صلاحية التعديل .. لك صلاحية الحذف ... لك صلاحية تعديل البناء ...."

بل نقول له ... "لك صلاحية المدراء "

انظر البساطة .... والسلاسة ... انظر كيف نعمل هذه الـ Roles ولاحظ الصورة 1303





http://img4.picsplace.to/img4/20/1303.jpg




الان لاحظ الامر :












create role manager ;









عملنا الدور ... الخاص بالمدراء ...


هيا يا أوراكل .... انظر ماذا لدينا ... لدينا دور .... ويدعى بدور المدراء ...

الان نضيف الصلاحيات الخاصة بالمدراء لمن ؟؟ للمستخدم كنج ؟ لسميث ؟؟؟ لمن ؟؟

لا ... بل للدور نفسه !!











grant select , update , alter , delete

on scott.emp

to manager;









الان الدور جاهز للاستخدام ... انظر فقط الى الامر التالي ...




















grant manager



to king , smith , scott ;








... وكأنه صلاحية واحدة !!


طبعا خاصية الأدوار لا تصلح الا لصلاحيات الاوبجيكت فقط .....

الان .... هل فهمت المغزى ؟؟

وكأن الدور صلاحيات متعددة بداخله .. ونعامله كصلاحية واحدة ... أي ان الدور ليس الا مجموعة صلاحيات متعارف عليها , لكي نستخدمها لغرض ما ...

The Coder
23-02-2006, 12:38 AM
انظر الى جداول الـ Data Dictionary لكي تستعرض الصلاحيات على اشكالها :


Role_sys_privs جدول خاص بصلاحيات النظام المعطاه للادوار


Role_tab_privs جدول خاص بصلاحيات الاوبجيكت المعطاه للادوار


User_role_privs جدول خاص بالادوار


User_tab_privs_made جدول خاص بصلاحيات الاوبجيكت المستخدمة على جميع الابجكت


User_tab_privs_recd جدول خاص بصلاحيات الاوبجيكت المعطاه للمستخدمين


User_col_privs_made جدول خاص بصلاحيات الاوبجكت المستخدمة على اعمدة ما ...


User_col_privs_recd جدول خاص بصلاحيات الاوبجت المعطاه للمستخدمين والتي تخص اعمدة ما ...





التحدي ما قبل ... قبل ... الاخير ... لـ SQL


استعرض الجداول السابقة .. وحاول ان تعرف ما مغزى كل جدول ...

واسألني اذا واجهت صعوبة ...





التحدي ماقبل الاخير لـ SQL


اعمل كذا مستخدم .... اقترح صلاحية للمدراء .. اقترح صلاحية للموظف العادي ...

وضع لكل مستخدم .. صلاحية تخصه , اي الموظف 1 , والموظف 2 .. لهم صلاحية المدراء ..

والموظف 10 , 20 , 30 , 50 , 1000 ..... لهم صلاحية الموظف العادي ... اقترح أي شيء ...







التحدي الاخير .... للـ SQL


اعمل جدول او مجموعة جداول ... تلخيص لاوامر الـ SQL .....


وسوف اعرض كل محاولاتكم ....





لم يبقى غير ان اخبرك ..... انني انا انهيت منهجي في الـ SQL


ولكن ... هل انهيت انت منهج SQL؟؟؟

ابحث , وجرب , واسأل ..... واستفسر .. وترقب كل جديد ....

من الممكن ان ترى كم هائل من المعلومات التي لم اشرحها ....

ومن الممكن ان تطرحها علي .....

الخيار لك ... ولكن ... أنصحك بنصيحة واحدة ....


تعلم كل شيء .. وكن خبيرا ... او لا تتعب نفسك واذهب ونم ..





انتهى المنهج للـ SQL

The Coder
01-03-2006, 11:40 PM
بسم الله الرحمن الرحيم

الدرس الثالث عشر


اسم الدرس :لغة PLSQL


نوع الدرس : تطبيقي


صعوبة الدرس : **** من *****


الوقت المتوقع منك لفهم الدرس : اربع ساعات .


المتوقع منك في هذا الدرس :

- التعرف على هذه اللغة ..


- المتغيرات ...

- بعض النصائح البرمجية ...





هيا لنؤركل ^^


السلام عليكم

لغة الـ PLSQL .....


ما هي هذه اللغة ...؟

لماذا نستخدمها ؟ وما فائدتها ؟؟؟

هي لغة تطويرية للغة SQL ,, طورت الأوراكل هذه اللغة لتواكب متطلبات البرمجة الحديثة ,,

وهي اختصار لـ Procedure Language SQL أي اللغة الاجرائية لجمل الـ SQL




انا سوف اشرح وكأنك لا تعرف شيئا عن البرمجة ... سوف تلاحظ هذا في منهجي ....

لذا اذا كنت تعرف .... فاقول لك ... هذه لغة قوية جدا جدا جدا جدا جدا ......... مع التعامل مع قواعد البيانات ...

هي لغة برمجة مخصصة لبرمجة قواعد البيانات ...

شكلها يشبه لغة ADA المشهورة (ADA لغة تم تطويرها لوزارة الدفاع الامريكية ... خلونا نبعد عن السياسة )

بها حلقات التكرار , بها مسارات منطقية و جمل شرطية ....بها مصائب اخرى .

اذا صادف وقد ربطت قواعد البيانات مع لغة اخرى مثل الجافا او الـ C# او الـ Visual Basic , فأقول لك ...


اخي , قل وداعا للتعب والربط وانشاء جمل الاستعلام , والتعقيد الذي يبطئ من انتاجية برمجة قواعد البيانات , ولتتعلم هذه اللغة التي تسهل لك برمجة قواعد البيانات !!

اذا لم تبرمج في حياتك .. اقول لك ,,,

اخي .. مارأيك في لغةSQL , لو قلت لك ... اريدك ان تعدل بيانات مئة شخص ... ومن ثم تعرض لي بياناتهم قبل التعديل وبياناتهم بعد التعديل ؟ ماذا تفعل ... سوف تعرض اولا بياناتهم .. ثم تعدل .. ثم تبحث عن الذين عدلتهم وتعرض بياناتهم ...

اخي تخيل انك تستطيع ذلك في كتابة 5 الى 10 سطور ... ثم تكبس زر انتر ... وسيعملها الأوراكل اوتوماتيكيا ؟؟

تخيل انك تريد برنامج اوتوماتيكي ... مثلا لو جاء احدهم يوم السبت وعدل في جدول الموظفين , يرفض النظام ذلك , ولو عدل الموظف scott مثلا في جدول الأقسام يوم الثلاثاء فان النظام لا يقبل ...

تخيل هذه البرامج الذكية والاوتوماتيكية ... موجودة ؟ هل تستطيع عملها بالـ SQL ؟؟ طبعا لا ...


PLSQL تستطيع عمل برامج اكثر عمومية , واكثر مرونة ... كيف يعني مرونة ... يعني أي شيء تريده يصير ... هذه اللغة تستطيع ذلك ...

طبعا لا غنى عن SQL فهي الام ولكن قدرتها محدودة في اوامر ... PLSQL تعطيك امكانيات اوسع لاستخدام الـ SQL ....


اذا لم تستطع فهم ذلك سوف ترى الكثير الكثير من الامثلة , لا تخف وكن معي ...





- قبل البدء :


اريدك يا صاحبي ... ان تتقن الـ SQL ... اريدك ان تشربها كشرب الماء .. خذ يومين فيها ... خذ عشر ... خذ شهرين ... هذا ليس مهم ... الاهم ان تتقن الـ SQL .... ان لم تتقنها او لا تريد ذلك ... فلا تكمل معي .





- ما معنى برنامج :


البرنامج هو مجموعة اوامر للحاسب , مثال على هذه الأوامر "احسب ,اجمع , اطرح , اقسم , هات , خذ , سوي , افعل " هذه الأوامر مكتوبة بلغة برمجة ما ... من يكتبها ؟ المبرمج ..

البرنامج يحتوي على خطوات منطقية , او ما تسمى بالخوارزميات .... اذا لقيت وقت كافي فسوف اشرحها بالتفصيل . الان نريد ان نحسب مربع مجموع عددين .... ونريد اخبار الحاسب الغبي والذي لا يفهم شيء بل ينفذ الأوامر ليس الا .. نريد اخباره بالاوامر التي تحسب لنا هذه المسئلة ,, انظر /


نحن :ياااا حاسب ....

الحاسب: نعم

نحن :خزن الرقم الاول

الحاسب:حاااضر

نحن :ياااا حاسب .... خزن الرقم الثاني

الحاسب:حاااضر ..

نحن :ياااا حاسب .. اجمعهما

الحاسب:حاااضر

نحن :ياااا حاسب.. خزن النتيجة في متغير

الحاسب:طيب ...

نحن :ياااا حاسب .... ضع النتيجة في متغير اخر

الحاسب: حاااضر

نحن :اووووف .... ياااا حاسب .... اضرب المتغيرين في بعضهما

الحاسب: طيييييييب

نحن :.... ياااا حاسب .... خزن النتيجة في متغير جديد ...

الحاسب:حاااضر





لاحظ اننا طفشنا ونحن نبرمج ونعطي الحاسب اوامر , والحاسب لا يطفش ولا يزهق , آلة غبية ولا تفكر ... تقرأ البرنامج وتطبق حتى لو كان فيروسا ... على فكرة ... الفيروس مجرد برنامج عادي , ولكن مبرمجه عمل هذا البرنامج للتخريب , يعني قال له يا حاسب , احذف , احرق , امسح , سوي , افعل .....

يعني نطلب من الحاسب كوارث ليس اوامر !! والكارثة العظمى "يا حااااسب ... فرمت الجهاز " .


لاحظت كيف تعبنا في مسئلة صغيرة ؟ هذه خطوات الحل التي تحدث في عقلك وانت لا تعلم ....

مثلا 2 و 5 .. ماهو مربع جمعهما ؟؟


2 + 5 = 7

7 * 7 = 49


يعني هي خطوات حل ... هذا ما نقصده بالخوارزميات !!

وهي خطوات منطقية تؤدي الى حل ..

فهمت ؟؟





- ماهي لغات البرمجة :


هي اللغات التي يفهمها الحاسب , والتي لا يفهمها فعليا أي شخص , الا المبرمجون , هي كتابات وارقام وطلاسم .. اذا كنت مبرمج سوف تعرف ان تقرأها وستستنتج ماذا تعني ..

لغات البرمجة كثيرة , كل شركة تطلع لغة جديدة , لا تمر بضع سنين الا ونسمع لغة جديدة او تطوير لغة ما ,,

هذه اللغات سوف تتحول الى اصفار وواحدات ..... لا يفهمها الا الكمبيوتر , الكمبيوتر اصلا لا يفهم هذه اللغات !!

هو يفهم الصفر والواحد , هذه اللغات ستتحول (ببرنامج اخر مكتوب بلغة ما ) الى اصفار وواحدات يفهمها الحاسب بطريقة لا اريد سردها هنا .








- المتغيرات Variables :


من اهم العناصر في البرمجة بشكل عام ,, احفظ الكلمة بالانجليزي ....

هل تذكر لما تكلمنا عن القرص الصلب وعن الذاكرة العشوائية (RAM) ؟؟

قلنا ان القرص الصلب للذاكرة الدائمة , والبيانات التي نريد تخزينها للابد ,, ومثال على ذلك قواعد البيانات نفسها !!

الذاكرة العشوائية هي الذاكرة المؤقتة , والتي تخزن بيانات طالما ايش ؟ طالما انه فيه كهربة .... طالما ان الجهاز شغال , اذا طفى الجهاز , راحت البيانات الموجودة في هالذاكرة ,,

تكلمنا لماذا تلك ولماذا هذه , واهم الاشياء التي اريدك ان تستذكرها هي ان الذاكرة العشوائية ميزتها ميزة .. ماهي ؟

سرعتها التي تقدر باضعاف سرعة القرص الصلب ..لماذا هذه السرعة ؟ لانها الكترونية والقرص الصلب ميكانيكي ..

الالكتروني يعتمد على سرعة الالكترونات , يعني مثل سرعة الضوء !!

الان سوف تعرف لماذا بعض البيانات غير هامة لدرجة اننا نخزنها تخزين مؤقت ....

المتغيرات ماهي ؟

هي اوعية , هي شيء يحمل قيمة , أي قيمة .... يخزن القيمة بداخله .... طبعا المتغيرات هي جزء من الذاكرة , يعني اذا قلنا المتغير س أي ان س هذه حاجزة مكان في الذاكرة ... المتغيرات دائما لا نستطيع نحن البشر ان نرى ما بداخلها ... الا اذا نحن قلنا "س=10" فهذا يعني ان س بها العدد عشرة , واذا قلنا "س=اهلا وسهلا" يعني ان س بها القيمة "اهلا وسهلا" ,,, واعيد واكرر ,, المتغيرات هي جزء من ماذا ؟ من الذاكرة , يعني الذاكرة هي مجموعة متغيرات .

لماذا نستخدم المتغيرات ؟ ستعرف بعد قليل ...


قبل ان نبدأ باول برنامج نستعرض شكل وتركيب هذه اللغة ...





- تركيب هذه اللغة :


هذه اللغة لها شكل محدد وهو :





Declare

……

…مجموعة تعريفات....

……

Begin

……

…مجموعة اوامر…

……

end;

Exception

……

…مجموعة اوامر ….

……

/




قبل البدء بالبرنامج الاول .....

لاحظ انني سوف استخدمة كلمة "جزئية" ...

مثلا جزئية التعريف يعني هي السطور ما بين الكلمة declare والكلمة begin


او جزئية الأوامر .. أي السطور التي بين begin وبين end ...


او جزئية الاستثناءات وهي السطور التي تحت كلمة Exception


الان ... البرنامج الاول ... وهو اشهر برنامج , انه برنامج"Hello world"


وهو ابسط برنامج يمكن كتابته .... وهو برنامج يعرض لنا الجملة hello world على الشاشة ...

طبعا بنفس البرنامج SQL PLUS نعمل برامج هذه اللغة ,,, الان اريدك ان تكتب الامر التالي وهو الخاص بعرض الرسائل والمخرجات :





SQL> set serveroutput on ;




يجب ان تكتبه في كل مرة تفتح هذا البرنامج ... يعني اعمله مرة واحدة في كل مرة تقوم بتشغيل البرنامج ...


الان برنامج hello world ..





SQL> begin

2 dbms_output.put_line('hello world');

3 end;

4 /

hello world



PL/SQL procedure successfully completed.




في السطر الاو كتبنا begin .... يعني يا أوراكل ... هذا بداية برنامج بلغة PLSQL


في السطر الثاني كلام كثير جدا ...dbms_output ثم نقطة ثم دالة ... بها مدخل Parameter , وهو مدخل واحد ,

ويظهر ان المدخل من نوع نصي ... انها دالة put_line("???")


وهي تأخذ ما بين القوسين (المدخل) .. وتخرجه لنا على الشاشة ..

السطر الثالث نهاية البرنامج

السطر الرابع .. يجب ان تكتبه لكي تقول للاوراكل "ياااا أوراكل ... نفذ بالله عليك برنامجي هذا "

يعني يجب ان تكتبه في كل برنامج .

الان انظر ماذا طبعت لنا ... طبعت لنا الجملة hello world ...


انظر تحتها بكم سطر ... يقول PL/SQL procedure successfully completed.


يعني خلاص ... كذا انتهى البرنامج ...

ركز في البرنامج السابق ... وانظر الى بلاهته .... ضع أي جملة من عندك .

الان لنضع جملتين hello world بجانب بعضهما ...





الان سوف استرسل في هذه اللغة , وستتعلمها ان شاء الله بكل يسر وسهولة .








SQL> begin

2 dbms_output.put_line('hello world');

3 dbms_output.put_line('hello world');

4 end;

5 /

hello world

hello world




اوبس .... يظهر ان الدالة تضع كل مدخل .... في سطر ... على اسمها put_line يعني ضع الجملة التالية في سطر.

لاحظ انه في كل نهاية جملة نضع الاشارة ; أي الفاصلة المنقوطة , يجب ان تضعها ...

في اماكن لا نضعها مثل begin و declare ... وغيرها .

الان نريد ان نستخدم المتغيرات ... كيف نستخدمها ؟

انظر البرنامج التالي ... وهو برنامج hello world .... ولكن من نوع اخر :








SQL> declare

2 abc varchar2(15) :='Hello World';

3 begin

4 dbms_output.put_line(abc);

5 end;

6 /

Hello World




يظهر ان هنالك نقطة جديدة ... وكلمة جديدة ... وهي declare أي تعريف ... أي اننا نعرف متغيرات ... ومصائب اخرى ... ماهي هذه المصائب الاخرى ؟ ستعرفها لاحقا ...

السطر الاول : هي كلمة declare أي تعريف ...

السطر الثاني : عرفنا متغير .. اسمه abc ونوعه ماذا ؟؟ رقمي ؟ حرفي ؟ نصي ؟ تاريخ ؟؟

نوعه varchar2 وهو نص .... كما عرفنا سابقا , كم حده الاعلى ؟ يعني كم يستطيع ان يحمل هذا الوعاء .. ااقصد المتغير بداخله من نص ؟ 15 حرفا ... 15 خانة نصية ... او خانة حرفية ...

العلامة التي تشبه اليساوي := ما معناها ؟؟ معناها اسند .. ساوي ... ضع ... ضع ماذا ؟ ضع القيمة التي في اليمين ... في المتغير الذي في اليسار ... اكرر .. تضع هذه العلامة القيمة الي باليمين , في المتغير الي في اليسار ...

لاحظ انه سوف يضع hello world في المتغير abc ... ولا تنسى ان تضع التواريخ والنصوص بين علامة تنصيص احادية ....

The Coder
01-03-2006, 11:47 PM
الان نحن خزنا في المتغير قيمة ...

الان نحن خزنا في المتغير جملة hello world


الان نحن خزنا في الذاكرة نص hello world


انتبه للفاصلة المنقوطة نهاية كل جملة ...





السطر الثالث .. بداية البرنامج .

السطر الرابع .. اطبع ماذا ؟ اطبع ما بداخل abc !! ماذا بداخل abc ؟؟؟ من يذكرني ؟؟

اها ... بداخله جملة "hello world" هيا اطبعه ...





انظر الى المخرجات ... على فكرة حينما اقول مخرجات ... أي ما سوف يعرض لنا ... او يطلع لنا عالشاشة او الطابعة او أي جهاز اخراج من الكمبيوتر الينا ...

لنعقد الموضوع قليلا في المثال القادم :





SQL> declare

2 hello varchar2(20) :='hello';

3 name varchar2(10):='hamzah';

4 any_thing varchar2(10);

5 like_any_thing any_thing%type;

6 begin

7 any_thing :='yes';

8 like_any_thing :=any_thing;

9 any_thing :=like_any_thing||' no';

10 dbms_output.put_line(hello||' '||name);

11 dbms_output.put_line(hello||name);

12 dbms_output.put_line(any_thing);

13 dbms_output.put_line(like_any_thing);

14 dbms_output.put_line('hi '||name);

15 hello := hello||' ali '||hello;

16 dbms_output.put_line(hello);

17 end;

18 /

hello hamzah

hellohamzah

yes no

yes

hi hamzah

hello ali hello




واو

يظهر ان البرنامج كبير قليلا ...

السطر الثاني ...

عرفنا متغير اسمه ماذا ؟ اسمه hello من نوع نصي .. وبه الجملة "hello" ... لاحظ ان اسم المتغير لا يدل دائما على محتواه !!





السطر الثالث :


.. عرفنا متغير اسمه name وبه القيمة "hamzah" , لاحظ ايضا ان اسم المتغير لا يدل دائما على محتواه .. فبعضهم يقول المتغير x .... وبداخله اسم شخص مثلا ...

اسماء المتغيرات ليست الا لمن ؟؟ لنا نحن لكي نعرف نقرأ البرنامج ....

هيا الان ما بداخل name ؟؟ بداخله القيمة hamzah ..... عرفنا ذلك لاننا سمينا المتغير باسم يليق ما بداخله ...

يجب ان تسمي المتغيرات باسماء تعرف معانيها ... سوف نرى ذلك فيما بعد ...





السطر الرابع:


عرفنا متغير باسم any_thing .... من نوع نص ايضا .... لكن هل بداخله شي ؟ هل وضعنا شيء ؟ هل اسندنا اليه قيمه ؟؟ لا ..... انه فارغ الان ...


على فكرة .. لما اقول "عرفنا " يعني حجزنا في الذاكرة ... يعني حجزنا جزء من الذاكرة .. كم حجمه ؟ على حسب .. فمثلا any_thing .... 10 خانات ... أي 10 احرف ... أي اخذنا من الذاكرة مقدار 10 احرف ...





السطر الخامس :

انتبه هنا ... عرفنا متغير باسم ماذا ؟ like_any_thing .... اسم طويل ... لكن لو قرأته فانه يدل على معنى ...

الان ما نوعه ؟ نص ؟؟؟ رقم ؟؟؟ تاريخ ؟؟

لا لا لا ...

ذكرنا ان نوعه ... هو any_thing%type .... لاحظ جيدا ....

معناه هو "اجعل نوع المتغير like_any_thing نفس نوع المتغير any_thing .... "


وما نوع المتغير any_thing ؟؟ نوعه نص !! وحده هو 10 احرف ... اذن المتغير like_any_thing سيكون نص , حده 10 احرف !! أي نفس نوع المتغير any_thing ....


لماذا عملوا الأوراكليين هذه الحركة ؟؟ ستعرف لاحقا .... ستعرف .

المهم ما نوع like_any_thing ؟؟ نوعه نفس نوع المتغير any_thing


طيب ما بداخل like_any_thing ؟؟ لا يوجد شيء !!

صحيح نفس نوع المتغير ... ولكن لا يوجد بداخله قيمه ...





السطر السادس :

بداية البرنامج ....





السطر السابع :

اسناد .... او وضع قيمة yes وهي نص طبعا في ماذا ؟ في المتغير any_thing ....


لاحظ اننا اسندناه في جزئية الأوامر ... وليس كمثل المتغيرين السابقين اسندنا في جزئية التعريفات ..

الان بداخل المتغير any_thing القيمة النصية yes




السطر الثامن :

اسناد اخر ... لكن ليس اسناد قيمة الى متغير هذه المرة .... انه اسناد ما بداخل متغير الى متغير اخر !!

يا سلام على المرونة ... الان المتغير like_any_thing الذي نوعه هو نفس نوع المتغير any_thing به القيمة ماذا الان ؟؟؟ به القيمة yes ... كيف ؟

قلنا انه سوف يتم اسناد ما بداخل المتغير any_thing الى المتغير like_any_thing في هذا السطر ..





السطر التاسع :

يظهر ان البرنامج لا يتكلم الا عن المتغيرات النصية ....

اسناد قيمة الى المتغير any_thing .. مالذي اسندناه بالضبط ؟

اسندنا ما بداخل المتغير like_any_thing + القيمة no الى المتغير any_thing


فكر معي ... ماهي العلامة || ؟؟؟

انها علامة الضم ... هل تذكرها ؟ هي تستخدم للنصوص ... يعني 'a' || 'b' تعطينا الناتج 'ab'


عملية رائعة ... ومفيدة ....

الان ... لاحظ ان المتغير like_any_thing بداخله ماذا ؟؟ به القيمة yes


طيب .. ناتج العملية التالية :


'yes' || ' no' = 'yes no'


لاحظ الفراغ كيف اتى ... اتى من ' no' .....


الان الناتج يوضع في المتغير any_thing


بداخل المتغير any_thing الان القيمة النصية 'yes no'


الان ما رأيك بالمتغير like_any_thing .. ما بداخله ؟؟

... بداخله قلنا 'yes' .... هل تغير في هذا السطر ؟؟ لا لا .. لم يتغير .. نحن استخدمناه فقط (يمين عملية الاسناد:= )




السطر العاشر :

اطبع على الشاشة القيمة التالية ( 'hello hamzah') .. يعني يطبع ما بداخل المتغير hello واعرض فراغ بعده .... ثم اعرض ما بداخل المتغير name ولاحظ عملية الضم || ....


hello || ' ' || name = 'hello' ||' '||'hamzah' = 'hello hamzah'




السطر الحادي عشر :


نفس العاشر لكن ... يوجد شيء مختلف ... الا وهو انه يقول اعرض مابداخل المتغير hello ثم المتغير name


الناتج : hellohamzah بدون فراغ .. انتبه للسطر هذا والسطر السابق وحاول التفريق بينهما ..

جرب وضع بينهما فاصلة مثلا ...





السطر الثاني عشر ..

سيعرض ما بداخل المتغير any_thing أي ستكون النتيجة 'yes no'




السطر الرابع عشر ...

سيعرض النص التالي 'hi hamzah' .... فكر فيه قليلا ...





السطر الخامس عشر :

قلنا ان ما بداخل المتغير hello هي القيمة 'hello' طيب .. فكر ماذا سيكون الناتج ؟؟

مالذي سوف يسند الى المتغير hello ؟؟ فكر قليلا ...

سوف اعطيك الحل ولن اشرح كيف ...


hello ali hello


الان لنستذكر المخرجات وكانت كما يلي :





hello hamzah

hellohamzah

yes no

yes

hi hamzah

hello ali hello







طيب .. لو كان احد المتغيرات فارغ ؟؟؟؟ سوف لن يطبع شيء ... اوكيه ..

انظر لاصغر برنامج يمكن كتابته بهذه اللغة ... لا فائدة منه ... ولكن انظر اليه :





begin

null;

end;

/







الان سوف اعطيك برنامج خاطئ .. وكله خطأ في خطأ ...





declare

qwertyuiopasdfghjklzxcvbnmQWERT number;

123abc number ;

a%b number ;

a , b , c number ;

select number ;

begin

null;

end;

/







لماذا خطأ في السطر الثاني ؟؟

لان اسم المتغير اكثر من 30 حرف !!





لماذا خطأ في السطر الثالث ؟؟

لان اسم المتغير لم يبدأ بحرف .. بل بدأ برقم !! ...

يمكنك ان تقول : aB348 ....


لماذا خطأ في السطر الرابع ؟؟

لان اسم المتغير احتوى على رمز من الرموز الممنوعة .. وهو الرمز % .. من هذه الرموز الممنوعة( + = - ^ & | .)





يمكنك ان تستخدم مابين القوسين ( _ $ # )

وانا صراحة احب استخدام _ كثيرا .....

وطبعا لا تبدأ بهذه العلامات ... يجب البدء بالحروف فقط . .





لماذا خطأ في السطر الخامس ؟؟

لانه تم تعريف مجموعة متغيرات !! .... بعض اللغات تسمح بذلك لكن لغتنا هذه لا تسمح ...





لماذا خطأ في السطر السادس ؟؟

لان المتغير اخذ اسم من الاسماء المحجوزة للغة ...

لكل لغة اسماء محجوزة لا يجوز تسمية متغيراتنا بها .... ومن هذه الاسماء المحجوزة update , insert , for , while , if , loop , select , create ….




ارجو ان تلتزم بقواعد المتغيرات هذه ..... ولا تنسى ان تكرار اسم المتغيرفي نفس البرنامج خطأ !!




- فوائد المتغيرات





تتلخص في ثلاث فوائد رئيسية ..

1- معالجة البيانات المخزنة في الذاكرة .



2- اعادة الاستخدام .




3- سهولة الصيانة .

..... يعني لو احتجنا عرض رقم الموظف من قواعد البيانات .. ماذا نعمل ؟ نذهب الى قاعدة البيانات ومن ثم الحصول عليه .... وعرضه ... لو احتجناه ثانية في نفس البرنامج .. نذهب ايضا الى قواعد البيانات و........

صراحة ... تقنيا طريقة بلهاء .... لانها بطيئة جدا ويمكن تسبب ضغط على السيرفر ...

لو ذهبنا مرة واحدة لقواعد البيانات ثم اخذنا رقم الموظف ... وخزناه في متغير ... وكل ما احتجناه اخذنا من المتغير هذا ... ما يكون افضل واسرع ؟؟ طبعا ... وهنا تكمن قوة المتغيرات .

ونستطيع ايضا ان نعدل ونغير فيها وبسرعة الضوء , وتخرب فيها ونضع قيم فيها ... وفي النهاية نضع الناتج مثلا النهائي بها , ونخزنها في قواعد البيانات مثلا ...

سهولة الصيانة ستعرف معناها في القريب العاجل ...

The Coder
01-03-2006, 11:53 PM
Constant الثوابت





الان لو عندي متغير يكون ثابت .. مثلا القوة = ثابت الجاذبية * الكتلة .. << لا اعرف من أين اتى هذا القانون ولكن لنفرض انه صحيح ...

ثابت الجاذبية هو 9.8 (لا ادري هل هو صحيح هذا العدد الاخر !!)

وهو ثابت لا يتغير ... في عالم البرمجة يمكن نحتاج لمتغيرات ثابته .. لسببين , اولا لا نريد التعديل فيها من قبل أي شخص اخر , وثانيا يمكن تكون ثوابت متعارف عليها , ولا نستطيع حفظها ... مثلا انا لا افظ الثوابت الفيزيائية الكبيرة والمعقدة ... اعمل لها متغير واضع به هذه الثوابت .. وكل ما احتجت هذه الثوابت .. انادي المتغير صح ؟

طيب انظر كيف تعمل متغير ثابت لا يتغير .








declare

gravity constant number :=9.8 ;

begin

dbms_output.put_line(gravity);

end;

/




نضيف كلمة constant فقط ....

حبيبي ... مع الثوابت لازم تضع قيمة مبدئية, يعني ايش قيمة مبدئية ؟ يعني تضعها وقت التعريف زي ما عملنا الحين





الغير خالية :


بعض المتغيرات ريدها ان لاتكون خالية بالمرة ... كيف نعمل ذلك ؟ بسيطة .. باضافة not null المشهورة ...

ومثلا اريده ثابت الجاذبية ... ولا يكون خالي ... انظر :








declare

gravity constant number not null :=9.8;

begin

dbms_output.put_line(gravity);

end;

/




انواع البيانات Data type:





تعرفها اعتقد ... سوف استعرض بعض هذه الانواع للتذكير :


VARCHAR2 للنص .. ويجب ان نحدد حجمه .. وحده الاقصى 32676 حرف .


CHAR للنص ايضا ... وبامكاننا ان لا نحدد حجمه .... ليصبح حرف واحد ... حده الاقصى 32676 حرف .


Number(P,S) للارقام .. نضع حده الكلي في الـ P ونضع حده الكسري في S

Date للتاريخ ...


BINARY_INTEGER وهو للارقام الصحيحة فقط .... ويحمل ارقام اكثر من مليارين موجبة واكثر من مليارين بالسالب ...


PLS_INTEGER نفس فكرة سابقه ولكن بحجم اقل .... من number ومن Binary_Integer





انواع المتغيرات :


1- المتغيرات التي تحتوي على قيمة واحدة ....


كما شاهدنا .... متغيرات التي تكون حرفية ورقمية و نصية و تاريخية ووو .......

يعني الي شاهدناها سابقا ... متغيرات القيمة الواحدة ...





2- المتغيرات المنطقية Boolean variables


متغيرات نتوقع ان تحتوي على ثلاث قيم ...


Null , false , true


اليك مثال عليها .....










declare

a boolean := true;

b boolean :=false;

c boolean :=null;

sal_1 number :=1000;

sal_2 number :=2000;

d boolean :=(sal_1>sal_2);

begin

null;

end;

/





المتغير a نوعه متغير منطقي ... وبه القيمة true يعني صحيح ..

المتغير b به القيمة false يعني خاطئ

المتغير c به قيمه خالية ..

المتغير d به القيمة ماذا ؟ true false null ؟؟؟ أي منهم ؟؟

انه false لماذا يا ترى ؟؟ لان ناتج التعبير المنطقي (sal_1>sal_2) هو خاطئ ...

ركز على كلمة تعبير منطقي ... هذه الامور المنطقية تكلمت فيها حتى تعبت ... راجعها اذا لم تعرفها ..





3- المتغيرات المركبة Composite Data type


متغيرات بها اكثر من قيمة ... سنخوض فيها حتى تطفش وتزهق مني ..

والجدير بالامر انها تحمل سجل كامل من قاعدة بيانات .... او يمكن جدول كامل !!





4- المتغيرات التي تخص الكائنات الكبيرة الحجم .. Large Object Data type


وهي تخص بتخزين القيم الضخمة من فيديو وملف صوتي وصور ..... ولن اتكلم عنها لانني انا بنفسي لم استخدمها ... يمكن لو لقيت الوقت الكافي ... ان ابحث فيها .





5- متغيرات الربط bind variables .


وهي متغيرات شاملة .. يعني نحن لو عرفنا المتغير a في برنامج ما ... بعد ان ينتهي البرنامج ماذا تتوقع يحصل ؟

سوف ينتهي صلاحية هذا المتغير ... طيب .. نريد متغير يعمل لأكثر من برنامج .... يعني .. انظر كيف نعرف هالمتغيرات :





SQL> variable a number;




عرفنا المتغير .... الذي يسمى بـ a





declare

abc number :=9;

begin

:a := abc;

dbms_output.put_line(:a);

end;

/




انظر كيف استخدمناه في هذا البرنامج ...

عرفنا متغير abc ويساوي تسعة ...

انظر الى المتغير a ماذا وضعنا قبله !!


وضعنا قبله العلامة :

اسندنا قيمة المتغير abc الى المتغير a


الان المتغير a به القيمة تسعة ..

انتهى البرنامج صح ؟ اذن مات المتغير abc وليس له وجود الان ...

تأكد بنفسك ....





begin

dbms_output.put_line(abc);

end ;

/







سوف يقول "لا وجود لشيء يدعى abc"


الان جرب ما يلي :





begin

dbms_output.put_line(:a);

end;

/




سوف يعطيك الناتج تسعة .. وهي اخر قيمة مخزنة في هذا المتغير ..

لنستعرض ما بداخله .. اليك الامر :





SQL> print a;



A

----------

9




الجدير بالذكر انك تستطيع ان تحفظها على القرص الصلب .. انا لا اعرف كيف ... >< اااسف




- تركيب لغة PLSQL وبعض الملاحظات عليها :




لغة الـ SQL و PLSQL مترابطة جدا , وستجد اننا سوف نأخذ بعض الدوال التي موجودة في SQL , وستجد مفاهيم اخرى جدا متشابهة ..

الان اريدك ان ترى بعض التراكيب في هذه اللغة .

- المتغيرات : وقد عرفنا خصائصها .

-القيم الثابتة : هي القيم النصية والرقمية وقيم التاريخ .. اشير الى ان التاريخ والنص يأتيان بين علامتي تنصيص .

- العمليات : وهي كما يلي :

الاس ** .... النفي NOT ,


الجمع + .... الطرح - .... الضرب * .... القسمة /

عمليات المقارنة = , > , < , =< , => , <> , IN , Between , LIKE , IS NULL....


العمليات المنطقية وهي AND OR

The Coder
01-03-2006, 11:55 PM
-الهوامش والملحوظات والتعليقات : وهي بعض التعليقات التي تنفعنا فيما بعد , يعني تخيل معي كتبت برنامج مكون من 1000 سطر , وأتيت عليه بعد سنتين ... هل ستذكر اسماء متغيراته ؟؟ هل ستذكر عمله بالضبط ؟؟


التعليقات فائدتها لكي ندون المعلومات التي ربما ننساها فيما بعد ... اريك طريقتين لعمل هذه التعليقات :

الطريقة الاولى باستخدام الرمز -- وهو يستخدم للسطر الواحد ...

لاحظ ان السطرين الثاني والثالث والسطر السادس لن يتم تنفيذهم , يعني أوراكل بيغطي عيونه عنها ولا ينفذها مهما كان فيها من اوامر .





declare

-- now we will declare a variable for

-- the gravity ... it's name is v_gra

v_gra constant number :=9.8 ;

begin

-- we will print it on the screen ...

dbms_output.put_line(v_gra);

end;

/




طيب ... عندي الفين سطر ابي اكتبهم تعليقات ..... يعني كل شوي اعمل بداية السطر -- ؟؟؟؟؟؟

اليك علامة /**/ ... وهي لمجموعة سطور ....

يعني /* اكتب التعليق هنا */

فهمت ؟ انظر :





declare

/* now we will declare a variable for

the gravity ... it's name is v_gra */

v_gra constant number :=9.8 ;

begin

/*we will print it on the screen ...*/

dbms_output.put_line(v_gra);

end;

/






- استخدام الدوال التي في لغة الـ SQL :


كل الدوال مسموح استخدامها في لغة PLSQL , من رقمية ونصية وتاريخية ودوال التحويل من نص الى تاريخ او من تاريخ الى نص او من رقم الى نص ....... كلها تستطيع استخدامها ... ما عدى :


1- Decode .... هل تذكرها ؟ هي غير مسموحة هنا

2- دوال الـ Group function مثل min , max , count …. ....... الخ




- الوحدات Blocks




ماهي الوحدات ؟

انظر المثال التالي :





declare

v_1 number ;

begin

v_1:=10;

end;

/




السطور التي بين begin و end تسمى وحدة block , في برنامجنا هذا يوجد وحدة واحدة صح ؟

في الحقيقة انه من declare وحتى end هذا يعتبر وحدة واحدة .....

طيب ... يوجد شيء جديد وهو الوحدات المتداخلة .. مجموعة وحدات في برنامج واحد ...

الان لنعمل برنامج به وحدتين ....وبرنامج اخر به ثلاث وحدات ... انظر شكلها في الصورة 1400:




http://img6.picsplace.to/img6/14/1400_000.jpg






لاحظ كلمة الوحدات المتداخلة .... Nested Blocks


يعني تتداخل فيما بينها ...

انتبه الى تركيبها ... لا تقل تركيبها مثل الصورة 1401 :


http://img7.picsplace.to/img7/10/1401.jpg


الصورة 1401 هذه .. مفهومها خطأ !!انتبه ...

الصح تجده في الصورة 1400





الان انظر الى المثال الخاطئ ... فكر لماذا هو خاطئ ؟؟





declare

v_1 number :=1;

begin

dbms_output.put_line(v_1);

declare

v_2 number :=2;

begin

dbms_output.put_line(v_2);

end;

v_1 :=10;

dbms_output.put_line(v_2);

end;

/




فكر فكر فكر ....





انا اخبرك .. في السطر الذي قبل الاخير .. قال اطبع المتغير v_2 ....


لقد عرفنا المتغير v_2 في وحدة داخلية Sub Block (تنبه للكلمة الانجليزية) .... في السطر السادس ..

لكنه مات هذا المتغير ... في السطر التاسع عندما رأى نهاية الوحدة end


يعني ... اذا ماتت الوحدة ... تموت متغيراتها معها , ولن يبقى لها اثر !! تنبه لهذه النقطة , فلن يخبرك أي كتاب عنها !!





الان اريد ان اتكلم قليلا عن مهارة جديدة ... وهي مهارة التتبع trace !!


مهارة التتبع هذه من اهم المهارات في البرمجة , انا سميتها مهارة لانها فعلا تحتاج مهارة ..

هي مملة ... تجيب القلق والمرض , ويمكن تجيب الحول في العيون ... صداع .... طفش ....

لكن هي مهمة ... مهمة جدا ...

لو عملت برنامج مثلا , وطلع فيه خطأ .... ماذا تعمل ؟ تتبعه ... تشوف مالذي يحدث في السطور , تحاول ان تكفش الخطأ ....

بالتمرس سوف ترى هذه المهارة ان شاء الله سهلة , وسوف اعلمك تكنيك رائع فيها , وقد اخذتها بخبرة وليس بعلم , يعني لا اعتقد انه يوجد كتاب يتحدث عن تقنيات التتبع بالتفصيل ....

The Coder
01-03-2006, 11:58 PM
ملاحظات برمجية :





انواع الاخطاء البرمجية :


اولا اريدك ان تعرف مصطلحين برمجيين ... اعرف انك تريد قتلي .. ولكن افهم يا اخي .... وسوف يسهل عليك كل شيء .. .

المفسر , والمترجم .. لا ادري .. ايهما Compiler وايهما Interpreter ...


لكن .... اعتقد ان المترجم Compiler


لا عليك من الترجمة ... لان ترجمة Compiler هي المجمع ...

وعلى اسمه ... يأخذ الكود البرمجي كله .... ويحاول اصطياد الاخطاء ضربة واحدة , ويظهر لك الاخطاء مجمعة ...

المفسر لا ..... يأخذ الكود سطر سطر ... ويرى هل السطر الاول صحيح ... اذن اكمل الكتابة ..

تأتي السطر الثاني .. ويقول هل هذا السطر صحيح ... وهكذا ... طبعا عملية المفسر عملية بطيئة بالمرة ..

و اغلبية اللغات تعتمد على المترجم ... او المجمع Compiler


هل استطعت ان تستنتج عمل هذين ؟ وما هما بالضبط ؟؟

عملهما هو اصطياد الاخطاء .. اذا لم يوجد اخطاء ... فسوف يترجمان كودك البرمجي .. الى لغة الالة .. وهي اللغة التي يفهمها الحاسب ... وهي لغة الصفر والواحد ....

هما ليس الا برنامجين ..... عملهما هو اخذ كودك البرمجي وترجمته الى لغة الالة ... هذا كل شيء ....

اقصد بالكود البرمجي ... program code او الكود المصدر Source Code وهو الشفرة البرمجية ...

وهو البرنامج نفسه ... المكتوب باحد لغات البرمجة .... هذا ما اقصده بالكود ...





الان الاخطاء هي :


الاخطاء التركيبية Syntax Errors


الاخطاء وقت التنفيذ Runtime Errors


الاخطاء المنطقية Logic Errors


هذه الثلاث انواع المشهورة , ولا اعتقد انه يوجد رابع ,,

سوف اتحدث بشيء من التفصيل فيها ,, لذا تنبه لهذه الانواع التي من الممكن ان تقع وانت تبرمج , فرصتك اذا ما بتعرف تبرمج , انا الان احاول ان اجعلك حريف برمجة ...





الاخطاء التركيبية Syntax Errors


هل نسيت فاصلة , هل قد غلطت وكتبت اسم متغير مو موجود , هل قد نسيت حرف ..

هذه الاخطاء الشائعة هي الاخطاء التركيبية , يعني لغة الـ PLSQL شكلها محدد , وتركيبتها محددة ....لو خالفتها او اخطأت فيها , فسوف يظهر لك رسالة خطأ ...

هي صراحة مزعجة جدا جدا جدا ... لكنها مفيدة جدا جدا جدا .... ولا تتشائم منها ... بل يجب عليك ان تفضل هذه الميزة .... لماذا ؟؟

انا لما كنت ابرمج في لغة ما .. وتدعى C++ (من لا يعرفها ؟؟) كنت اسب واشتم والعن حينما تأتي هذه الاخطاء , فيما بعد .. برمجت في مايسمى بلغات الاسكربت ... هذه اللغات (اقصد لغات الاسكربت)حينما لا تعرف متغيرات ... هي من وحدها تعرفه ...

بالله عليك لو قلت :


V1 number :=10 ;

Begin

Dbms_output.put_line(V11);





هل هذا خطأ ؟؟ طبعا خطأ !! .... انا مثلا اخطأت ... غلطت ... لا ادري كيف غلطت ... زلة كيبورد ... سرحت في وجبة عشاء .. المهم انني لا اعرف كيف اخطأت !!

وكتبت البرنامج السابق ... الـ PLSQL واللغات الاخرى سوف تقول لي خطأ !! لا يوجد متغير V11


تأتي انت مثلي .. تسب وتلعن وتشتم ..... وتعدل خطأك وانت متلهف تريد ان ترى برنامجك .. وظهر خطأ ثاني ... و يرجع امبير الضغط الى الاتش في رأسك ...





في لغات الاسكربت ... سوف تعرف هي اوتوماتيكي المتغير V11 يعني يصير متغيرين موجودين ...

تأتي انت ... وترى الناتج NULL .... تقول انا بنفسي وضعت قيمة 10 في هذا المتغير (وانت لا تدري انك اخطأت !! )

هذا طبعا خطأ بسيط ... لكن حينما يكون امامك 30 او 60 متغير (مثل ما حصل معي !!) فسوف تتمنى ميزة الاخطاء هذه ان ترجع ...





هي طبعا الاخطاء ليست في تعريف المتغيرات !! بل في نسيانك لحرف من دالة ما ... او نسيانك لفاصلة منقوطة ...





declare

v1 number :=0;

v2 number :=10;

begn

dbms_output.put_line('??');

end;

/



ERROR at line 6:

ORA-06550: line 6, column 1:

PLS-00103: Encountered the symbol "END" when expecting one of the following:

begin function package pragma procedure subtype type use

<an identifier> <a double-quoted delimited-identifier> form

current cursor




أين الخطأ يا ترى ؟؟

انه في كلمة begin ...... انا اخطأت وكتبتها begn ...


شباب ... تعودوا ان تقرأو الاخطاء ... ما اغباني ....

جلست فترة طويلة ... ابحث عن الاخطاء في برامج كثيرة .... واتأخر في اصطياده !! .... وبعض الاحيان لا اصطاده ... ينتابني اليأس ... ولما اقرأ الخطأ بتمعن ... تأتي كالصاعقة !! .... اذ بالخطأ واضح جدا جدا ... ولم انتبه له !!

لذا ... تعودوا ان تقرأوا الاخطاء ... ترجموها للعربي .. حاولوا ان تفكروا فيها .....





الاخطاء وقت التنفيذ Runtime Errors


الان ... عدلنا الاخطاء ... ويا سلام .. لا يوجد خطأ في برنامجنا ...

شغلناه ... نظرنا اليه ....

يا سلام .. البرنامج يشتغل مئة بالمئة .. لم يكتشف مترجم الأوراكل أي خطأ ... وها هو يشتغل ... نذهب نعمل شاي ... نرجع نلاقي البرنامج طلع لنا مئتين سطر ... اخطاء !!!!

لماذا ؟؟ الم نتخلص من الاخطاء التركيبية ؟؟ يأتينا خطأ "وقت التنفيذ" ؟؟؟

هذا النوع اخطر من سابقه !! يمكن لا تعرف مالمشكلة .... تبحث وتبحث وتتبع ... اكرر تتبع ..... وفي النهاية تجد الخطأ في عملية حسابية مثلا !!

اعطيك اشهر مثال .... وهو القسمة على صفر ... قلي صفر تقسيم عشرة تساوي كم ؟؟ تساوي صفر .

طيب عشرة تقسيم صفر ؟؟ كم تساوي ؟؟ يا اصحاب الرياضيات ... وينكم ؟؟

النتيجة هي "غير معروفة "....

حاسبات الدنيا لا تعرف نتيجة قسمة أي رقم على الصفر ....

اليك مثال حي عليها :





SQL> declare

2 v1 number :=0;

3 v2 number :=10;

4 begin

5 dbms_output.put_line('??');

6 dbms_output.put_line(v2/v1);

7 end;

8 /

??

declare

*

ERROR at line 1:

ORA-01476: divisor is equal to zero

ORA-06512: at line 6







في السطر الثاني عرفنا متغير به القيمة صفر ..

في السطر الثالث عرفنا متغير به القيمة 10

في السطر الخامس قلنا اعرض أي جملة على الشاشة ولتكن "؟؟"

في السطر السادس قلنا اعرض ناتج قسمة المتغير الثاني على المتغير الاول ....

كان المتغير الثاني 10 وكان المتغير الاول 0 ...

يعني 10 تقسيم 0 .... النتيجة غير معروفة ....





يأتي البرنامج ويقرأ هالكود البرمجي ..

يقرأ السطور جميعها ولا يجد اخطاء تركيبية ..

ثم يرجع ويقرأ لكي ينفذ ... بعد ان ضمن انه لا يوجد خطأ ...

يأتي في السطر الاول .. الثاني .. الثالث .... الرابع .. ينفذ ....

ثم يأتي السطر الخامس .... ويلاقي امر عرض القيمة "؟؟"

يعرضها ومافيه أي مشاكل .. حلوين وطيبين ولا يوجد خلافات عائلية ..

يأتي الى السطر السادس ... ويقول اعرض المتغير الثاني/ المتغير الاول ..

يحسبها في راسه ... وتطلع نتيجة غير معروفة ...

طبعا النتيجة الغير معروفة عنده ... يعني خطأ .... ليست كمثل الـ NULL !!


فرق بينهما ....

يأتي ... ويخبرك انه خطأ !! لا يجوز القسمة على الصفر !!

هل فهمت !! ...

The Coder
02-03-2006, 12:00 AM
مثال اخر ....








SQL> declare

2 v1 number :=10**10;

3 v2 number :=v1**2;

4 begin

5 dbms_output.put_line(v1);

6 dbms_output.put_line(v2);

7 v2:=v1**2;

8 end;

9 /

10000000000

100000000000000000000




معنى ** أي اس ..

عرفنا متغير v1 وهو يساوي 10 اس 10 ....

المتغير v2 يساوي v1 اس اثنين ...

البرنامج صحيح ومافيه مشاكل ... وعرض لنا القيمتين ... يا سلام ....

انظر الى البرنامج التالي .. نفس البرنامج السابق ... ولكن فيه مشكلة :





SQL> declare

2 v1 number :=10**100;

3 v2 number;

4 begin

5 dbms_output.put_line(v1);

6 v2:=v1**2;

7 dbms_output.put_line(v2);

8 end;

9 /

1.000000000000000000000000000000000000000000000000000000000000000000000000000000

000000000000000E+100

declare

*

ERROR at line 1:

ORA-06502: PL/SQL: numeric or value error

ORA-06512: at line 6




عرفنا المتغير v1 ويساوي 10 اس 100 !!!

عدد كبير جدا ....

اتينا وطبعناه عادي وطبع معانا .... اكرر .. طبع القيمة في السطر الخامس ....

ثم قلنا في السطر السادس ... المتغير v2 اجله تربيع المتغير v1 !!!


سوف ينتج لدينا عدد كبير جدا جدا جدا ... ما زلنا في السطر السادس ..

يقول أوراكل .."اخي ..... كسرت ظهري !! لماذا تريد ان تذبحني ؟ هذا عدد اكبر من سعة المتغير v2 !!!"


طبعا صار طفح !! ... صار زيادة وطفرة هائلة في المتغير !!

المتغير نوعه ماذا ؟ number ..... وهو لا يتحمل عدد مكون من مئة صفر ... ونأتي بتربيعه !! يعني مئتين صفر !!

هو تحمل مئة صفر ... لكن في النهاية .. لم يتحمل المئتين صفر !!

أي صار خطأ وقت التنفيذ ... لانه كان شغال مئة بالمئة ... والدليل عرض لنا المتغير v1 .... ثم وهو يفكر ويفحط وينفذ اوامرنا البلهاء ... طفح الكيل به لكي يعطينا خطأ وقت التنفيذ ... ارجو ان يكون ذلك مفهوم .... ولا يقتصر فهمك في عرض نتيجة ثم يظهر خطأ !! يمكن بعض الكمبيوترات تبقى ايام تخدم مجموعة هائلة من البشر ... وبعد هذه الايام صادف ان هنالك طفح في احد المتغيرات ... وياااااحبيبي ... تطلع رسالة خطأ تفيد بايقاف البرنامج ...

سوف نتعلم فيما بعد .. كيف نجعل برنامج ما ... مستقر ... أي اذا ظهرت مثل هذه الاخطاء ... يكون شغال لا يغلق ابدا !! .. سوف نتعلم هذا الاستقرار ...


اليك تحدي من نوع خاص !! .. وهو التحدي الاول !!

اريدك ان تعمل برنامج يعطيني خطأ وقت التنفيذ .. ليس لاعداد !! بل لمتغيرات نصية !!





الاخطاء المنطقية Logic Errors


العن وابشع الاخطاء .. والتي من الممكن تودينا في داهية ...

المصيبة انها خفية .. والمصيبة الاعظم اننا حتى لو اصلحناها .... فلا نعرف بعض الاحيان هل اصلحنا هذا الخطأ او وقعنا في خطأ منطقي اخر !!

هو لا يظهر رسالة خطأ قبل التنفيذ !! ولا يظهر رسالة خطأ اثناء التنفيذ !!

هو يسكت !! .. ويهز رأسه ويقول لك "مم .. مم .. صح صح ... انت صحيح !!"


وتبقى انت يا مسكين تعتقد انك صح ... ولا تعلم انك اكبر خاطئ في التاريخ ...

فكرته هي كالتالي .. تأتي انت وتعمل احصائية مثلا ... والاحصائيات فيها الجمع والقسمة والطرح والضرب والقتل والصلب ... واخرى لا تعلمها !! ...

وتأتي انت وتخطئ في مسئلة ما !! ... نسيت ان تضع الجذر مثلا !!

واذا بالبرنامج يصفق لك ... ويقول "انظر الناتج النهائي" !!

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

بعد التدقيق من قبل الدكاترة ... واذ النتيجة خطأ !!

لا تعرف .. كيف .. فين .. أين ... لماذا الخطأ !!

هل من البرنامج ؟ هل من قواعد الاحصاء ؟ هل من النظريات ؟ هل وهل وهل ؟؟ والحقيقة انك نسيت ذلك الجذر اللعين !!

تبا لهذا الخطأ !! المصيبة انه غير معروف المصدر !! .. والمصيبة الاعظم ان امثلته ليست كثيرة فحسب .. انما لا نهائية الاحتمالات !!.. انا شخصيا اكرهه ....ويحدث معي بشكل متكرر ... وهو اكثر الاخطاء شناعة ..

اذ انني ابحث وابحث وابحث ... واتتبع البرنامج ولا اعرف أين الخطأ !!

طبعا انا اتكلم في برنامج مكون من 1000 سطر او 10000 سطر .... ليس في خمسين سطر فقط !!

اليك مثال ... ويا مكثر الامثلة في هذا الخطأ اللعين .. مثال يوضح المعدل لثلاث قيم .. :





SQL> declare

2 v1 number :=10;

3 v2 number :=20;

4 v3 number :=60;

5 v_avg number ;

6 begin

7 v_avg := (v1 + v2 + v3)/3;

8 dbms_output.put_line('the averge is:'||v_avg);

9 end;

10 /

the averge is:30



PL/SQL procedure successfully completed.




طبعا هذا البرنامج صحيح مئة بالمئة ..

تأتي انت .... مثلا وتخطئ في السطر السابع ....فبدلا من ان تكتب عدد المتغيرات وهو ثلاث قيم .. كتبت اثنين ...

وتظهر المعدل ... وانت تعتقد انه صحيح :





SQL> declare

2 v1 number :=10;

3 v2 number :=20;

4 v3 number :=60;

5 v_avg number ;

6 begin

7 v_avg := (v1 + v2 + v3)/2;

8 dbms_output.put_line('the averge is:'||v_avg);

9 end;

10 /

the averge is:45



PL/SQL procedure successfully completed.




صدقني ...

انت ترى المثال السابق .. سهل ويمكن اكتشاف الخطأ !!

اعرف انك تقول ذلك .. لكن انا مجرب هذا الخطأ !! في امثلة معقدة .. واكثر من معقدة , سوف تقطع شعرك اذا لم تنتبه لهذا الخطأ !!







مالذي يحصل بداخل أوراكل ؟


عادة في المترجمات الخاصة باللغات الاخرى ....

يأخذ المترجم الكود المصدر ... ثم يحوله الى لغة الالة .... أي اصفار واحاد ..

يعني بالفصيح ..... يحوله الى ملف تنفيذي .. من نوع exe ...


الملفات بداخل الجهاز في الحقيقة نوعين ..

ملف تنفيذي ... وملف مقروء ....


مثال على الملف المقروء ... ملفات الوورد ... ملفات الاكسس .. ملفات النوت باد .... ملفات قواعد البيانات ..

ولا تنسى ان المجلدات folder ليست الا ملف ... ملف عادي جدا , صراحة نستطيع بطريقة ما ان نقرأ الملف هذا ...

مثال على الملف التنفيذي .... هو ملفات exe , مثل البرامج , الفيروسات ......

هي ملفات عادة لا نستطيع ان نقرأها ..

هي اوامر ... يا حاسب اعمل .. يا حاسب افعل ...

الكمبيوتر حينما يقرأها ... يعرف انها اوامر ... فيبدأ بتنفيذها عند تشغيلها ....

نستطيع القول الان .. ان الملف الذي به الكود المصدر ... ملف مقروء ... وسوف يتحول الى ملف تنفيذي ...

بواسطة ماذا ؟ بواسطة المترجمات ...

يأخذ المترجم الخاص بالأوراكل الكود البرمجي ويقرأه ثم يتأكد من الاخطاء , وبعدها يحوله الى ملف

يدعى بـ P-CODE .. معلوماتنا عن هذا الملف ... قليلة ..... ان شاء الله اعمل فيه بحث ..

وساتكلم عنه ان شاء الله في الدروس القادمة ..





اريد ان انوه ... انني سأتبع اسلوب غريب ...

سوف لن اشرح بالعناوين , بل سأشرح بالامثلة ....

سوف اكثر من الامثلة ..... واخترع الامثلة .... لكي يتسنى لكم الفهم ....

وجدت ان اقصر الطرق ماذا ؟ هي التقليد ... يعني شوف امثلة .. قلدها ... غير فيها ... افهم فكرتها ... وفي النهاية سوف تستطيع ان تعمل برامج بنفسك في اسرع وقت ... ان شاء الله ...

The Coder
07-03-2006, 01:32 AM
بسم الله الرحمن الرحيم

الدرس الثالث عشر


اسم الدرس :لغة PLSQL والتفاعل مع سيرفر أوراكل بواسطة جمل الاستعلام .


نوع الدرس : تطبيقي


صعوبة الدرس : **** من *****


الوقت المتوقع منك لفهم الدرس : اربع ساعات .


المتوقع منك في هذا الدرس :


- ان تخلط ... وتمزج لغتي SQL و PLSQL


- الجمل الشرطية ...





هيا لنؤركل ^^





السلام عليكم ,,

قبل البدء في درس اليوم ... اتوقع انك حللت تحديات الدرس السابق ..

كان تحدي واحد وهو :


اريدك ان تعمل برنامج يعطيني خطأ وقت التنفيذ .. ليس لاعداد !! بل لمتغيرات نصية !!


قبل ان تشاهد الحل .. فكر فيه .. اقرأ الدرس السابق ....





الحل هو








SQL> declare

2 v varchar2(10):='hello ali!';

3 vv varchar2(2):='??';

4 begin

5 dbms_output.put_line(v);

6 vv:=vv||v;

7 dbms_output.put_line(vv);

8 end;

9 /

hello ali!

declare

*

ERROR at line 1:

ORA-06502: PL/SQL: numeric or value error: character string buffer too small

ORA-06512: at line 6




صغرنا حجم المتغير اصغر مما يجب في السطر الثالث ... ولما كان في السطر السادس .. اتى ونظر الى الناتج فوجده اكبر من المتغير ... أي ان


Vv||v='??hello ali'

Vv :='??hello ali'


ولما اراد تنفيذ هذه الخطوة لقي ان حجم المتغير حرفين فقط .....








درسنا لهذا اليوم هو التفاعل مع سيرفر أوراكل ...

وش هو سيرفر أوراكل ؟ يعني برنامج أوراكل الي يجيب لنا المصادر ويعدل لنا المصادر , و يتعامل مع المصادر resources , وش هي هالمصادر ؟

هي قواعد البيانات ... هي البيانات ... هي الملفات المخزنة لديه , هي الجداول وما الى ذلك

وطبعا لا نصل الى هذه الموارد الا عبر ماذا ؟ عبر لغة الـ SQL


يعني بالعربي . . درس اليوم هو خلط PLSQL مع SQL


لترى جمل الـ SQL في برنامج الـ PLSQL

The Coder
07-03-2006, 01:40 AM
استخدام جمل الاستعلام :


هيا لنعرض اسم صاحب الرقم 7839 , ببرنامج PLSQL ... اتوقع كم شخص يحمل الرقم 7839 ؟؟ طبعا واحد شخص .. واحد موظف ليس الا .... لماذا ؟؟ سوال غبي ... لانه مفتاح أساسي !! ولا يملك الرقم 7839 الا موظف واحد ,, لذا ... فان ناتج جملة الاستعلام كم صف ؟ صف واحد ... اكرر سجل واحد .










declare

v_name varchar(15);

begin

select ename into v_name from emp where empno=7839;

dbms_output.put_line(v_name);

end;

/




انظر الى البرنامج ....

في السطر الثاني عرفنا متغير من نوع ماذا ؟؟؟ من نوع نص وحده 15 حرف ....

في السطر الرابع جملة استعلام غريبة قليلا , فيها زيادة into v_name .... ما معناها ؟

يعني ... يا أوراكل ... احضر لي اسم الموظف وضعه في المتغير v_name ..... خزنه في هذا المتغير ..

أي موظف ؟؟ أي الموظف رقمه 7839 .... وطبعا لا يوجد الا موظف واحد ... وهو KING ...


طبعا يكون الناتج سجل واحد وعمود واحد ... اكرر .... يعني قيمة واحدة !!

الان المتغير v_name .... مالموجود به ؟ اسم الموظف الذي يحمل الرقم 7839 ...

في السطر الخامس قلنا اطبعه على الشاشة ...

ستكون المخرجات هي :





KING







وهو صاحب الرقم ..... 7839

لاحظ ان جملة الاستعلام هنا ليست للعرض ... بل لجلب البيانات من قاعدة البيانات ...

يعني .... لو قلنا :





select ename from emp where empno=7839 ;




فان أوراكل يفهم انه لغة SQL فقط ...

وسوف يعرضها ..

لكن نحن بداخل برنامج .... أي ان معنى جملة select ..... في برنامجنا ليست "اعرض"

بل معناها "اجلب" .... هات .... احضر يا أوراكل .....

احضر البيانات من قاعدة البيانات .. وأتي بها الى برنامجنا ..





لاحظ جملة الاستعلام في نهايتها فاصلة منقوطة ..

لاحظ انها تحتوي على عمود ename .... وهو عمود واحد , ونوعه نص واعتقد ان حده 15 حرفا ....

ولاحظ انني عرفت متغير من نفس نوع عمود ename .... لاننا وضعنا قيمة من العمود الى المتغير المفترض ان يكون نوعه نفس نوع العمود !





لنعقد الامور .... ونخترع مشاكل ... اليك برنامج فيه خطأ ....





declare

v_name varchar(5);

begin

select ename into v_name from emp where empno=7654 ;

dbms_output.put_line(v_name);

end;

/




تتوقع ما هو الخطأ ... مع العلم ان الموظف الذي رقمه 7654 هو الموظف Martin


فكر قليلا ....

من الممكن ان لا يكون خطأ .... ويمكن يكون .... ما رأيك ؟؟





انا اخبرك ...

يوجد خطأ .....

وهو ان حجم المتغير v_name .... كم حرف ؟ 5 حروف ..

في السطر الرابع .... نفذ الأوراكل جملة الاستعلام , ثم وجد ان الناتج سجل واحد , وقيمة واحدة ...

اكرر قيمة واحدة .... أي انه سجل واحد وعمود واحد .. صح ؟؟ تأكد بنفسك ..

المهم وجد ان القيمة هي "MARTIN" ... يا سلام .. سوف يضعه في المتغير الذي اسمه v_name


يأتي .. وهو مبسوط , ويضع الاسم مارتن المكون من ست حروف .. ويجد ان المتغير لا يحمل الا خمس حروف ..!!

يصيح باعلى صوته ويقول :





ERROR at line 1:

ORA-06502: PL/SQL: numeric or value error: character string buffer too small

ORA-06512: at line 4




يضع فيك عيوب البشر كلها , ويفضحك بين العرب ويقول لك ..... ان المتغير صغير جدا جدا جدا ....

حرام عليك يا أوراكل .... ياخي صحيح انه صغير .. وما بيكفي .. بس لا تكبر الموضوع وتقول صغير جدا جدا جدا


.... منافق الأوراكل ....

مالعمل ؟؟؟ مشكلة .. لو كنت تتعامل مع جدول به ستة وعشرون الف مليار سجل , والفين عمود ... ونحن نريد ان نعرف متغير يشبه العمود X في هذا الجدول الضخم الذي يدعى بـ Z .... بالله عليك كيف نعرف حجم هذا العمود ؟؟ نروح ... ونكتب ما يلي :





Desc Z ;




وسوف يعرض لنا الفين سطر لاعمدته الالفين وانواعها , ... ندور على العمود الي اسمه x وبعد عناء ... نجده من نوع رقم وسعته 4 ارقام ...


X number(4)


متعبة هاه ؟

ماذا ؟ ليست متعبة ؟ طيب طيب ...


لو عندنا الف متغير ... يشبهون الف عمود مختلف من مئة جدول مختلف ... هل ستذهب في كل مرة وتراها عمود عمود ؟؟ اتحداك تسويها ... روح استقيل احسن ...

هذه مشكلة اذن ... ونحتاج لحل سريع وسهل ... ماذا ؟ ليست مشكلة لديك ؟؟

طيب طيب .. انظر الى المثال البسيط التالي :








declare

v_name varchar(15);

begin

select ename into v_name from emp where empno=7654 ;

dbms_output.put_line(v_name);

end;

/




نفس المثال السابق ولكن حينما اكتشفنا ان العمود ename من نوع نص , وسعته 15 حرف ...

وضعنا المتغير 15 حرف ....

الان البرنامج يشتغل ... ويا سلام ... سوف تحفظه في ملف .. لكي يشتغل على طول ....

وسوف نتعلم كيف نحفظ هذه البرامج ...

بعد اسبوع .. اتى نذل يريد الحاق العار بك .... و غير العمود ename وجعله 16 خانة .. وادخل اسم موظف مكون من 16 حرف ....

تأتي انت مبسوط ... وتشغل امام المدير برنامجك ... واذا .... بنفاق أوراكل واتهامه وافترائاته تتجه نحوك ..

لن يفصلك المدير ولكن .. سوف يمترك بنظره من فوق لتحت .. ويمشي ... تأتي انت وترى مالمشكلة ... و .......









لن اكمل ولكن ... هي صراحة ليست مشكلة .... بل مصيبة !!

يعني بدل ما احفظ برنامج للابد يشتغل صح .... مهما صارت التغييرات , يعني شغل احترافي ...

اطلت عليك ولكن اريدك ان تعيييييييييش المصائب الان , لكي لا تعيشها فيما بعد ...

هنا ميزة في هذه اللغة رائعة جدا ... انظر الى المثال ....





declare

v_name emp.ename%type ;

begin

select ename into v_name from emp where empno=7654 ;

dbms_output.put_line(v_name);

end;

/







ركز جيدا في السطر الثاني .. يوجد كلام كثير ....


v_name emp.ename%type;


عرفنا متغير من نوع ماذا ؟ من نوع حرف ؟ رقم ؟ تاريخ ؟ نصوص ؟ جغرافيا ؟

بل من نفس نوع العمود ename الذي يقطن في الجدول emp ..... اكرر نفس نوع العمود ename !!


يعني لو حرف ... يكون المتغير v_name حرف ... لو العمود رقم مكون من ست عشر خانة ... حيكون المتغير مثله تماما ... لو اليوم نص 5 حروف ... وبكرة 20 حرف ..... سيكون المتغير اليوم 5 حروف .. وبكرة 20 حرف ..

مثله ..شبهه تماما ...

والله رائعة هالنقطة ...

انظر المخرجات :





MARTIN






لاحظ للمرة المليون ... ان جملة الاستعلام ترجع لنا كم سجل ؟؟؟ سجل واحد ...

انظر الى مثال ثاني ... سوف يعرض صاحب الرقم 7654 و اسم القسم الذي يعمل به ..





declare

v_ename emp.ename%type;

v_dname dept.dname%type;

begin

select e.ename , d.dname into v_ename , v_dname

from emp e, dept d

where e.deptno=d.deptno

and e.empno=7654 ;

dbms_output.put_line('the name is :'||v_ename||' and his dept name is:'||v_dname);

end;

/




برنامج دسم قليلا ....

السطر الثاني .. عرفنا متغير اسمه v_ename ونوعه هو نفس نوع العمود ename في جدول emp


السطر الثالث .. عرفنا متغير اخر اسمه v_dname ونوعه هو نفس نوع العمود dname في جدول dept


السطور الخامس السادس السابع والثامن ... به جملة استعلام تحضر لنا اسم الموظف و اسم القسم الذي يعمل فيه ... ثم سيضع الاسم واسم القسم فين ؟ في المتغيرين التاليين v_ename , v_dname ....


لاحظ الترتيب .... v_ename سوف يكون فيها اسم الموظف e.ename ...


وايضا v_dname سيكون فيها اسم القسم d.dname


الان اسألك .. ما بداخل المتغير v_dname ؟؟؟

اخي اذا لم تعرف ... خليك ذكي .. وخذ جملة الاستعلام .. وشوف وش يطلع لك ...





SQL> select e.ename , d.dname from emp e, dept d

2 where e.deptno=d.deptno

3 and e.empno=7654 ;



ENAME DNAME

---------- --------------

MARTIN SALES




يعني في داخل المتغير v_dname ... ماذا ؟ بداخله طبعا القيمة SALES


الان في السطر التاسع .... سوف يعرض لنا اسم الموظف واسم قسمه ... لكل موظف يحمل الرقم 7654 ....

ارجو ان يكون مفهوما وانظر الى الناتج كيف اصبح ... فكر فيه كيف صار الناتج هيك :





the name is :MARTIN and his dept name is:SALES




الان اليك تحدي ....

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


في برنامجنا السابق يطبع اسم الموظف واسم قسمه .. للموظف الذي رقمه 7654 .... بجملة استعلام واحدة ...

وكما تلاحظ اننا ربطنا جدولين ...

المطلوب ... تخيل انه محرم ربط الجداول ... ماذا تفعل في هذه الحالة ؟ ولكي ابشرك .. يوجد طريقتين ...

هيا برمج لنا برنامج بجملة استعلام لا تحتوي على ربط جداول .... وحاول ايجاد هذه الطريقتين ..

The Coder
07-03-2006, 01:48 AM
,,


الان ...

هل تذكر اننا قلنا انه لا نستطيع استخدام نوعين من دوال الـ SQL في داخل هذه الدالة ؟

ما هما ؟


Decode و دوال المتعددة الصفوف مثل count , min , max ...


ماذا كنت انا اقصد ؟

هل صحيح لا نستطيع استخدامها ؟؟ طيب انظر المثال التالي ... يعرض لنا عدد الموظفين في الجدول emp





declare

v_count number ;

begin

select count(*) into v_count from emp ;

dbms_output.put_line(v_count);

end;

/




سوف يطبع 14 .... كما هو موضح عندي .. لا ادري كم الموظفين عندك .

المهم ....

استطعنا استخدام الدالة !! ..... كيف ؟

هو صحيح انها محرم استخدامها داخل لغة PLSQL .... ولكنها في مثالنا هذا .. داخل لغة SQL !!


هل فهمت الفكرة !! ...

انظر الى هذا المثال الذي سوف يطبع راتب الموظف الذي رقمه 7654 بهذه الصيغة : $01,234.00







declare

v_sal scott.emp.sal%type;

begin

select scott.emp.sal into v_sal from scott.emp

where scott.emp.empno=7654;

dbms_output.put_line( to_char(v_sal , '$00,000.00'));

end;

/


اردت توضيح الدالة to_char شوف كيف استخدمناها في لغة الـ PLSQL ....


وهي اخذت المتغير v_empno .. وهو رقم طبعا .. وحولته الى نص ... بهذه الهيئة $00,000.00 .... اعتقد انك تذكر عمل هذه الدالة , وتكلمنا حتى طفشنا فيها .. المهم المخرجات هي كما يلي :


$01,250.00





الان ... اتضحت فكرة استخدام دوال SQL داخل لغة الـ PLSQL ؟؟؟

طيب .. انظر الى البرنامج مرة ثانية ....

ستجد شيء زيادة .... في السطر الثاني ... والسطر الرابع والخامس ... ماهو ؟


Scott.emp.sal%type

Scott.emp.sal

Scott.emp

Scott.emp.empno

....


اعتقد انك عرفت لماذا انا وضعتها ..

تخيل انني المستخدم Silver ...


هل لو كتبت البرنامج التالي :





declare

v_sal emp.sal%type;

begin

select

emp.sal into v_sal from emp

where emp.empno=7654;

dbms_output.put_line( to_char(v_sal , '$00,000.00'));

end;

/




حيشتغل ؟؟

لن يشتغل !!

ليش ؟ وش السبب ؟ وش بيقول الأوراكل ؟

بيقول "لا يوجد جدول اسمه emp ... يا سلفر !!"

وهو صادق ... اذن ... مالحل ؟ مالعمل ؟

تكتب البرنامج السابق الذي مفاده :





declare

v_sal scott.emp.sal%type;

begin

select scott.emp.sal into v_sal from scott.emp

where scott.emp.empno=7654;

dbms_output.put_line( to_char(v_sal , '$00,000.00'));

end;

/


هل فهمت ؟

من الان وصاعد .. تعود ان تكتب برامجك بهذه الصورة .. ياريت والله تفتكر هالنقطة ..

انا سوف اتجاهلها كثيرا لاني اشرح وغارق في الشرح ...

ارجو ان تتعود حتى في حل التحديات ان تكتب بهذه الصورة ... ارجوا ذلك ...





طيب ...

الان اليك برنامج يطبع كل بيانات الموظف الذي رقمه 7654 ,, هيا انظر الى البرنامج

طيب ... ماهي الاعمدة في جدول الموظفين ؟؟

ممممم ... رقم الموظف .. اسمه .. راتبه .. رقم القسم ... ممممم ... نسيت .....

اها ... رقم مديره ... ممممم ...... نسيت البقية >< ...

اذن سوف اراها بجملة الاستعلام :


Desc emp;


لكي اشاهد الاعمدة ...

ممممم ثماني اعمدة ....





declare

v_empno scott.emp.empno%type;

v_ename scott.emp.ename%type;

v_job scott.emp.job%type;

v_mgr scott.emp.mgr%type;

v_hiredate scott.emp.hiredate%type;

v_sal scott.emp.sal%type;

v_comm scott.emp.comm%type;

v_deptno scott.emp.deptno%type;

begin

select scott.emp.empno , scott.emp.ename , scott.emp.job

,scott.emp.mgr , scott.emp.hiredate ,scott.emp.sal

,scott.emp.comm , scott.emp.deptno

into v_empno , v_ename , v_job , v_mgr , v_hiredate

,v_sal , v_comm , v_deptno

from scott.emp where scott.emp.empno=7654;

dbms_output.put_line('the name:'||v_ename);

dbms_output.put_line('the number:'||v_empno);

dbms_output.put_line('the job:'||v_job);

dbms_output.put_line('the mgr:'||v_mgr);

dbms_output.put_line('the hire date :'||v_hiredate);

dbms_output.put_line('the salary:'||v_sal);

dbms_output.put_line('the comm:'||v_comm);

dbms_output.put_line('the deptno:'||v_deptno);

end;

/




كحححححح كحححححححححح كححححححححح ..... افففففففف

تعبت ....

كأنني مشيت الف ميل ....( دنا احوليت يارقالة !!)


26 سطر ... هالبرنامج ... ولا تجعلني اخبرك كم خطأ سوف يظهر ..

ولا تجعلني اخبرك انه مجرد 8 اعمدة فما بالك 100 عمود ....

سوف انقلهم واحد تلو الاخر .. يعني حتكثر التعريفات ... وتتلخبط علينا ....

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

بالله عليك اقرأه قليلا ... تمعن في اسم المستخدم ثم اسم الجدول ثم اسم العمود ....

تمعن وانظر كيف جملة الاستعلام ضخمة ... فما بالك بربط ثلاث جداول مثلا ...

تمعن وانظر .... كم تعريف ..

انظر الى المخرجات Output :








the name:MARTIN

the number:7654

the job:SALESMAN

the mgr:7698

the hire date :28/09/81

the salary:1250

the comm:1400

the deptno:30







خلينا واقعيين وعمليين وانتاجيين .... نريد حل يا PLSQL الله يرضى عليك ....

هاه ؟ ماذا قلت ؟ متغيرات من نوع سجلات ؟؟؟ وما هذه المتغيرات ؟

انظر الى البرنامج التالي .. اختصر علينا بعض التعب بس ... بالله لاحظ ان البرنامج صغر الى 14 سطر !

صراحة انجاز عظيم .... من 26 الى 14 سطر !! والله اعتبره قمة العبقرية !!

صدقني انه شيء رائع جدا في نظري .....





declare

r_emp scott.emp%rowtype;

begin

select * into r_emp from scott.emp where scott.emp.empno=7654;

dbms_output.put_line('the name:'||r_emp.ename);

dbms_output.put_line('the number:'||r_emp.empno);

dbms_output.put_line('the job:'||r_emp.job);

dbms_output.put_line('the mgr:'||r_emp.mgr);

dbms_output.put_line('the hire date :'||r_emp.hiredate);

dbms_output.put_line('the salary:'||r_emp.sal);

dbms_output.put_line('the comm:'||r_emp.comm);

dbms_output.put_line('the deptno:'||r_emp.deptno);

end;

/






... ولو ركزت ... تلاقي البرنامج الثاني اكثر سهولة بكثييييييييييير

ومقروء اكثر (قابل للقرائة وسهل القرائة)

نفس المخرجات ...

طيب ...

مالذي حصل بالفعل ....





في السطر الثاني ...عرفنا متغير r_emp ... نوعه ماذا ؟

نوعه scott.emp%rowtype


ما معنى هذا الكلام .. ركز ..

يعني ... اجعل نوع المتغير e_emp سجل ... ( row type تعني نوع سجل )

نوعه ماذا ؟ نوعه سجل ... سجل من ؟ سجل احمد ؟؟ محمد ؟؟

لا لا ... بل سجل جدول ... يعني صف جدول ...

أي جدول ؟ جدول الموظفين الخاص بالمستخدم scott


ماذا يعني "اجعل المتغير r_emp نوعه مثل سجل الجدول emp" ؟؟؟؟ ماذا نقصد بها اصلا ؟

انظر كيف يفكر الأوراكل ...

يأتي الى جدول emp ... ويرى كم عمود فيه ... يجده ثمانية ....

ماهي ؟ ename , empno , sal ........


الان سوف يجعل المتغير r_emp ... به ثماني متغيرات !!

يعني المتغير r_emp .... هو ليس الا مجموعة متغيرات !! أي انه متغير كبيــــــــــر ...

ماهي هذه المتغيرات الثمانية ؟ ما اسمائها ؟ اسماءها نفس اسماء اعمدة الجدول emp !!


بدأت الامور تتشربك ... اعد قرائة السطور السابقة .. فكر في عقلك ... متغير كبير ..... مقسم الى عدد من المتغيرات !!

دعنا نرسم شكل في مخيلتنا .... انا تخيلت الشكل التالي .. للمتغير الصورة 1500:

The Coder
07-03-2006, 01:50 AM
سوري .. الصورة 1500
http://img9.picsplace.to/img9/7/1500.jpg


طيب طيب .... هل انتهى كل شي ؟؟ لا لا ..

يوجد مشكلة بالنسبة لاوراكل ... يريد ان يستخدم المتغير empno الموجود في هذا المتغير r_emp ..


كيف ؟ كيف يعرف ان empno للمتغير r_emp ؟؟؟؟

بسيطة ... اليك حل :


r_emp.empno


سيكون المتغير empno ... الموجود في المتغير r_emp .... بس ... هذه الفكرة ...





ستجد في السطر الرابع جملة استعلام بسيطة جدا .... انظر ماذا تقول ...


Select * into r_emp from scott.emp where scott.emp.empno=7654 ;


سيضع كل الحقول .. بنفس الترتيب .... في المتغير r_emp ..... والذي نوعه ماذا ؟ نوعه سجل .. سجل ماذا ؟ سجل جدول الموظفين .. emp


طبعا في هذا السطر الرابع ... سوف تكون ناتج الاستعلام :


Select * from scott.emp where scott.emp.empno=7654 ;





EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

----- ---------- --------- ----- -------- ---------- ---------- ----------

7654 MARTIN SALESMAN 7698 28/09/81 1250 1400 30


لاحظ للمرة المليونين ونصف المليون .... اننا حتى الان ... نجد ان الناتج سجل واحد ...

طيب ... ماذا يعني في السطر الرابع ذلك الامر ؟

سوف يقوم بوضع القيمة التي في العمود empno الذي في الجدول emp ... فين ؟ في المتغير r_emp.empno ...


أي بمعنى اخر ... سيضع 7654 في المتغير r_emp.empno


ثم يضع MARTIN في المتغير r_emp.ename ....


وهكذا ...

ارجو ان يكون ذلك واضح ..





السطور من السطر الخامس الى السطر 12 ..... مخرجات ...

لاحظ كيف استخدمنا المتغير الجميل r_emp والذي نوعه سجل !!

ياسلام على هالنوع الجديد ...

استخدمنا في السابق متغيرات من نوع اعمدة ..

الان متغيرات من نوع سجلات !!

والله مرونة عالية , واختصار للوقت والجهد ...

طبعا اذا بتستخدم عدد قليل من الاعمدة .. لا تستخدم سجل كامل .. استخدم متغيرات من نوع الاعمدة التي تريدها , حتى لا تحجز من الذاكرة ... اكثر من حاجتك , انظر الى مثال يقتصد في





declare

r_emp scott.emp%rowtype;

begin

select scott.emp.ename , scott.emp.empno into r_emp.ename ,r_emp.empno

from scott.emp where scott.emp.empno=7654;

dbms_output.put_line('the name:'||r_emp.ename);

dbms_output.put_line('the number:'||r_emp.empno);

end;

/




تتبع البرنامج ... تدرب ان تقرأ برامج وتتبعها , وتحاول فهمها ...

اعرف ان هذا ممل ... لكن ... تحمل

اريدك ان تستنتج ماذا يعمل هذا البرنامج وما فائدته , فهو سهل جدا ... لا تطبقه في الحاسب الا بعد ان تفكر فيه .

هيا .. حاول ان تكتسب مهارة التتبع الجيد واستنتاج فوائد البرامج ....





الان اريدك ان تذكر شيء ... وهو data type ... أي انواع البيانات ..

مثل varchar و char و number و X%type و date و X%rowtype


هذه تسمى ماذا ؟ تسمى انواع البيانات data type ....


سوف نرجع لها قريبا ... فلا تنسى ...





مشاكل جمل الاستعلام مع لغة PLSQL


مشكلتين ...

ارجاع اكثر من سجل ...

او ارجاع صفر سجل ...

انظر الى المثال التالي :





declare

v_name scott.emp.ename%type;

begin

select ename into v_name from scott.emp;

dbms_output.put_line(v_name);

end;

/




شوف النتيجة الي تفشل :





ERROR at line 1:

ORA-01422: exact fetch returns more than requested number of rows

ORA-06512: at line 4




اقرأ الخطأ .... (وهو خطأ وقت التنفيذ Runtime Error)


انظر اليه بتمعن ....

يقول ان جملة الاستعلام ترجع كم سجل ؟ كم صف ؟ اكثر من صف واحد ..


اعيد واكرر للمرة الثلاث مليون وثلاثمئة وست واربعون ..... حتى الان امثلتنا لا ترجع الا صف واحد ..

طيب ... لما شفنا الان انها ترجع اكثر من صف اعتبرها خطأ ... بالله عليك وش نسوي ؟

الا يوجد طريقة لتساعدنا ؟

يوجد طريقة وتدعى بـالمؤشر .... Cursor .... وهو الكابوس الاعظم في هذه اللغة , كل من ارادني ان اشرح له هذه اللغة .. كان يريدني ان اشرح له المؤشرات .... هي سهلة وصعبة في نفس الوقت

قريبا سنشرحه ...

الان مشكلة السجلات المتعددة حللناها ان شاء الله

وتبقى مشكلة عدم ارجاع أي سجل قائمة والتي تعتبر Runtime Error , وحتى اشعار اخر ...





المنطق (جمل if الشرطية):


يوجد حل لمشكة عدم ارجاع أي سجل ... وهو حل متقدم .. يعني فيما بعد ...

يوجد حل اخر في رأسي اعتقد انه يصلح قليلا ... وسنحاول ان نوجده معا ....

ماهي هذه الجملة ؟ if الشرطية ؟؟

وما قصدي بالمنطق ؟

انا اخبرك ...

لو صار كذا وكذا اعمل كذا .... ولو ماصار كذا وكذا لا تعمل كذا بل اعمل كذا ....

احتمالات .... مسارات للاحداث ...

يا احمد ... لو اتى اخوك ... اذهب معه , واذا لم يأتي , اذهب لوحدك ..

ويا خالد اذا لم تكن مشغول ساعدني , واذا كنت مشغول فاذهب ....

اذا و اذا ... اذا لم ..

كلها هذه شروط .. اذا تحققت ... تصير بعض الامور ... واذا لم تتحقق تصير امور اخرى ..

هنا تكمن قوة البرمجة ... هنا يكمن المنطق الرقمي ... من هنا نستطيع عمل الذكاء الاصطناعي ..

من هنا نستطيع جعل البرامج ذكية .. ونجعلها نفكر تفكير سليم كما نفكر نحن ..

ندخل على الامثلة وبسرعة .... ونرى ما يمكننا فعله حيال هذه اللغة ....

برنامج يخبرنا اذا كان المتغير v يساوي عشرة ... سيقول "هذا المتغير يساوي عشرة" :








declare

v number :=10 ;

begin

if v=10 then

dbms_output.put_line('it is 10');

end if;

end;

/




انظر الى المخرجات :








it is 10




طيب طيب ...

السطر الثاني عرفنا متغير وقيمته 10 .....

في السطر الرابع قلنا "اذا v يساوي عشرة .... فانه " (معنى if أي "اذا" )

في السطر الخامس سوف يخرج الرسالة it is 10


في السطر السادس نهاية الشرط .....

ما معنى هذا الكلام ؟

لاحظ انه في السطر الرابع ... عملية اليساوي ... وليست اسناد !!

فرق بينهما !! = يعني مساواه ... =: ... يعني اسناد ووضع قيمة ....

الان في السطر الرابع سوف يتأكد هل ما بداخل v يساوي 10 او لا ...

سؤال .. ما بداخل المتغير v ؟؟ عشرة ..

طيب ... يقول اذا تحقق الشرط .. ما معنى اذا تحقق شرط ؟ واي شرط يتحدث عنه ؟

الشرط هو كما قلنا v=10 .. اذا نعم ... نفذ الأوامر من بعد سطر الشرط ... الى end if ....


اذا لم يتحقق أين يذهب ؟ في هذه الحالة ... سوف يذهب الى end if .... على طول ....

بعدها ينتهي البرنامج ...




انا اريد ان اضع قيمة اخرى .... دعنا نرى ذلك ....





declare

v number :=9;

begin

if v=10 then

dbms_output.put_line('it is 10');

end if;

end;

/




النتيجة .... لم يعرض شيء !!

لماذا لم يعرض شيء ؟

انظر الى البرنامج مرة ثانية ...

يقول اذا v=10 اطبع it is 10 ....


اذا لم يساوي v العشرة .... انتهى الشرط ... خلاص ...(لاحظ then هي كلمة زائدة ولكنها مهمة ... ومعناها "فإنه ")

هل انتهينا الى هذا الحد ؟ الا يوجد تعقيدات ؟





اريد ان يرى ... اذا كان عشرة .. يطبع لي 10 ... اذا كان تسعة .. يطبع لي 9





declare

v number :=9;

begin

if v=10 then

dbms_output.put_line('it is 10');

end if ;

if v=9 then

dbms_output.put_line('it is 9');

end if ;

end;

/


السطر الرابع .. اذا كان عشرة ... طبق السطور حتى اول end if تجده ...

طبعا ينفذ الامر الذي في السطر الخامس ... (عرض انه 10) ,,, في السطر السادس انتهى الشرط ...

في السطر السابع .. يقول اذا v=9 نفذ السطر الثامن .... (عرض انه 9) ....

في السطر التاسع انتهى الشرط ...

الان .. عرفت معناها ولم تفهم متى وكيف واين نستخدمها ....





انظر الى المثال ... نفسه ولكن يجعلك انت تدخل القيمة .. هل تذكر ادخال القيم ؟؟؟





declare

v number :=&Enter_Any_Number ;

begin

if v=10 then

dbms_output.put_line('it is 10');

end if ;

if v=9 then

dbms_output.put_line('it is 9');

end if ;

end;

/




جعلنا المتغير يساوي مدخل من عندنا ...

ماذا يعني مدخل من عندنا ؟ يعني نحن ندخل رقم وسوف يتخزن في هذا المتغير .. اعتقد تكلمنا فيها كثيرا ...

وطبعا علامة المدخل ... هي & .........


سوف يسألك ... ويطلب منك ادخال قيمة :










Enter value for enter_any_number: 10



it is 10




انا ادخلت 10 ....

قال لي it is 10


لو ادخلنا 9 ... سيقول لنا it is 9


طيب لو ادخلنا 8 ؟؟؟ لن يقول شيء ..... فكر فيها ..

ولكن لاحظ ان لكل شرط .. تقفيلة خاصة ... أي end if ....

The Coder
07-03-2006, 02:41 AM
انظر الى المثال البسيط ... اذا يساوي 10 .... اضرب العدد في اثنين ... واقسمه على اربع ... واعرضه :





declare

v number :=&V;

begin

if v=10 then

v:=v*2;

v:=v/4;

dbms_output.put_line(v);

end if ;

end ;

/




كل هذه الأوامر ينفذها .. اذا تحقق الشرط !! ...

يعني السطور 5 و 6 و 7 ... سوف تنفذ اذا كان العدد يساوي 10 ... هل فهمت ؟ بامكانك ان تضع ما شئت من الأوامر .... حتى لو كانت جمل استعلام او أي شيء اخر ....

لنشربك الموضوع ولنعقده اكثر واكثر ... ولنمارس فن التعذيب .....


اليك مثال يوضح اذا كان اكبر من الصفر معناه ماذا ؟ معناه موجب .. اذا اصغر من الصفر معناه سالب ...

اذا يساوي الصفر ... فاعرض صفرا ....










declare

v number :=&V;

begin

if v<0 then

dbms_output.put_line('-');

end if ;

if v>0 then

dbms_output.put_line('+');

end if ;

if v=0 then

dbms_output.put_line('0');

end if ;

end;

/










Enter value for v: 1



+










Enter value for v: -1000



-












Enter value for v: 0



0






لا تعليق ...





الان ... سوف نعقد اكثر واكثر ....

وسأعدك بان ارفع امبير الضغط عندك الى ما بعد الاتش ..

اريد برنامج يرى اذا كان المتغير اكبر من 10 ... يعرض "هو اكبر من 10 "....

اذا لم يكن اكبر من عشرة .. وكان اكبر من خمسة ... يعرض "هو اكبر من 5 وليس اكبر من 10"








declare

v number :=&V;

begin

if v>10 then

dbms_output.put_line('it is > 10 ');

end if ;

if v>5 then

dbms_output.put_line('it is not >10 but is >5 ');

end if ;

end;

/


في السطر الرابع .. اذا كان اكبر من 10 .... نفذ السطور التي بالاسفل (السطر الخامس) حتى جملة end if


في السطر السابع .. اذا كان اكبر من خمسة ... فنفذ السطور التي بالاسفل وحتى سطر end if .... (الذي بالسطر التاسع ) ... نجرب برنامجنا .. هل هو ذكي ... هل سيكتشف ذلك حقا ؟؟ لنرى :





Enter value for v: 1






جربنا الواحد .. ولله الحمد لم يطبع شيء .. لانه ليس اكبر من العشرة .... وليس اكبر من الخمسة .. فسوف لن ينفذ شيء ... يا سلام ...





Enter value for v: 6



it is not >10 but is >5




رائع ... الستة ايضا .... ليست اكبر من العشرة ... ولكنها اكبر من الخمسة

فطبع "انها ليست اكبر من 10 ولكنها اكبر من 5" ... رائع جميل ...





Enter value for v: 11



it is > 10

it is not >10 but is >5




جربنا 11 ... ياسلام .. يقول "انها اكبر من العشرة " .. صحيح .. جميل ..

يقول ايضا "انها ليست اكبر من العشرة .. ولكنها اكبر من الخمسة" ؟؟؟!$#؟#@؟$@$%@#$%

يوجد خطأ منطقي !! .... هذا هو الخطأ المنطقي !!

فكر قليلا ... ما هو السؤال ؟؟ ما هو المفترض ان يكون ؟؟ انا قلت ...

اريد برنامج يرى اذا كان المتغير اكبر من 10 ... يعرض "هو اكبر من 10 "....

اذا لم يكن اكبر من عشرة .. وكان اكبر من خمسة ... يعرض "هو اكبر من 5 وليس اكبر من 10"





انا لم اقل

اريد برنامج يرى اذا كان المتغير اكبر من 10 ... يعرض "هو اكبر من 10 "....

واذا كان اكبر من خمسة ... يعرض "هو اكبر من 5 وليس اكبر من 10"







فرق بين الحالتين .. اذا كان اكبر من 10 .. اعمل واعمل .. اذا لم يكن !! وكان اكبر من خمسة اعمل وافعل ...





بالله عليك قبل ان ترى الحل فكر ... فكر ولو قليلا ..








declare

v number :=&V;

begin

if v>10 then

dbms_output.put_line('it is > 10 ');

end if ;

if not(v>10) and v>5 then

dbms_output.put_line('it is not >10 but is >5 ');

end if ;

end;

/




ببساطة الحل في السطر السابع ...

يقول اذا لم يكن اكبر من عشرة .. و ....... كان اكبر من خمسة ..... فاطبع تلك الرسالة ..

منطقك الان يشتغل ... ورأيك يفكر ... وها انت تقترب من المنطق الصحيح ... والتفكير السليم ...

الحل السابق جميل ... ولكن ليس عملي ... لماذا ؟ انا اخبرك ..

لو كان اكبر من عشرة ... قل اكبر من عشرة ...

وإلا ..... اذا كان اكبر من خمسة ... قل اكبر من خمسة وليس اكبر من عشرة ...

وإلا اذا كان اكبر من ثلاثة قل اكبر من ثلاثة وليس اكبر من خمسة وعشرة ...





declare

v number :=&V;

begin

if v>10 then

dbms_output.put_line('it is > 10 ');

end if ;

if not(v>10) and v>5 then

dbms_output.put_line('it is not >10 but is >5 ');

end if ;

if not(v>10) and not(v>5) and v>3 then

dbms_output.put_line('it is not >10 and not >5 but is >3');

end if ;

end;

/




البرنامج صحيح ... جرب ان تضع القيم 2 و 4 و 6 و 11 ...

لكن ... انظر الى السطر الثالث .... والسابع ... و العاشر .... الشرط يكبر ويكبر ويكبر .....

هذا وانا قلت لك ..... 3 احتمالات فقط .. سوف تتعرض لبرامج بها العشرات والعشرات من الشروط والاحتمالات ...

سوف تتلخبط... سوف تكره حياتك ....

سوف تغلط .... سوف تكره برنامجك ..

الحل ؟ مالحل ؟ انها else .... و else if ....

Else .... تعني بالعربي وإلا ....

مثلا ... "حل الواجب وإلا قتلتك " يعني اذا لم يتنفذ شرط عملية حل الواجب ... سوف تنفذ فيك عملية القتل

اليك مثال جميل عليها .. مع العلم انهم اختصروها بدلا من else if قالو elsif


برنامج يرى المتغير ..لو اكبر من او يساوي الصفر يطبع + ... وإلا .... يطبع -








declare

v number :=&V;

begin

if v>0 then

dbms_output.put_line('it is +');

else

dbms_output.put_line('it is -');

end if ;

end ;

/




اولا ... انه شرطين ولهم تفقيلة واحدة end if ....


هل لاحظت ؟؟

يقول في السطر الرابع ... اذا اكبر من 0 اعمل كيت و كيت ...

في السطر السادس ... وإلا ... اعمل كيت وكيت ...

والله جميلة ... جميلة جدا ...

لو ادخلنا -3 .. مالذي سيحصل .. في السطر الرابع سوف يقول "هل اكبر من الصفر ؟" اذا نعم اعرض انه موجب ..

طيب – 3 ليس اكبر من الصفر ... أين يذهب ؟؟ الى أي سطر ؟

الى السطر else .... أي السطر السادس مباشرة ... ويطبق ما فيها ....

اذا ادخلنا 5 ... يأتي في السطر الرابع ... ويرى هل اكبر من الصفر ؟ نعم اكبر من الصفر .. اذن اعرض +

ثم اذا شاهد else ..... يقفز وينط الى السطر الثامن end if ...




الان مثالنا السابق الذي ينص على :





لو كان اكبر من عشرة ... قل اكبر من عشرة ...

وإلا ..... اذا كان اكبر من خمسة ... قل اكبر من خمسة وليس اكبر من عشرة ...

وإلا اذا كان اكبر من ثلاثة قل اكبر من ثلاثة وليس اكبر من خمسة وعشرة ...





انظر اليه الان كيف ستكون سهولته :








declare

v number :=&V;

begin

if v>10 then

dbms_output.put_line('it is > 10 ');

elsif v>5 then

dbms_output.put_line('it is not >10 but is >5 ');

elsif v>3 then

dbms_output.put_line('it is not >10 and not >5 but is >3');

end if ;

end;

/




Elsif ...... هي السر ..

يعني اذا لم يكن كذلك وكان ....

في السطر السادس ... elsif v>5 then


يعني لو ما كان اكبر من 10 .... وكان اكبر من خمسة ... فـ ـ ـ ـ ـ

وفي السطر الثامن elsif v>3 then


يقول لو ما كان اكبر من 10 ولا كان اكبر من 5 .... وكان اكبر من الثلاثة ... فـــــ .....

السطر العاشر ... تقفيلة الكل ......

The Coder
07-03-2006, 02:43 AM
ارجوا ان تستنتج الفكرة ... وارجوا ان تفهمها جيدا ...

هي بالممارسة ستعرف ... لكن اعرف انك لن تتدرب وتمارس .. لذا .... افهمها الان

لان مبدأها في جميع لغات البرمجة ... سوف تلاحظ ذلك .





نفس فكرة المثال .. لكن لمتغيرين ولجملتين شرطيتين مختلفتين ... انظر :








declare

v number :=&V;

v2 number:=&V2;

begin

if v>10 then

dbms_output.put_line('V is > 10 ');

elsif v>5 then

dbms_output.put_line('V is not >10 but is >5 ');

end if ;

if v2>10 then

dbms_output.put_line('V2 is > 10 ');

elsif v2>5 then

dbms_output.put_line('V2 is not >10 but is >5 ');

end if ;

end ;

/




في السطر الخامس . بدأ بجملة شرطية ...

في السطر السابع ... elsif خاصة بالجملة الشرطية التي في السطر الخامس ...

في السطر التاسع ... end if ... وهي تقفيلة السطر الخامس ... تقفيلة الجملة الشرطية التي في السطر الخامس ..

في السطر العاشر .. بدأ بجملة شرطية ثانية ...

في السطر الثاني عشر .. elsif ... خاصة بالجملة الشرطية التي في السطر كم ؟ في السطر العاشر ..

في السطر الرابع عشر ... نهاية الجملة الشرطية التي في السطر العاشر ...

انظر الى المخرجات .... انا ادخلت 10 و 20 :





Enter value for v: 10



Enter value for v2: 20



V is not >10 but is >5

V2 is > 10







ارسمها على ورق ... تصرف ... حاول فهمها .. اخترع امثلة مشابهة ...

هذه ليست صعبة ... الصعوبة حينما نرى الجمل الشرطية المتداخلة !! Nested Loop ...


معقدة بعض الشيء ... وتحتاج الى تركيز ....

الان .... اليك برنامج ... اخر .. سوف يحل مشكلة جملة الاستعلام .. وهي عدم ارجاع أي سجل ..

قبل كل شيء .. انظر المثال هذا .... وفيه ان تدخل رقم موظف والبرنامج يرى هل هو موجود في الجدول او لا ..








declare

v_ename emp.ename%type;

v_empno emp.empno%type :=&v_empno;

begin

select ename into v_ename from emp

where empno=v_empno;

dbms_output.put_line(v_ename||' is the employee who his empno is :'||v_empno);

end;

/




انظر الى البرنامج السابق ....

في السطر الثالث .. عرفنا متغير ... وعلينا ان ندخل قيمة فيه ..

فأول ما ننفذ البرنامج , سوف يخبرنا الأوراكل ... ماهي القيمة التي تود ان تضعها في المتغير v_empno ؟؟

في السطر الخامس والسادس ... نستعلم عن اسم الموظف الذي رقمه = v_empno وكما قلت ... هو الرقم الذي ادخلناه سابقا ....

في السطر السابع ... اعرض اسم الموظف الذي رقمه يساوي الرقم المدخل ..

اعرف ان شرحي سريع وغير مفهوم هذه المرة , ولكن .. اتوقع انك قرأت البرامج السابقة ففيها الشرح الكافي لها ان شاء الله ...


طبعا اذا لم تفهم .. اقرأ الدرس من البداية .. وحاول ان تعمل برنامج يعرض لنا اسم الموظف الذي رقمه يساوي الرقم الذي ندخله ....

الان اليك المخرجات ... انا وضعت الرقم 7654 ... وهو رقم الأخ مارتن ....





Enter value for v_empno: 7654

old 3: v_empno emp.empno%type :=&v_empno;

new 3: v_empno emp.empno%type :=7654;



MARTIN is the employee who his empno is :7654




لا عليك من السطور الاولى ... انظر الى السطر الاخير من المدخل ... يقول ان مارتن هو صاحب الرقم 7654

طيب ... نجرب ننفذ البرنامج مرة ثانية ... اقصد بتنفيذ البرنامج أي .. كتابته ومن ثم ضغط Enter ..... وسوف يتنفذ اوتوماتيكيا ... يعني انسخ البرنامج السابق .. والصقه فر الـ SQL PLUS... فسوف يتنفذ معك ....

الان انظر .. هل يوجد موظف رقمه 0 ؟؟ طبعا لا .... يعني ان جملة الاستعلام ترجع لنا كم سجل ؟؟؟ صفر سجل ..

يعني ما ترجع لنا سجلات .. وهو خطأ وقت التنفيذ .. وصراحة مشكلة عويصة .. وهي احد المشكلتين التي قد تواجهنا في جمل الاستعلام في لغة الـ PLSQL


انظر اليها :





Enter value for v_empno: 10

old 3: v_empno emp.empno%type :=&v_empno;

new 3: v_empno emp.empno%type :=10;

declare

*

ERROR at line 1:

ORA-01403: no data found

ORA-06512: at line 5




انا الان سوف اشرح الخطأ الذي ظهر ....

ارجوا ان تتعودوا قرائة الاخطاء !! اقسم اننا نجلس وقت طويل لا نعرف ما هو الخطأ ... وحينما نقرأ الخطأ نكتشف انه خطأ غبي وابله ... وتافه ... فأقرأوا جزيتم الف خير ...

اقرأ السطر الاول ... قال ادخل قيمة ... قلت له 10 .... في السطرين الثاني والثالث فقط ليخبرك انه استبدل العلامة &v_empno بالعدد 10 .....

في السطر الرابع والخامس والسادس يقول انه فيه خطأ ...

السطر السابع يقول انه "لا يوجد بيانات"

في السطر الثامن يقول "ان هذا الخطأ يكمن في السطر الخامس من البرنامج"

الان ...

مالحل ؟ مالعمل ؟؟؟

لماذا هذا خطأ .؟؟ اليس غباء ؟؟ تخيل برنامج كبير ... وصار فيه هالخطأ ... يعني خلاص ؟ يتوقف البرنامج بالمرة ؟

صراحة فيه سبب لهذه الاخطاء ... فيما بعد ستعرفه ... وستعرف طريقة البرمجة الجميلة , والتي تسهل علينا فهم البرامج وان نكفش ونمسك بالخطأ متلبسا وبسرعة ...

انا اخترعت حل بسيط جدا .... وهو باستخدام جملة الشرط if ......


انظر اليه :








declare

v_ename emp.ename%type;

v_count number ;

v_empno emp.empno%type :=&v_empno;

begin

select count(*) into v_count from emp

where empno=v_empno;

if v_count = 0 then

dbms_output.put_line('no one his empno='||v_empno);

else

select ename into v_ename from emp

where empno=v_empno;

dbms_output.put_line(v_ename||' is the employee who his empno is :'||v_empno);

end if ;

end;

/




اليك التحدي .... التحدي الثاني على ما اعتقد ..

اشرح لي مالذي حدث بالفعل ؟ وما هي فكرتي في هذا البرنامج ؟؟

صراحة لو ما عرفت تشرحه ... فهي مصيبة !! ...

اذا لم تعرف .. حاول .... اذا لم تعرف ان تحاول ... جرب ...

اذا لم تعرف ان تجرب .... حاول ان تجرب ...

اذا ما تبغي اصلا تحاول وتجرب .. فلا تتعلم ...

اليك المخرجات ....





Enter value for v_empno: 10

old 4: v_empno emp.empno%type :=&v_empno;

new 4: v_empno emp.empno%type :=10;

no one his empno=10



PL/SQL procedure successfully completed.




فعلا .... لقد حللنا المشكلة ....





Enter value for v_empno: 7654

old 4: v_empno emp.empno%type :=&v_empno;

new 4: v_empno emp.empno%type :=7654;

MARTIN is the employee who his empno is :7654



PL/SQL procedure successfully completed.

The Coder
08-03-2006, 01:41 AM
الان اليك مثال يوضح هل الرقم المدخل زوجي او فردي !!

اولا .... كيف نعرف اذا كان العدد زوجي او فردي ؟؟

هاه ؟ لا تعرف ؟ طيب ...

مثلا 8 .. زوجي صح ؟؟ كيف عرفت ؟؟

يظهر ان بعضكم .. لا يعرف ما معنى زوجي وما معنى فردي ...

رياضيا العدد الزوجي هو العدد الذي يقبل القسمة على اثنين ....

والفردي هو الذي لا يقبل القسمة على اثنين ...

ما معنى يقبل او ما يقبل ؟

يعني مثلا العشرة هو زوجي ... لو قسمناه على اثنين ... هل يبقى شيء ؟؟

لا ...


بعضهم لا يعرف ... اعرف ذلك .... ولا عيب .. تعرفون ان بعضهم لا يستخدم ما يتعلمه .. لذا فهو لا يعرف .





يعني 8/2 = 4 هل يوجد كسور ؟ لا ... اذن لا يوجد باقي ..

طيب ....

11/2=5.5 ..... يعني ايش في باقي ومافي باقي ؟ يعني اذا فيه كسور .. يعني فيه باقي .. واذا مافيه كسور .. يعني مافيه باقي ... الـ 11 فيه باقي .. لان فيه كسور ... الباقي كم ؟ واحد ....كيف واحد ؟

في العدد 11 ... ماهو العدد الاصغر منه الذي يقسم على العدد 2 ولا يطلع باقي ؟ طبعا العشرة ..

10/2=5 .... طبعا اخذنا من الـ 11 كم ؟ 10 ..... ويبقى كم ؟؟؟ 1

لو مش فاهم ... روح تعلم هالقوانين ... وارجع لهذا المثال ... عادي ... انا انتظرك ...





اذن .. اذا الباقي من القسمة على اثنين يساوي صفر .... فهو عدد زوجي .. و إلا ... فهو عدد فردي !!

انظر الى البرنامج :








declare

v number :=&V;

begin

if mod(v,2)=0 then

dbms_output.put_line('even');

else

dbms_output.put_line('odd');

end if ;

end;

/




هنا استخدام رائع لدالة mod ... وهي دالة تاخذ مدخلين الاول هو القاسم .. والثاني هو المقسوم عليه ..

وترجع لنا ايش ؟؟؟ تخرج لنا ايش ؟؟ نتوقع منها ان تعطينا ايش ؟؟

سوف تعطينا باقي القسمة ! .....





في السطر الرابع ... اذا كان المتغير v(الذي ادخلنا فيه رقم) باقي قسمته على الاثنين يساوي صفر ... فهذا يعني انه موجب .... أي نفذ السطر الخامس (اطبع على الشاشة انه موجب even) ...


في السطر السادس .. وإلا ....نفذ السطر السابع ( أطبعه سالب odd ) ...



انظر الى الفردي ..





Enter value for v: 5

old 2: v number :=&V;

new 2: v number :=5;

odd




انظر ... الى الزوجي ...





Enter value for v: 6

old 2: v number :=&V;

new 2: v number :=6;

even




يتهيألي .... ان البرامج جميلة ... ومسلية .. وكالألغاز ..


طبعا كلامي هذا نتج عن حب للبرمجة ... ليش حبيتها ؟ لأني أحس انني ابرع فيها ...

فاذا كنت تكرهها من قلبك .. فاعرف ان السبب هو لانك لم تبرع فيها بعد ...

لو عرفت لها ... سوف لن تبحها ... بل ستعشقها ..

وكما قيل "الانسان عدو ما يجهله" .... يعني يكره الي يجهله .... يعني اذا يجهل ولا يعرف البرمجة .. سوف يكرهها طبعا ...

بعضكم سوف يذهب ويخترع برامج من رأسه ... ومسائل .. والغاز .. ويحاول ان يبرمجها .. اعرف ذلك ..

ولكن البعض الاخر ... هيـــه .... ولا همه شيء ...

ويبقى الاهتمام سيد الموقف .

برنامج ... يوضح الزوجي الموجب .. والزوجي السالب ...

والفردي الموجب والفردي السالب ..





declare

v number :=&V;

begin

if v>0 and mod(v,2)=0 then

dbms_output.put_line('even positive');

elsif v>0 and mod(v,2)<>0 then

dbms_output.put_line('odd positive');

elsif v<0 and mod(v,2)=0 then

dbms_output.put_line('even negative');

elsif v<0 and mod(v,2)<>0 then

dbms_output.put_line('odd negative');

end if ;

end;

/




برنامج جميل ....

انظر الى السطر الرابع ... لو المتغير اكبر من الصفر .... و ..... باقي القسمة على اثنين يساوي صفر

فهو ايش يعني ؟ اكبر من الصفر يعني موجب .. ويقبل القسمة على اثنين ايش يعني ؟ يعني زوجي ..

اذن زوجي موجب .....





نفس الفكرة في السطور الثانية ...





هيا ... اليك تحدي .. وتحدي من نوع محترم !!

برنامج ذكي ... صدقني سهل وذكي جدا لكنه صعب في نفس الوقت ... فكر فيه ...

انا اريد ان اعطيك اياه ليس لتعجيزك ... انما ... لكي تفكر فيه حتى الدرس القادم ان شاء الله ....

خذ السؤال ....

كيف نحكم على عدد انه يقسم على العدد ثلاثة ؟

يعني باقي القسمة على ثلاثة يساوي صفر ...؟

يعني .. انه لو قسم على ثلاثة .. يكون الناتج عدد صحيح بدون كسور .... ؟

مثلا ...

27 نقسمه على 3 يصبح الناتج 9 ... اذن عدد صحيح بلا كسور .... اذن 27 يقبل القسمة على ثلاثة ...

هذا ليس السؤال ....

خذ هذه القاعدة ..

بعض الاعداد كبيرة ... مثل 999 ... هل يقبل القسمة على ثلاثة ؟

توجد طريقة جميلة ... بالنظر تعرف ... وهي 9 + 9 + 9 = 27 ... و 27 تقبل القسمة على ثلاثة ..

طيب .. 1233 هل يقبل القسمة على ثلاثة ؟ .... 1 + 2 + 3 + 3 = 9 ... والـ 9 يقبل القسمة على ثلاثة .. اذن ...


1233 يقبل القسمة على ثلاثة ....

هذا ليس سؤالي ..

سؤالي هو ...


اريد برنامج .. ندخل له عدد ..

اذا كان العدد ثلاث ارقام ... فسوف يقبله .. واذا لم يكون ثلاث ارقام .. فلن يقبله ويطبع الرسالة


(not 3 digit number)


مامعنى ثلاث ارقام ؟ يعني ثلاث خانات ... أي انه عدد ذو ثلاث خانات مثل 567 (3 digit = ثلاث خانات او اعداد)

الان ... قلنا البرنامج لا يقبل الا عدد من ثلاث خانات ....

اذا لم يكن العدد ثلاث خانات .. يطبع الرسالة not 3 digit number ويخرج من البرنامج

اذا كان العدد من ثلاث خانات هنا يطبع البرنامج مايلي :

العدد الاول العدد الثاني العدد الثالث

العدد الاول + العدد الثاني + العدد الثالث

مجموع الاعداد الثلاثة ...

يعني لو ادخلنا 123

فانه يطبع الاتي :





Enter value for v: 123

1 2 3

1 + 2 + 3

6




ولو ادخلنا 999 فسوف يطبع الاتي :





Enter value for v: 999

9 9 9

9 + 9 + 9

27




برنامج من العيار الثقيل ....



انتهى درس اليوم ... لذا ... سوف نعقد الامور اكثر واكثر .... في المرات القادمة ....
لذا ..... فطبق كثيرا .. وسوف لن تفهم الدروس القادمة طالما انك لم تطبق ..
سلااااام

ميعاد عوده
11-03-2006, 10:01 AM
يا اخ حمزه بارك الله فيك انا يا دوب لسه مسجل بالمنتدي وحبيت اشجعك بكلمتين جزاك الله خير

The Coder
11-03-2006, 08:29 PM
يا اخ حمزه بارك الله فيك انا يا دوب لسه مسجل بالمنتدي وحبيت اشجعك بكلمتين جزاك الله خير


حياك الله في منتدانا
وحياك الله بيننا ....
شكرا لك .. وجزيتي الف الف خير ....
تسلمي .... ^^

The Coder
26-05-2006, 04:02 AM
السلام عليكم ^^
اهلا وسهلا مرة ثانية ..


رجعنا رجعة ان شاء الله نقدر نختم فيها هذه الدورة ..
احب اعتذر عما حصل من تأخير للدورة ....
المفترض ان انتهي منها في شهر او شهرين ...
لكن ظروفي والله ما تسمح ...


المهم اننا احياء نرزق وحتى هذه اللحظة ...
ان شاء الله نبدأ ..
بس صار مشكلة في المنتدى ... وراحت اعتقد بعض الدروس ..
ياريت لو في احد يقدر يرجع لنا الدروس الضائعة ...
من المحفوظات الموجودة في المستعرض ..
لو فيه احد يساعدنا في استرداد الصور الضائعة ياريت يكلمني ...

ان شاء الله نبدأ بطريقة كما عهدتمونا .... وصراحة حاسس اني مش مستقر .. لكن احاول انهي الدورة ..




سي يا ...

The Coder
28-05-2006, 02:34 AM
بسم الله الرحمن الرحيم

الدرس السادس عشر


اسم الدرس

:لغة PLSQL



نوع الدرس

: تطبيقي



صعوبة الدرس

: ** من *****



الوقت المتوقع منك لفهم الدرس

: خمس ساعات .



المتوقع منك في هذا الدرس

:

- فكرة عن الجمل الشرطية



-

فكرة عن حلقات التكرار






هيا لنؤركل ^^







السلام عليكم ....






هنا حل لتحديات الدرس الخامس عشر ...





حل التحدي الاول ...



declare

v_ename emp.ename%type;

v_dname dept.dname%type;

v_deptno emp.deptno%type;

begin

select ename into v_ename from emp

where empno =7654 ;

select deptno into v_deptno from emp

where empno=7654;

select dname into v_dname from dept

where deptno = v_deptno ;

dbms_output.put_line('the name is :'||v_ename||' and his dept name is:'||v_dname);

end;

/








خزنا اسم الموظف صاحب الرقم 7654 ...

خزنا رقم القسم لصاحب الرقم 7654 ...

استخدمنا رقم القسم الذي خزناه لايجاد اسم القسم الخاص بالموظف رقم 7654 ....

انظر الى المنطق في هذا البرنامج .... حاول فهمه وتتبعه وعمل مثله ...

اعتقد انه سهل جدا , و اعتقد ان بعضكم فكر فيه .... ولا اعتقد ان احدكم حله ^^ ....





حل اخر لهذا التحدي ....







declare

v_ename emp.ename%type;

v_dname dept.dname%type;

begin

select ename into v_ename from emp

where empno =7654 ;

select dname into v_dname from dept

where deptno=(select deptno from emp where empno =7654);

dbms_output.put_line('the name is :'||v_ename||' and his dept name is:'||v_dname);

end;

/










رائع هذا الحل ... وسهل ... استخدمنا فيه الاستعلامات الفرعية ....





اليك حل ثالث !!!!!

وهو أروعهم وأسهلهم نظريا .....





declare

v_ename emp.ename%type;

v_dname dept.dname%type;

begin

select d.dname , e.ename

into v_dname , v_ename

from emp e , dept d

where e.deptno=d.deptno

and e.empno=7654;

dbms_output.put_line('the name is :'||v_ename||' and his dept name is:'||v_dname);

end;

/







فكرته فقط ربط الجدولين !!

يعني ....

اما ان تحضر كل معلومة من استعلام ما .. كما شاهدنا في الحل الاول ..

او ان تحضر ما أمكن إحضاره باستخدام جمل الاستعلام الفرعية ... كما شاهدنا في الحل الثاني ..

او ان تحضر ما أمكن إحضاره باستخدام جملة الاستعلام وربط الجداول مع بعضها ...

وكل طريقة احلى من الثانية ......

فكر فيهم ... حاول تفهمهم ... اخترع اسألة ... اذا لم تستطع ... فلا مشكلة ان شاء الله ....





التحدي الثاني ....








كل مافي الامر ... اننا عملنا استعلام عن

count(*) .... هذه دالة رائعة .. ترجع لنا الصفوف ...

يعني لو ما بيرجع لنا ولا صف .... فسوف تكتب هذه الدالة صفر .... أي صفر صف ....

واقصد يرجع لنا صفوف ... أي حينما ننفذ جملة استعلام ... نتوقع بنتيجة ترجع لنا ...

الان لو كان الـ count(*) .... يساوي صفر .. وش معناه ؟ معناه مافيه أي صف ..

تجنبنا الخطأ ... بطريقة جميلة .... انا اراها جميلة ... لكن هي طريقتي انا ... وارى انه الافضل ان نتبع طرقهم هم .. الاوراكليون لأن لهم اغراضهم في حل مشاكلهم ...











التحدي الثالث :

declare

v number :=&V;

t1 number ;

t2 number ;

t3 number ;

begin

if v>999 or v<100 then

dbms_output.put_line('the number is not 3 digit !!');

else

t1 :=mod(v,10);

v:=trunc(v/10);

t2 :=mod(v,10);

v:=trunc(v/10);

t3:=v;

dbms_output.put_line(t3||' '||t2||' '||t1);

dbms_output.put_line(t3||'+'||t2||'+'||t1);

dbms_output.put_line(t3+t2+t1);

end if ;

end;

/



برنامج من العيار الثقيل ...

السطر الثالث والرابع والخامس .... متغيرات رقمية للتخزين ...

سؤالي كان .. ان يدخل المستخدم رقم ذو ثلاث خانات .. أي ذو ثلاث ارقام .... أي على سبيل المثال 123 ..... ثلاث خانات ... و 123456 ست خانات ... وهكذا ...

طيب ... لكي نضمن ان هذا الرقم ثلاث خانات ... ما هو الشرط الذي نضعه لكي نضمن ذلك .؟؟

أي انه اذا كان الرقم اكبر من او يساوي 100 او اصغر من او يساوي 999 فهذا رقم مكون من ثلاث خانات !!! ...

فكرة حلوة ... 100 هو اصغر عدد مكون من ثلاث ارقام ... والـ 999 هو اكبر عدد ممكن .... مكون من ثلاث ارقام .

لو كان هذا الرقم يحقق هذا الشرط ! ..... فهو رقم ثلاث خانات !!

لاحظ .... اكبر من او يساوي 100 ....... و.......... اصغر من او يساوي 999 ....

ولاحظ ايضا انه بإمكاننا ان نقول :

اكبر من 99 .... واصغر من 1000 ...... للاعداد الصحيحة .... هل فهمت ؟ كلها واحدة ...

طيب ...

في السطر السابع قلت : اذا كان اكبر من 999 ... او ..... اصغر من 100 ... فهذا ليس عدد مكون من ثلاث خانات

الله الله على المنطق ... كم هو معقد ... وكم هو سهل .... وكم هو صعب ...

انتبه لهذه النقطة ... انتبه كثيرا ... فكر لو عدد اكبر من 999 .. هل ثلاث خانات ؟ لا ..

(أو)فكر لو عدد اخر اصغر من 100 ... هل ثلاث خانات ؟ طبعا لا !!

طيب طيب ... في السطر السابع اذا لم يكن ذو ثلاث خانات ... اطبع على الشاشة "ليس ثلاث خانات"




في السطر التاسع يقول

else .. لو لم يكن ثلاث خانات .. هل سيدخل وينفذ الأوامر التي في جزئية else ؟؟؟

فكر ...

طبعا لا ... سوف يقفز الى أين ؟؟؟ الى end if .....



في السطر التاسع .. اذا كان ثلاث خانات ..... فاعمل السطور من 10 الى 17 ....

السطر العاشر غريب !! والحادي عشر والثاني عشر ايضا ... الى الخامس عشر ..

قبل ان اشرحها ... اريدك ان تعرف السؤال اصلا ..

يقول "اذا كان ثلاث خانات ... اجمع كل خانة مع الاخرى !! واعطيني الناتج"

يعني ... لو ادخلنا 156 ... سوف يعمل مايلي : 1 + 5 + 6 .... والناتج يساوي 12

كيف نعملها بالله عليك ؟؟كيف نفرق كل خانة ؟؟؟ نحتاج لخدعة !! .....

.



خدعة مشهورة وهي بدالة باقي القسمة !!


t1 := mod(v,10);



في هذا السطر ... قلت الرقم الاول خزن فيه ماذا ؟

خزن فيه مايلي :

باقي قسمة

v على عشرة .....

مثال :



t1 := mod(123,10);

t1 :=3



الان ... المتغير

t1 ..... به أي خانة ؟؟؟ انظر .... انها خانة الاحاد ...

هل لاحظت ذلك ؟؟؟

قسمنا على عشرة ... لاخذ خانة الاحاد !!

الان اريد خانة العشرات ... كيف ؟؟ كيف الوصول ؟؟؟



v:=trunc(v/10);



لماذا هذه الخطوة ؟؟؟ نعطيك المثال نفسه .


v:=trunc(123/10)

v:=trunc(12.3)

v:=12



الان العدد الذي ادخلناه .... صار 12 بدلا ان كان 123

!! ....



طيب طيب .. ما رأيك نعيد من جديد بطريقة رياضية .. وعلى اساس اننا ادخلنا 123 ...


if 123>999 or 123<100 then

dbms_output.put_line('the number is not 3 digit !!');



طبعا لن تعرض الرسالة ... لانه رقم ذو ثلاث خانات ....






عارض الشرط وخالفه .. اذن .... سوف يتم تنفيذ مايلي :


Else



t1 := mod(123,10);

t1 := 3



v:=trunc(123/10);

v:=trunc(12.3)

v:=12



طبعا بعد ان كانت

v بها العدد 123 ... صارت الان 12 ..



يعني كأننا تخلصنا من ماذا ؟ من خانة الاحاد ... واين خزناها ؟؟ خزناها مسبقا في المتغير

t1 صح ؟

الان خانة العشرات .. والتي هي 2 ... موجودة الان في خانة الاحاد في المتغير v ... اكرر .. بعد ان تخلصنا من الـ3

صارت الان ... خانة الاحاد ..... صح ؟



t2 := mod(12,10) ;

t2 :=2 ;





v:=trunc(12/10);


v:=trunc(1.2)

v:=1;



الان .... المتغير

v به الرقم 1 .. والذي كان ... يا مكان .... في خانة المئات معزز مكرم ... تخلصنا من 2 والان الرقم 1 هو في خانة الاحاد ....





t3:=v;





المتغير

t1 به الان الرقم الذي كان .... في خانة المئات .. والمتغير t2 به الرقم الذي كان في خانة العشرات ..

واخيرا t3 يخزن العدد الذي كان في متغير الاحاد ...

وضاع العدد الذي بداخل v الفعلي ..

الان نستطيع التلاعب بالارقام .. انظر ماذا سوف ينتج جراء الامر التالي





dbms_output.put_line(t3||' '||t2||' '||t1);



المخرجات ستكون :



1 2 3





dbms_output.put_line(t3||'+'||t2||'+'||t1);



مخرجاته ستكون :



1+2+3



dbms_output.put_line(t3+t2+t1);



مخرجاته ستكون



6





صدقني انه صعب في البداية ... وفي النهاية اسهل بكثير ..

واذا شاهدته سهل الان ... فهذا جيد ...

برنامج مسلي ... ومفيد كثيرا

جرب وادخل قيم ليست ثلاث خانات .. وجرب ادخل قيم اخرى بثلاث خانات

The Coder
28-05-2006, 02:53 AM
درسنا اليوم ..... لا بأس به ....سهل وبسيط


الان ... لنعقد الامور .. ولنداخل الجمل الشرطية ... وكما تذكر التداخل في الوحدات

Nested Block الذي اريتك صورة توضيحية لهذا التداخل ....




الجمل الشرطية لها نفس المفهوم ... ونفس التداخل ....








-





الجمل الشرطية المتداخلة Nested If Condition:







انظر البرنامج التالي :







declare
v number :=&v;
v2 number:=&v2;
begin
if v>0 then
dbms_output.put_line('v is positive');
elsif v<0 then
dbms_output.put_line('v is negative');
end if ;
if v2>0 then
dbms_output.put_line('v2 is positive');
elsif v2<0 then
dbms_output.put_line('v2 is negative ');
end if ;
end ;
/






طبعا لو نفذناه يطلب منا البرنامج ادخال قيمة في المتغير


v وقيمة في المتغير v2









سوف يكتشف اذا كان





v موجبا او سالب ... وسوف يكتشف v2 هل موجب او سالب هو الاخر .. وسيطبع ذلك ..




انظر الى المخرجات ....












Enter value for v: 1


old 2: v number :=&v;


new 2: v number :=1;


Enter value for v2: 2


old 3: v2 number:=&v2;


new 3: v2 number:=2;


v is positive


v2 is positive











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








declare


v number :=&v;


v2 number:=&v2;


begin


if v>0 then


dbms_output.put_line('v is positive');


if v2>0 then


dbms_output.put_line('v2 is positive');


elsif v2<0 then


dbms_output.put_line('v2 is negative ');


end if ;


elsif v<0 then


dbms_output.put_line('v is negative');


if v2>0 then


dbms_output.put_line('v2 is positive');


elsif v2<0 then


dbms_output.put_line('v2 is negative ');


end if ;


end if ;


end;


/







مشربك جدا ,,, ومربك جدا ,,,









انظر الى الصورة 1600 :


http://img8.picsplace.to/img8/15/1600_001.jpg


هناك جمل شرطية داخلية

if inner ويوجد في مثالنا هذا جملتين شرطيتين داخليتين







وايضا جملة واحدة شرطية خارجية


if outer







ارجو ان تفرق بينها وبين الصورة 1601

http://img8.picsplace.to/img8/15/1601.jpg



اذ ان هذه الصورة لايوجد بها تداخل .



ركز جيدا في الصورتين , ركز في ترتيبهما وفرق بينهما .






حلقات التكرار :






اريد ان اكرر أي امر او عملية عدد من المرات ....




اريد مثلا ان اطبع الاعداد من واحد الى مئة ماذا اعمل ؟


اريد ان اعرض اسم موظف الف مرة ...


اريد ان اكرر شيء ما ... حتى حدوث شيء ما اخر ...


ماذا اعمل ؟


لنقل انني اريد ان اطبع كلمة



hello world خمس مرات .... اليك البرنامج :




















SQL> begin


2 dbms_output.put_line('hello world');


3 dbms_output.put_line('hello world');


4 dbms_output.put_line('hello world');


5 dbms_output.put_line('hello world');


6 dbms_output.put_line('hello world');


7 end;


8 /


hello world


hello world


hello world


hello world


hello world





لنقل ايضا انني اريد ان اطبع الاعداد من 1 الى 100 كل عدد في سطر ...



اليك برنامج يطبع من 1 الى 10 :














begin

dbms_output.put_line('1');



dbms_output.put_line('2');


dbms_output.put_line('3');


dbms_output.put_line('4');


dbms_output.put_line('5');


dbms_output.put_line('6');


dbms_output.put_line('7');


dbms_output.put_line('8');


dbms_output.put_line('9');


dbms_output.put_line('10');


end;


/












اتعبني بالرغم من انه من 1 الى 10 ....




اريد برنامج يطبع الاعداد التي من واحد الى عشرة الزوجية منها


يعني لو العدد زوجي ... اطبعه والا فلا تطبع ... اليك البرنامج :













begin

if mod(1,2)=0 then


dbms_output.put_line('1 is even');


end if ;


if mod(2,2)=0 then


dbms_output.put_line('2 is even');


end if ;


if mod(3,2)=0 then


dbms_output.put_line('3 is even');


end if ;


if mod(4,2)=0 then


dbms_output.put_line('4 is even');


end if ;


if mod(5,2)=0 then


dbms_output.put_line('5 is even');


end if ;


if mod(6,2)=0 then


dbms_output.put_line('6 is even');


end if ;


if mod(7,2)=0 then


dbms_output.put_line('7 is even');


end if ;


if mod(8,2)=0 then


dbms_output.put_line('8 is even');


end if ;


if mod(9,2)=0 then


dbms_output.put_line('9 is even');


end if ;


if mod(10,2)=0 then


dbms_output.put_line('10 is even');


end if ;


end;


/




المخرجات





2 is even




4 is even


6 is even


8 is even


10 is even

The Coder
28-05-2006, 03:13 AM
البرنامج ضخم ... ونحن نحتاج لتكرار عملية ما ..

اريد منك ملاحظة انه يوجد شرط ... في تكرارنا هذا ... متى يتوقف التكرار ..؟؟

يتوقف التكرار اذا وصلنا العدد عشرة !!

اذن عملية ما ... تتكرر ولا تتوقف الا بشرط ما ..




اكرر كلامي ....... تتكرر وتتوقف بوجود شرط ما !!

رأينا البرنامج السابق كيف كان ضخم وتكرار فيه من ناحية الكتابة ... هذا وهو من 1 الى 10 ..

فما بالك لو قلت لك ... من 1 الى 1000 ؟؟ خلينا واقعيين ... نحتاج لاداة تكرار ... تتوقف عند شرط معين !!

يوجد هناك ما يسمى بجمل التكرار !

جمل معينة لها بداية ولها نهاية .... ومن الممكن ان تستمر الى اللانهائية ...

يوجد العديد من الأنواع هذه ,, واذكر بعض منها

جمل التكرار البسيطة

Simple loop



جمل التكرار العددية

Numeric for loop



جمل التكرار طالما

While loop



جمل التكرار الخاصة بالمؤشرات

Cursor for loop



الأخيرة سوف نأخذها فيما بعد ....





جمل التكرار البسيطة

Simple loop



سأعطيك مثال تكرار

hello world .... خمس مرات :

declare

i number :=1;

begin

loop

dbms_output.put_line('hello world');

i:=i+1;

if i>5 then

exit;

end if ;

end loop;

end;

/









يظهر انه اصعب من ذلك البرنامج ,,,

انظر اليه ...

السطر الثاني عرفنا

i وقيمتها الاولية هي 1

السطر الرابع كلمة غريبة ... وهي loop يعني تكرار ... او حلقة تكرار .... او يعني ابدأ التكرار من هنا ...

السطر الخامس يطبع الجملة ..

السطر السادس المتغير i يزداد بواحد .... يعني كان هو 1 , والان سيصبح اثنين ...

السطر السابع اذا كان المتغير اكبر من 5 ,,,,

السطر الثامن .. exit ... أي اخرج .... اخرج من ماذا ؟ من البرنامج ؟؟ لا .... من حلقة التكرار !!

السطر التاسع نهاية الشرط الموجود في السطر السابع

السطر العاشر نهاية التكرار !!

الان ... في السطر العاشر هل يعني ان البرنامج اذا وصل هذا السطر ينتهي التكرار ؟ لا ... يقصد هنا تقفيلة التكرار !!

لم تفهم ؟ طيب ...

اليك شرح موجز ...

اولا سوف يكرر البرنامج من السطر الرابع الى السطر العاشر ... كم مرة ؟؟ مرات عديدة تصل الى اللانهائية ...

يعني لن يتوقف ابدا من التكرار .. طالما انه لا يوجد شيء او امر يردعه !!

هذه نقطة مهمة ...

في برنامجنا السابق ... يكرر كما قلت السطور من الرابع الى العاشر ...

في السطر السادس سوف يزيد في كل مرة المتغير بواحد .. يعني المرة الاولى كان 1 ... يزداد بواحد ويصير 2

في المرة الثانية يكون 2 ... يزداد بواحد فيصير 3 ... وهكذا ...

السطر السابع ... يقول اذا كان المتغير اكبر من 5 ... ماذا يفعل ؟ يفعل السطر الثامن .. أي اخرج من التكرار !!

هل تعرف ما هي المخرجات ؟ انظر :



hello world

hello world

hello world

hello world

hello world





لماذا طبعها خمس مرات ؟

أي انه كرر الجمل تلك خمس مرات !!

انا اخبرك .. في التكرار الاول ..يطبع الجملة ويزيد المتغير بواحد (كان 1 ويصبح الان 2)

هل المتغير اكبر من 5 ؟؟؟ لا ....







في التكرار الثاني يطبع الجملة و يصير المتغير 3

هل المتغير اكبر من 5 ؟؟؟ لا ....

في التكرار الثالث يطبع الجملة و يصير المتغير 4

هل المتغير اكبر من 5 ؟؟؟ لا ....

في التكرار الرابع يطبع الجملة و يصير المتغير 5

هل المتغير اكبر من 5 ؟؟؟ لا ....

في التكرار الخامس يطبع الجملة و يصير المتغير 6

هل المتغير اكبر من 5 ؟؟؟ نعم !!

هنا ينفذ السطر الثامن .. لانه تحقق الشرط ... ينفذ امر

exit ... أي اخرج !!

اخرج من جملة التكرار !!

سوف يخرج ويقفز الى أي سطر ؟ الى السطر الحادي عشر (بعد السطر العاشر الذي به الامر end loop)





وبهذا ينتهي البرنامج !!

ارجو ان يكون ذلك واضح ... اعرف ان الشرح الكتابي ليس كافيا في بعض الاحيان , ولكن طبق والعب في النتائج وانظر ... سوف اساعدك ...





رأينا كم كان البرنامج معقد !! واطول من البرنامج الذي يطبع الجملة خمس مرات يدويا ..

طيب .... البرنامج المعقد ... بإمكاننا ان نجعله يكرر اكثر بتغيير بسييييييط جدا ....

ما رأيك ان نجعله يكرر 20 مرة ؟



declare

i number :=1;

begin

loop

dbms_output.put_line('hello world');

i:=i+1;

if i>20 then

exit;

end if ;

end loop;

end;

/





هل شاهدت التغيير ؟ ... مجرد عدلنا في الشرط !!
بدلا ان يكون اكبر من 5 .... يكون اكبر من 20 !!




hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world










تغيير بسيط جدا في البرنامج

... وتغيير كبير في الناتج !!



مارأيك بخمسين ؟

declare

i number :=1;

begin

loop

dbms_output.put_line('hello world');

i:=i+1;

if i>50 then

exit;

end if ;

end loop;

end;

/





رائع جميل ... انظر الى الناتج :



hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

hello world

The Coder
28-05-2006, 03:19 AM
اريد ان اعرض الاعداد بين 1 الى 10 :

declare

i number :=1;

begin

loop

dbms_output.put_line(i);

i:=i+1;

if i>10 then

exit;

end if ;

end loop;

end;

/



1

2

3

4

5

6

7

8

9

10



لنعقد الامور ...
اريد ان اعرض الاعداد الزوجية من واحد الى عشرة !!

declare

i number :=1;

begin

loop

if mod(i,2)=0 then

dbms_output.put_line(i||' is even');

end if;

i:=i+1;

if i>10 then

exit;

end if ;

end loop;

end;

/




لاحظ السطر الخامس !!

وضعنا المتغير

i في داخل الدالة ... سوف تتغير قيمة هذا المتغير في كل مرة في التكرار !

فمرة تجده 1 ,,, ومرة 2 ومرة 3 .... حتى 10

اذا كان باقي قسمة قيمة المتغير على اثنين تساوي صفرا يعني انه زوجي !!

انظر مخرجاته :

2 is even

4 is even

6 is even

8 is even

10 is even



الان انظر الى الاعداد الزوجية من 0 الى 50 !!

declare

i number :=0;

begin

loop

if mod(i,2)=0 then

dbms_output.put_line(i||' is even');

end if;

i:=i+1;

if i>50 then

exit;

end if ;

end loop;

end;

/



نفس البرنامج لا تغير ولا تبدل ... الا تغيير بسيط جدا في السطر التاسع , غيرنا الشرط يكون المتغير اكبر من 50 !

يوجد جملة جديدة قليلا ... وهي
exit when



ما فائدتها ...؟؟ ليست تلك الفائدة العظيمة ولكن ... مجرد استخدام اخر لـ

exit ...



انظر الى البرنامج التالي نفس البرنامج السابق ولكن باستخدام هذه الجملة :


declare

i number :=0;

begin

loop

if mod(i,2)=0 then

dbms_output.put_line(i||' is even');

end if;

i:=i+1;

exit when i>50;

end loop;

end;

/

يظهر انها كالشرط !!

هي جاهزة وتسهل قليلا علينا ولكن محدودة وغير مرنة , فلا افضل استخدامها الا اذا اردنا فقط الخروج عند نهاية التكرار .. اما اذا اردنا ان نعمل أي شيء اخر قبل الخروج فاستخدم الجملة الشرطية
if ....





مارأيك ان نطبع الاعداد الزوجية من صفر الى عدد يدخله المستخدم ؟

التحدي الاول !!

اعمل برنامج يطبع الاعداد الزوجية .. من صفر الى أي عدد يدخله المستخدم !!

يعني سوف يقول لي .. ادخل قيمة .. وادخل انا مثلا 22 ... فسوف يوجد لي كل الاعداد الزوجية التي بين 0 و 22

ولو ادخلت 66 فسوف يوجد لي كل الاعداد الزوجية التي بين 0 و 66 وهكذا !!

لا اعتقد انها صعبة ..


اليك تحدي ثاني ... من العيار الثقيل ... صعب لدرجة عالية جدا , ولا اعتقد ان احدكم سوف يحله بسهولة !!

الاعداد الاولية ,,, prima numbers



هل تعرف ماهي الاعداد الاولية ؟

هي الاعداد التي لا تقبل الا القسمة على نفسها وعلى واحد فقط !!

اعني يقبل القسمة عدد على عدد اخر أي ان باقي القسمة العدد على العدد الاخر يساوي صفر ....

تحدثت فيها كثيرا يا رجل ... لا ترفع ضغطي ...

الان التحدي الثاني يقول .. اريد برنامج يطبع الاعداد الاولية .. التي بين الواحد وعدد يدخله المستخدم ...

يعني لو ادخل المستخدم 20 فسوف يوجد البرنامج الاعداد الاولية بين الواحد والعشرين !!

للتسهيل عليك ...

الاعداد الاولية 1 و 2 و 3 و 5 ......

..



هذه التي لا تقبل القسمة الا على نفسها وعلى واحد !!

الان اريدك ان تلاحظ ان جملة التكرار البسيطة هذه ... لو نزعنا

exit منها فسوف لن نستطيع الخروج من البرنامج الى اللانهائية ....

انظر الى البرنامج :






النوع الثاني ...





جمل التكرار العددية

Numeric for loop



صراحة هذه اسهل قليلا .... وهو يصلح للتكرار الذي نعرف متى ينتهي ..

طيب ... اليك طباعة الجملة

hello world بهذه الطريقة ..

اريد طباعتها خمس مرات ... ثم عشر مرات في المثالين التاليين :



begin

for i in 1 .. 5 loop

dbms_output.put_line('hello world');

end loop ;

end;

/






السطر الثاني ...

for i in 1 .. 5 loop



يعني عرف المتغير

i وجعل اول قيمه له تساوي 1 , ثم سوف يكرر الى ان يصل المتغير القيمة الاكبر من 5 ...

مرة يجعل المتغير يساوي واحد .... وينفذ ثم يجعل المتغير يساوي اثنين وينفذ .......وهكذا



hello world

hello world

hello world

hello world

hello world



سهلة كما قلت .... وتعمل بشكل اوتوماتيكي في زيادة المتغير ....





لنعمل برنامج الاعداد الزوجية :

begin

for i in 1 .. 20 loop

if mod(i,2)=0 then

dbms_output.put_line(i||' is even');

end if ;

end loop ;

end;

/



النتيجة والمخرجات :

2 is even

4 is even

6 is even

8 is even

10 is even

12 is even

14 is even

16 is even

18 is even

20 is even


مازلنا في تطبيقات بسيطة وسهلة الان ....

توقع برامج اكثر شراسة فيما بعد !!

فلا تنسى قوة واهمية التكرار في البرمجة !!

The Coder
28-05-2006, 03:25 AM
جمل التكرار طالما
While loop






شكل ثالث من جمل التكرار ..

while تعني طالما ..

الان برنامج الاعداد الزوجية التي بين الصفر والعشرة ...


declare

v number :=0;

begin

while v<=10 loop

if mod(v,2)=0 then

dbms_output.put_line(v||' is even');

end if ;

v:=v+1;

end loop;

end;

/



في السطر الرابع .. قلنا
while v<=10 loop



يعني طالما ان المتغير

v قيمته اصغر من 10 .. فكرر !!

يعني بعكس ما تعودنا ... كنا نقول اذا قيمة المتغير اكبر من عشرة .... توقف .

الان نقول .... اذا قيمة المتغير اصغر من او تساوي عشرة كرر !!

نفس الفكرة , عكس المفهوم

السابقة .. تقول اذا ..... توقف ...

وهذه تقول اذا ..... كرر !!

فرق بينها ....






طبعا في السطر الثامن زدنا في كل مرة المتغير بواحد ...





الان ....

لماذا هذا التنوع واللخبطة في حلقات التكرار ؟ هل يريدون تعقيدنا من البرمجة والاوراكل ؟

صراحة انا ارى انه لكل واحدة لها غرض ...

طيب لنبدأ بحلقتي التكرار البسيطة والعددية !! ... ايهما افضل واحسن واسهل ؟

طبعا حلقات التكرار البسيطة وحلقات التكرار العددية متشابهة جدا ...

ولكن العددية اوتوماتيكية وبتريح ولكن .. محدودة القوى ..

اما البسيطة تتعب ولكن قواها اوسع واكثر مرونة .... كيف ؟ انا اخبرك ...

طبعا لما نشاهد من اول نظرة الامور , نتسرع ونحكم

انا من اول نظرة لي ان العددية افضل بكثيييييييييير

ولكن .. ارى ان جمل التكرارية البسيطة افضل من العددية

...



سوف اعمل برنامج بحلقة التكرار البسيطة لا تستطيع عمله حلقة التكرار العددية !

قبل كل شيء اريد عمل برنامج يطبع لي الاعداد الزوجية بين الصفر والعشرة .. ولكن من الكبير الى الصغير !!

يعني من عشرة الى الصفر !!

declare

v number :=10;

begin

loop

if mod(v,2)=0 then

dbms_output.put_line(v||' is even');

end if ;

v:=v-1;

if v <0 then

exit ;

end if ;

end loop;

end;

/



10 is even

8 is even

6 is even

4 is even

2 is even

0 is even


انظر الى جمالها !!

السطر الثامن لم نقل "زد المتغير بواحد" !!

بل قلنا "اطرح من المتغير واحد" !!

سوف يكون 10 في البداية كما لاحظنا في السطر الثاني !!

ويتناقص في كل تكرار بواحد .... يعني يصير تسعة ثم ثمانية ...... في السطر التاسع يقول اذا كان المتغير اصغر من الصفر !! اخرج من حلقة التكرار !!

لاحظ وتأمل في هذا الشرط ... لو قلنا "اذا كان المتغير اكبر من الصفر " مالذي يحصل ؟ سوف يخرج من اول تكرار بالطبع !! لان المتغير في السطر الثامن ينقص بواحد ويصبح قيمته تسعة , ثم يختبره الشرط الذي في السطر تسعة ..

يجده اكبر من الصفر طبعا !!

لكي توسع المفهوم ... انظر البرنامج التالي ... وهو نفس السابق ولكن من 10 الى 5 !!

declare

v number :=10;

begin

loop

if mod(v,2)=0 then

dbms_output.put_line(v||' is even');

end if ;

v:=v-1;

if v <5 then

exit ;

end if ;

end loop;

end;

/



10 is even

8 is even

6 is even



غيرنا فقط الشرط وقلنا
if v<5 then بدلا من الصفر ..

اعتقد انها نقطة مفهومة واضحة سهلة تافهة ....






الان نرجع لموضوعنا !! وهو مالفرق بين حلقة التكرار العددية والبسيطة ؟؟

كما قلنا .. اولا التكرار التنازلي .. وكما شاهدنا .. ننقص المتغير وليس نزوده !!

حلقة التكرار البسيطة استطاعت ذلك ...

هل تستطيع حلقة التكرار العددية ؟؟ لنرى ذلك :


begin

for i in 20 .. 1 loop

if mod(i,2)=0 then

dbms_output.put_line(i||' is even');

end if ;

end loop ;

end;

/



في الحقيقة لا يوجد خطأ ولكن ... سوف يرى قيمة المتغير
i الاولية ... ويجدها 20 .. ثم يقول "هل 20 اكبر من 1؟"

طبعا يقول نعم !! اذن اخرج من الدوارة ...

لن يطبق شيء وستكون المخرجات لاشيء !!

اذن هذه الحلقة غبية وليست قادرة على استيعاب الامر !!

فهي اذن للزيادة فقط !!

يوجد طريقة لحل هذه المشكلة ...


begin

for i in reverse 1 .. 20 loop

if mod(i,2)=0 then

dbms_output.put_line(i||' is even');

end if ;

end loop ;

end;

/



اضفنا كلمة
reverse وهي تعني العكس , سوف تعد تنازليا من 20 الى 1 ...

جميل جدا ..






الامر الاخر لنفرق بين حلقتي التكرار البسيطة والعددية هو مقدار الزيادة والنقصان !!

يعني كما شاهدنا ... نزيد بواحد , ننقص بواحد !!

اريد برنامج يطبع لي الاعداد التي بين 3 و 30 والتي تقسم على العدد ثلاثة !! ماذا اعمل ؟

بسيطة .. اول شيء الثلاثة , ثم الستة , ثم التسعة ... وهكذا !!

كيف عرفت ؟ اضيف في كل مرة ثلاثة !!

اليك البرنامج البسيط ولكن قبل كل شيء ... ارجو ان تكتب انت البرامج قبل ان تطلع عليها !!

يعني حاول عمل البرنامج قبل ان تراه !!



declare

v number :=3;

begin

loop

dbms_output.put_line(v);

v:= v+3;

if v>30 then

exit;

end if;

end loop;

end ;

/



3

6

9

12

15

18

21

24

27

30








شاهدنا في السطر السادس
v := v+3



يعني نزيد بثلاثة .

نستطيع ان نزيد باربعة .. بخمسة .. بعشرة بألف بمليون ...

نستطيع ان ننقص بستة او سبعة او ..... الخ

حتى اننا نستطيع ان نزيد او ننقص بكسور !!

مثلا :

v:= v+0.98



نستطيع ذلك ... جرب وانظر !!





الان .. رأينا انه في حلقة التكرار البسيطة نستطيع ان نضيف غير الواحد !

وحلقة التكرار العددية لا تستطيع ذلك !!

لا اهتم لهذه الفروقات لأني لا اعلم هل توجد طريقة لحل هذه المشكلة (ولا اعتقد

) في حلقة التكرار العددية او لا !!

ولكن اريد ان اوصل لك رسالة ..

في لغات البرمجة الاخرى , توجد لغات تعمل كل شيء جاهز , هي صراحة مريحة جدا للمبرمج , ورائعة , وفي وقت قياسي تعمل برامج كبيرة .

وتوجد لغات اخرى متخلفة جدا , وكل شيء تعمله يدوي ....

ايهما افضل ؟ هل اللغات التي تعمل لك كل شيء وانت تستخدمها او اللغة التي تجبرك على عمل كل شيء ؟

طبعا ستقول اللغة التي تريحني وتعطيني كل شيء جاهز !

انت صادق , ولكن .. في الحقيقة هي سريعة في الانتاج بطيئة في التنفيذ ! يعني لو لديك برنامج كبير , عملته بهذه اللغات الجاهزة في اقل من شهر ... سترى ان اداء البرنامج الكبير سيء !! بطيء ايضا !

طبعا هذا اذا اهتمينا في اداء البرامج , بينما لو عملناه باليدوية فسوف ننهيه في اربع شهور مثلا ولكن سنجد البرنامج صاااروخ !!

وهنالك شيء اخر !! المرونة ,,

اللغات التي تعطيك اشياء جاهزة من الممكن ان تعطيك شيء ضيق الحدود , ولا تستطيع التعديل فيه ...

اما اليدوية فسوف تعمل كل شيء بنفسك وتتحكم في كل شيء !

طبعا هذا موضوع كبير جدا , ويحتاج معلومات وفيرة لكي تفهمها .... ولكن كل ما اردت قوله , لا تتذمر من الشيء اليدوي وخاصة في عالم البرمجيات .. ولا تحكم على شيء وانت لا تعلم وتتسرع في ذلك .






الان حلقة التكرار "طالما"

while loop



لماذا نستخدمها ؟ الا تكفي جملتي التكرار تلك ؟

في الحقيقة انا اراها زائدة !!

في بعض لغات البرمجة هي مهمة جدا لكن هنا .. مجرد زيادة , لأننا نستطيع عمل مثلما تعمله هذه الحلقة , باستخدام الحلقة البسيطة !! رهيبة الحلقة البسيطة , نستغني عن الكل اذا استخدمناها فركز فيها ,,,

الان لماذا نستخدم

while ؟؟

في حلقة التكرار العددية نحن نعرف كم تكرار يلزمنا , لذا نحدد المجال ونقول من كذا الى كذا ...

طيب لو ما بنعرف ؟ ماذا نستخدم ؟ هل العددية ؟ طبعا لا !!

مثلا كرر طالما انه يوجد سجلات في الجدول مثلا ,, طبعا نعرف ان انه يوجد سجلات في جدول ما , ولكن لا نعرف كم سجل !!

لو قلت لك عشر سجلات ... فحلقة التكرار العددية تقوم بذلك , ولكن اذا لم نعرف ذلك , while وجملة التكرار البسيطة تستطيع عمل ذلك ,, لا اريد اعطائك الان أي امثلة ولكن سوف تلاحظها فيما بعد ان شاء الله .






هل تذكر تداخل الوحدات , وتداخل الشروط , الان يوجد تداخل للتكرار !!

نفس المفهوم , ونفس الفكرة .....

سوف نبدأ ان شاء الله درسنا القادم ببرنامج من العيار الثقيل ....(على ما اظن)

انتهى درس اليوم , واعدكم بدروس ستشيب رأسك حتما , فترقب !!

The Coder
30-05-2006, 03:43 AM
بسم الله الرحمن الرحيم

الدرس السابع عشر
اسم الدرس
:لغة PLSQL

صعوبة الدرس
: ***** من *****

الوقت المتوقع منك لفهم الدرس
ست ساعات , تطول او تقصر ... .

المتوقع منك في هذا الدرس
- لماذا المصفوفات .
- كيفية عمل المصفوفات .
- دوال المصفوفات .
- مهارة التتبع .


السلام عليكم ....
قبل البدء في اجوبة التحديات في الدرس السابق , اريد ان اشير الى انني ان شاء الله اعمل بعض عروض الفلاش الخفيفة والبسيطة جدا في تتبع البرامج , والتي أرى انها مفيدة ان شاء الله ...
الان اليك اجوبة التحديات في الدرس السابق ...
حل التحدي الاول :



declare
v number :=&v;
s number :=0;
begin
loop
if s>v then
exit;
end if;
if mod(s,2)=0 then
dbms_output.put_line(s||' is even');
end if;
s :=s+1;
end loop;
end;
/



حل التحدي الثاني :



declare
v number :=&v;
flage number :=0;
begin
for i in 2..v loop
for j in 2..i-1 loop
if mod(i,j)=0 then flage:=1;exit;end if;end loop;
if flage =0 then
dbms_output.put_line(i||' is prima');
end if;
flage :=0;
end loop;
end;
/


ناتج البرنامج كما يلي ... يطلب رقم , انا ادخلت 13 .... وسوف يعرض الاعداد الاولية التي اقل منه :



Enter value for v: 13
old 2: v number :=&v;
new 2: v number :=13;
2 is prima
3 is prima
5 is prima
7 is prima
11 is prima
13 is prima


في حل التحدي الثاني يوجد بعض الافكار القوية ...
فكرة البرنامج هي طباعة الاعداد الاولية ... يعني يدخل المستخدم عدد ما , والبرنامج يطبع الاعداد الاولية التي اقل منه ...
الاعداد الاولية هي الاعداد التي لا تقبل القسمة الا على نفسها او على واحد !!
كيف "لا تقبل القسمة ... " ؟؟؟
يعني باقي قسمتها يساوي صفر ...
مثلا قسمة 4 على 2 .... كم الناتج بدون كسور ؟؟ الناتج 2
كم باقي القسمة ؟ باقي القسمة يساوي صفر ...
طيب قسمة 3 على 2 .... اريد الناتج بدون كسور !! ... اكرر بدون كسور .
الناتج =1 ... وباقي القسمة تساوي 1 ....
اذن باقي القسمة لا تساوي صفرا ... اذن الثلاثة لا تقبل القسمة على الاثنين ....
نعيد ونكرر .... ما معنى اعداد الاولية ؟ هي التي لا تقبل القسمة الا على نفسها او على الواحد ..
مثل الاثنين ... لا تقبل القسمة الا على نفسها او على الواحد ...
مثلا السبعة ... لا تقبل القسمة على ستة ... او على خمسة ... او على اربعة او ثلاثة او اثنين ...
السبعة لا تقبل القسمة الا على نفسها (يعني سبعة) او على الواحد ! (ركز .. على نفسها , وعلى الواحد فقط !! )
اذن السبعة عدد اولي ...
الاعداد الاولية هي كما يلي :
1 , 2 , 3 , 5 , 7 , 11 ,13 ......... الخ
هل التسعة من ضمنها ؟ لا .. لماذا ؟ لأنها تقبل القسمة على ثلاثة .... اذن ليست اولية .
يعني لو فكرنا بالمنطق كيف نعمل برنامج يطبع الاعداد الاولية ؟؟ انظر الى المنطق ... ممل ولكن مهم , تحمل خمس دقائق او اقل .... لقرائته :

- مثلا نجعل المستخدم يدخل عدد اقصى ... مثلا ادخل العشرة ...

- نبدأ نختبر العشرة هل عدد اولي ام لا ... كيف نختبره ؟ نقول 10/9 .. يقبل ؟ لا ... 10/8 يقبل ؟ لا .... 10/7 يقبل ؟ لا ....10/6 يقبل ؟ لا ... 10/5 يقبل ؟ نعم !!
هنا العشرة ليست عدد اولي

- ننقص القيمة القصوى المدخلة ... بتصير الان تسعة مثلا ...

- نبدأ نختبر التسعة .... هل عدد اولي ام لا ؟ كيف نختبره ؟ نقول 9/8 يقبل ؟ لا ... 9/7 يقبل ؟ لا .......الخ
يتضح ان التسعة ايضا ليست عدد اولي

- ننقص التسعة ... ثم نختبر ثم ننقص ثم نختبر ........... الخ ...

- نلاحظ انه يوجد حلقة تكرار للاختبار , يعني لو اردنا نختبر أي عدد هل اولي او لا ... نعمل حلقة تكرار ...

- نلاحظ ايضا انه يوجد حلقة تكرار ثانية لتنقيص العدد المدخل ! .... بعد ما نختبر العدد , ننقصه ونختبره........الخ

الان ... نرى البرنامج مرة ثانية بارقام الاسطر :



SQL> declare
2 v number :=&v;
3 flage number :=0;
4 begin
5 for i in 2..v loop
6 for j in 2..i-1 loop
7 if mod(i,j)=0 then flage:=1;exit;end if;end loop;
8 if flage =0 then
9 dbms_output.put_line(i||' is prima');
10 end if;
11 flage :=0;
12 end loop;
13 end;
14 /

السطر الثاني :
نعرف المتغيرالذي يحتوي على اعلى قيمة نريدها , وطبعا قيمته تساوي كم ؟ هي القيمة التي يدخلها المستخدم ..اعتقد اننا تكلمنا في هذا الموضوع .

السطر الثالث :
متغير flage وقيمته الابتدائية بصفر , وهو العلم ...لماذا هذا المتغير (العلم)؟ سترى ...

السطر الخامس :
بداية حلقة تكرار تنتهي فين ؟ في السطر الثاني عشر .... قرب نهاية البرنامج
هذه الحلقة تكرر من 2 الى العدد الاقصى الي يدخله المستخدم , يعني تختبر من العدد 2 هل اولي او لا ... ثم تنتقل اوتوماتيكيا الى العدد الذي يليه وتختبره , ثم تنتقل للعدد الذي يلي يليه وتختبره .... وهكذا ...
طبعا اقصد بـكلمة "تختبره" يعني تشوف هل هو اولي او لا , وذلك بالتأكد انها لا تقسم الا على نفسها او على الواحد .

السطر السادس :
بداية حلقة الاختبار والتي تنتهي في السطر السابع .... تبدأ بالقيمة 2 وتنتهي بالقيمة الحالية للإختبار ..
ركز جيدا ... فهم البرامج (وخاصة ذوات حلقات التكرار ) تأتي بما يسمى بعملية التتبع tracing
هذه من افضل واسوأ المهارات ... وهي الاكثر امتاع والاكثر ملل ...
وصراحة الاكثر تعب في البرمجة , من ناحيتي اكرهها واقدر قوتها واهميتها .
نعود لبرنامجنا ونقول من اين اتى المتغير i ؟؟ من حلقة التكرار السابقة ... والتي تبدأ من اثنين وتنتهي عند العدد v الذي ادخله المستخدم .
يبدأ مثلا بالاثنين ... الان الـ i تساوي اثنين .... في السطر السادس الان .. نبدأ من الاثنين وننتهي الى الاثنين .
بعد ان تنتهي هذه الحلقة ,اين يذهب مؤشر البرنامج ؟ اين سوف يقرأ البرنامج ؟؟سوف يرجع الى حلقة التكرار التي في السطر الخامس وسوف تزيد هذه الحلقة قيمة الـ i بواحد وتصبح في المرة الثانية ثلاثة .
ونعيد الكرة بقيمة ثلاثة , في السطر السادس حلقة تكرار تختبر من الاثنين الى الثلاثة ....... الخ

اذا لم تفهم لا تخف , سوف احاول بطريقة اخرى .

السطر السابع :
اذا باقي القسمة للمتغير i على المتغير j يساوي صفر فهذا يعني انه ليس أولي .
ماهو المتغير j ؟ وكيف اتت هذه المعادلة ؟
Mod(i,j) تعني باقي قسمة i على j
والمتغير j هو القيمة الحالية لحلقة التكرار الثانية (السطر السادس)
الان لو باقي قسمتهما يساوي صفر , فسوف تصبح قيمة العلم بواحد وسيخرج من حلقة التكرار الداخلية (التي تبدأ في السطر السادس).
الان سوف تدور هذه الحلقة الداخلية , وتدور وتدور وتختبر باقي القسمة للعدد على الاعداد الاقل منه ,
يعني اذا كانت الـ i تساوي 10 فسوف تختبر هذه الحلقة الداخلية مايلي :
باقي 10/9 = 0 ؟ لا
باقي 10/8 = 0 ؟ لا
باقي 10/7 = 0 ؟ لا
....
باقي 10/5 = 0 ؟ نعم .. اذن العلم (العلم هو المتغير flage)يساوي واحد (ومعناه انه ليس أولي)و اخرج من حلقة التكرار .

السطر الثامن:
هل العلم يساوي صفر (هل العدد اولي)؟ اذن اطبع انه اولي (السطر التاسع) وطبعا العشرة ليست بعدد أولي
السطر الحادي عشر :
ارجع قيمة العلم لصفر من جديد لنختبر عدد جديد .

يرجع البرنامج ويقرأ السطر الخامس ....أي حلقة التكرار الخارجية سيزود قيمة العشرة وتصبح احدى عشر.
في الحلقة الداخلية سوف يحدث مايلي :
باقي 11/10=0 ؟ لا
باقي 11/9 =0 ؟ لا
.....
11/2=0؟ لا
وطبعا العلم يساوي 0 الان ... أي انه لم تتغير قيمته ....
سوف يرى هل العلم يساوي صفر ؟ طبعا نعم ... إذن أطبع "الاحدى عشر عدد أولي"

وهكذا سوف يتم التكرار ...
وحتى ينتهي عند الحد الاقصى .
الفكرة هي في العلم , يكون صفر ... لو وجده يقبل القسمة على أي عدد .. اصبح العلم واحد , يعني ليس اولي ..
وبعد الانتقال للعدد التالي , سوف يرجع العلم صفر ويبدأ الاختبار من جديد ....


إذا لم تفهم , فحاول أن تفهم هذا المثال عبر ملف الفلاش (رقم 17000) الذي سأرفقه

الآن أريد أن أقول أن الرقم واحد اعتقد انه (في اغلب ظني ) عدد أولي . وبرنامجي هذا لا يعرضه ..
فلو حبيت , حاول ان تعدل البرنامج لكي يعرض الواحد .

انتهينا من حل التحديات في الدرس السابق , لذا نبدأ بدرس اليوم .

The Coder
30-05-2006, 03:49 AM
المصفوفات :
ماهي المصفوفة يا ترى ؟ مجموعة متغيرات مرتبة .... فقط .... لماذا ؟ هنا القصة تطول قليلا ..
المصفوفة عبارة عن متغيرات , مجرد متغيرات .
لكن هذه المتغيرات مرقمة , وكأنها مفهرسة , وكأن بها عنوان . اليك مثال بسيطة

A(0) :=10;
A(1) :=5;
A(2) :=6;
كما شاهدنا , تحمل هذه المصفوفة نفس الاسم ! ولكنها مرقمة , يعني المتغير A والذي رقمه 0 به القيمة 10

انتبه جيدا , بامكاني ابدأ درس اليوم مباشرة , ولكن لا اريد منك معرفة كيف ... بل اريد منك معرفة لماذا !
يعني كيف نعمل مصفوفة .... هذه سهلة , اعطيك سطرين واحفظهم وطبق , ولكن لماذا ؟ هنا المصيبة !

لماذا المصفوفة ؟
لو مثلا قلت لك , اريد البرنامج ندخل به ارقام ويعرضها , ثم يعرضها ثانية وهي مضاعفة , ولكن يجب ان يكون ذو مواصفات كما يلي :
- ان نطبع الاعداد المدخلة جميعها ....ثم نطبع الاعداد المدخلة مرة ثانية ولكن مضاعفة (العدد*2)
- مع العلم انه في بداية البرنامج يطلب من المستخدم عدد الاعداد التي يدخلها فيه .. يعني اذا ادخل ثلاثة فيجب ان يكون هنالك ثلاث متغيرات , و يدخل في كل متغير عدد , ولو ادخل اربعة في البرنامج .. فيجب ان يكون هنالك اربع متغيرات .... وهكذا .

- ان يطبع الاعداد المدخلة مرتبة تصاعديا ..على ان يكون البرنامج بسيط للقراءة , ولا يكون طويل جدا ...

طبعا البرنامج غريب , وكأن به صعوبة ... لماذا طلبت منك هذه المواصفات بالذات ؟ لماذا ؟ لأني اردت ذلك .
بالله عليك ناقشني في هذه المواصفات ... فكر , حاول ان تحل ولو مواصفة واحدة من هذه المواصفات ...
بعد ان تفكر , نناقش الموضوع ... نكتب هذه المواصفات واحدة تلو الاخرى .

- ان يطبع البرنامج الاعداد وبعد ان ينتهي من طباعتها يطبعها ثانية .. هذه الصفة بسيطة .. وحلها ان نعرف متغيرات , ونضع الاعداد التي ندخلها في المتغيرات , لماذا ؟ لاننا طبعنا , ثم استخدمنا نفس القيم مرة ثانية .. ومن الممكن ان نستخدمها مرة ثالثة ورابعة ..... اعتقد انها واضحة . وهذا يعتمد على فهمك لماذا اخترعو المتغيرات .

- ان يطلب البرنامج من المستخدم ادخال عدد الاعداد , يعني لو قلنا انه ادخل ثلاثة , فيسمح البرنامج بان ندخل ثلاث قيم لثلاث متغيرات .. الم نقل انه يجب عمل متغيرات ؟
طبعا يجب ان نخزن القيم في متغيرات , مثلا عملنا البرنامج , لو ادخل المستخدم اثنين , كم يلزمنا متغير ؟ طبعا متغيرين , لو ادخل ثلاثة , فيجب ان نعرف ثلاثة .... وهكذا . كيف نفعل ذلك ؟ كيف نجعل البرنامج ذكي ويعرف اوتوماتيكيا عدد المتغيرات ؟ هل يعقل ان نعرف a,b,c,d,e,f مثلا , و ادخل المستخدم عدد اكبر من المتغيرات التي عرفناها ؟ اذن المشكلة هي اننا في بعض الاحيان لا نعرف كم نحتاج متغير ! يعني يجب ان يكون هنالك تمدد في الكود بشكل اوتوماتيكي ! وهو شبه مستحيل بالنسبة لنا في هذه المرحلة !
اعرف ان كلامي فيه غموض .. لأنك في اغلب الامر لا تعرف ماهي المصفوفة ...

- ان يطبع البرنامج الاعداد مرتبة .. سواء تصاعديا او تنازليا على ان يكون البرنامج بسيط ولا يكون طويل ولا يتمدد ....

هذه صعبة جدا , لماذا ؟ انا اخبرك ... ادخلنا ثلاث متغيرات , a , b , c .....
ادخلنا ثلاث قيم .. كيف نعرف الاكبر منها او الاصغر ؟
سوف ترى هل a اكبر من b و c ؟؟ اذا اكبر فيطبعها , ثم يرى الاكبر في الـ c و الـ b
لو لم تكن الـ a اكبر , فسوف يرى هل الـ b اكبر قيمة , ثم يطبعها ويطبع الذي يليها ..... الخ
اذا اردت ان تتطلع على الكود , فلن يسرك .. اقدر انه اكثر من ثلاثين سطر , وعملية مكررة ومتعبة وغبية ..
هذه وهي ثلاث قيم , فما بالك بعشرين ؟؟ انها معقدة جدا جدا , ولا استغرب لو كلفنا الكود اكثر من مليارات الاسطر .. او اكثر !!
طبعا انت لن تحس بالمشكلة حتى ترى الكود التالي ... ولا تحبط منه , فهو برنامج غبي جدا والمصفوفة حلت مشكلته في تمدد الكود :




declare
a number ;
b number ;
c number ;
begin
a:=&a;
b:=&b;
c:=&c;
if a > b and a > c then
dbms_output.put_line('the first:'||a);
if b > c then
dbms_output.put_line('the second:'||b);
dbms_output.put_line('the third :'||c);
else
dbms_output.put_line('the second:'||c);
dbms_output.put_line('the third:'||b);
end if ;
else if b > a and b > c then
dbms_output.put_line('the first:'||b);
if a>c then
dbms_output.put_line('the second:'||a);
dbms_output.put_line('the third :'||c);
else
dbms_output.put_line('the second:'||c);
dbms_output.put_line('the third:'||a);
end if ;
else
dbms_output.put_line('the first:'||c);
if a>b then
dbms_output.put_line('the second:'||a);
dbms_output.put_line('the third :'||b);
else
dbms_output.put_line('the second:'||b);
dbms_output.put_line('the third :'||a);
end if ;
end if ;
end if ;
end ;
/

Enter value for a: 2
old 6: a:=&a;
new 6: a:=2;
Enter value for b: 3
old 7: b:=&b;
new 7: b:=3;
Enter value for c: 1
old 8: c:=&c;
new 8: c:=1;
the first:3
the second:2
the third :1


ارجو رجاء خاص جدا ان تتمعن في البرنامج , اعرف انه طويل ولكنه غبي وساذج , لكن اريدك ان تعمل مثله لو استطعت .
وكما تشاهد الكود قابل للتمدد بشكل مخيف .
لو كان لدينا رقمين فالكود صغير جدا .. يوجد احتمالين .. اما ان الاول اكبر او الثاني اكبر ..
لو كان لدينا ثلاث ارقام .. فالكود يتمدد كما شاهدنا .. ويوجد ست احتمالات .... (1*2*3)
ولو كان لدينا عشر ارقام , فيوجد لدينا 3628800 احتمال !! (1*2*3*4*5*6*7*8*9*10)

الان ... انتهت هذه المناقشة التي اعتقد انك لم تنتفع منها .
بعد هذا الدرس , اذا كنت راغب في تضخيم عقلك ومنطقك , فأعد قراءة السطور السابقة (ولكن بعد الدرس )
الان...
ماهي المصفوفة وكيف نعملها :
قلنا من قبل ان المصفوفة عبارة عن متغيرات , مجرد متغيرات .
لكن هذه المتغيرات مرقمة , وكأنها مفهرسة , وكأن بها عنوان .
رأيت مثال لم تفهمه في اغلب الامر .
سوف اعطيك برنامج سهل , وهو يخزن ثلاث ارقام في مصفوفة , ويقوم بطباعتها :




declare
type t1 is table of number index by binary_integer ;
A t1;
begin
A(0):=0;
A(1):=5;
A(2):=8;
dbms_output.put_line(A(0)||' '||A(1)||' '||A(2));
end;
/

المخرجات
0 5 8


في السطر الثاني , سطر طويل وغريب , في السطر الثالث كذلك ...
لتعريف مصفوفة .. أولا نعرف نوع المصفوفة , كيف ؟ نقول "لا نريد يا أوراكل نوع رقمي , أو حرفي أو تاريخي ... نريد نوع جديد يدعى بمصفوفة أعداد.. لا اريد مصفوفة حروف , ولا مصفوفة تاريخ .. بل مصفوفة اعداد !! "
في السطر الثالث كما شاهدنا type أي عرف نوع جديد ... اسم هذا النوع بـ t1 .... الان t1 صار نوع جديد مثل الـ number و الـ date ..... وباقي الانواع . فهمت ؟
الان ما مواصفات هذا النوع ؟ is table of number يعني مصفوفة عددية , يخزن به اعداد يعني .
طبعا ستكون مجموعة متغيرات متشابهة في الشكل , وكل متغير فيها نوعه ماذا ؟ طبعا رقم ! انتبه جيدا .
لو اردنا نصوص ؟ هكذا is table of varchar2(15) يعني مصفوفة نصية , لكل متغير فيها يحمل بداخله 15 حرف ! ... فهمت ؟
يقول في السطر الثاني :
Index by binary_integer تعني انها مرقمة ومفهرسة باعداد ... سوف تعرف هذه النقطة بعد قليل .

السطر الثالث :
الان لدينا نوع اسمه t1 , هذا النوع مثله مثل التاريخ , والاعداد ....
هذا النوع يعتبر عدد , ولكن مجموعة متغيرات (مصفوفة) عددية .. وليست واحدة فقط , يعني بالامكان تكون متغير واحد او اثنين او عشرة او عشرين ...... الخ , فكما ترى ان مشكلة "عدم معرفة عدد المتغيرات" قد انتهت وماتت كما ستشاهد بعد قليل .
لدينا نوع , ولكن لا يوجد متغير لهذا النوع .... في السطر الثالث عرفنا متغير يدعى بـ A , و نوعه "مصفوفة عددية" !! فهمت ؟

السطر الخامس والسادس والسابع :
كما نشاهد .. ان المتغير A هو مصفوفة , هو صحيح متغير واحد ولكن به عدد غير معلوم من المتغيرات العددية ! الان استخدمنا هذا المتغير المرقم , وكما قلنا انه مفهرس باعداد (index by binary_integer ) لو قلنا انه مفهرس بحروف او نصوص (index by varchar(3)) فسوف يكون شكل هذه السطور هكذا :
A(abc):=1;
A(gfd):=2;
A(ef):=3;
وطبعا لكل استعمالاته , واكثر الاستعمالات مع المرقمة طبعا .
الان تخيل معي المصفوفة الحالية A : (صورة 1701)


http://img8.picsplace.to/img8/15/1701.jpg


هذه المصفوفة A , والتي لا نعرف كم متغير بداخلها , لكن الذي نعرفه انه يوجد بداخلها حتى الان ثلاث متغيرات بها قيم . وهو الذي يهمنا !
الجدير بالذكر ان المصفوفات في لغات البرمجة الأخرى تبدأ فهرستها بالصفر , لكن في هذه اللغة المصفوفة تبدأ فهرستها من أي رقم سالب .
كما نشاهد في الصورة , ان بعض العناوين ليست بها قيم فهي خالية ..
فلو استخدمناها فسيعطي الاوراكل خطأ .اليك ما سيحدث لو استخدمنا هذه المناطق الخالية .





declare
type t1 is table of number index by binary_integer;
A t1;
begin
A(0):=0;
A(1):=5;
A(2):=8;
dbms_output.put_line(A(0)||' '||A(1)||' '||A(3));
end;
/

نفس البرنامج ولكن في سطر الطباعة استخدمنا المتغير A والذي عنوانه رقم ثلاثة .
نحن وضعنا قيم في العناوين 0 و 1 و 2 ... ولكن لم نضع في الرقم ثلاثة ... اليك الخطأ .



ERROR at line 1:
ORA-01403: no data found
ORA-06512: at line 8

يقول انه لا يوجد بيانات ... صادق يا اوراكل .

The Coder
30-05-2006, 03:55 AM
دعنا نعقد قليلا الامور .... انظر الى مصفوفتين عدديتين مختلفتين :




SQL> declare
2 type t1 is table of number index by binary_integer ;
3 A t1;
4 B t1;
5 begin
6 A(0):=2;
7 A(1):=5;
8 B(-4):=33;
9 B(20):=41;
10 dbms_output.put_line(A(0)||' '||A(1)||' '||B(-4)||' '||B(20));
11 end;
12 /


2 5 33 41

فقط لا جديد سوى انني اريد ايصال فكرة متغير ونوع مصفوفة .
نوع المصفوفة العددية هي t1 , بامكاننا ان نعمل عدد من المتغيرات , انا عملت متغيرين من نوع t1 , الاول يدعى بـ A والاخر يدعى بـ B .
شاهد البرنامج والنتيجة , واعتقد انه لايوجد أي صعوبة في فهمها .






الان لنرى برنامج يدخل الاعداد من 0 وحتى رقم يدخله المستخدم , سوف ترى كيف اننا لن نكون ثابتين في عدد معين من المتغيرات , يعني بكلمة اخرى ديناميكية وليست ثابتة ,, شخصيا احب الديناميكية في كل البرامج , والتي تتغير على حسب الظروف , لو عشت لأمد ابعد وصادفت برمجة الانترنت والمواقع الديناميكية سوف تقدر معنى الديناميكية في البرمجة بشكل عام .

البرنامج ناتجه هكذا :



Enter value for number: 3
old 4: v number :=&Number;
new 4: v number :=3;
1 :1
2 :2
3 :3
1*2 :2
2*2 :4
3*2 :6

ولو ادخلنا مثلا قيمة غير الثلاثة سوف يكون ناتجه ما يلي :



Enter value for number: 5
old 4: v number :=&Number;
new 4: v number :=5;
1 :1
2 :2
3 :3
4 :4
5 :5
1*2 :2
2*2 :4
3*2 :6
4*2 :8
5*2 :10

هل تعرف ان تبرمج هذا البرنامج ؟
بالمصفوفة طبعا ...
فكر قليلا ....واليك البرنامج :



declare
type t1 is table of number index by binary_integer ;
A t1;
v number :=&Number;
begin
for i in 1..v loop
A(i):=i;
end loop ;
for i in 1..v loop
dbms_output.put_line(i||' :'||A(i));
end loop ;
for i in 1..v loop
dbms_output.put_line(i||'*2 :'||A(i)*2);
end loop;
end;
/

السطر السادس الى الثامن :
حلقة تكرار من الواحد وحتى الـ v الذي ادخله المستخدم ... يدخل قيم عددية في المتغير A
طبعا على حسب ما ادخله المستخدم , سوف ندخل اعداد , وكأننا وضعنا متغيرات ديناميكية .
يعني لو ادخل ثلاثة فكأنما عرفنا ثلاثة متغيرات فقط ! ولو ادخل اكثر فسوف يتم تعريف متغيرات اكثر , وعلى حسب ما ترغب , ستشاهد هذه الديناميكية الرائعة (عدد غير معلوم من المتغيرات).

السطر التاسع الى الاحد عشر :
نريد طباعتهم .... مع ملاحظة عدد المتغيرات الان v , أي اننا لا نعرف عددهم , على حسب ما يدخله المستخدم .

السطر الثاني عشر الى السطر الرابع عشر :
حلقة تكرار ثالثة لطباعة هذه الاعداد في المصفوفة بشكل مضاعف , لاحظ الـ reuseability او ما يسموه باعادة الاستخدام , هنا تكمن قوة المتغيرات , وهنا ايضا تكمن قوة المصفوفة , جميلة هذه الخاصية (اعادة الاستخدام) فلقد احتجنا قيم المصفوفة مرة اخرى .

دوال المصفوفات :
هل تذكر كلمة "دوال"؟
لا اذكر ما قلت ولكن ... هي جزء برمجي , له وظيفة معينة ....
للمصفوفات بعض الدوال المساعدة والتي سنرى بعض منها الان .
قبل البدء سوف تجدني اقول بعض الاحيان عنصر المصفوفة , فما معنى عنصر element ؟
اقصد بذلك لو عندنا مصفوفة وبها ثلاث قيم , يعني ان بها ثلاث عناصر , والعناصر هي المتغيرات الموجودة بالمصفوفة ذات القيم .... هل فهمت ؟
وهنالك شيء اخر اعتقد انك نسيته في اغلب الظن , وهو مدخل الدالة ومخرج الدالة ...
مدخل الدالة argument هل القيم التي بين أقواس الدالة واعتقد انني تكلمت كثيرا عنها , اما مخرج الدالة هو النتيجة المرجوة من الدالة . راجع دروسي السابقة لو نسيت .
انظر الى الدوال , سوف اشرحها بشكل مبسط , وسوف اعطيك مثال كبيييييير وشامل عليها كلها , وسوف اعطيك تلخيص (صورة) شامل للكل ...

EXISTS : هذه تخبرنا اذا كان العنصر الفلاني موجود او لا .. كيف ؟
. نعطي هذه الدالة مدخل (وهو العنوان او الفهرس) وتخبرنا هل يوجد بيانات او لا .. سوف تعطينا نتيجة false اذا لا يوجد شيء , وtrue اذا وجدت .

COUNT
هذه توجد عدد العناصر بالمصفوفة ....

FIRST
هذه توجد فهرس (انتبه فهرس !) اول عنصر بالمصفوفة ...

LAST
هذه توجد فهرس اخر عنصر بالمصفوفة ...

PRIOR
اعطيها مدخل (فهرس) لعنصر ما في المصفوفة , وسوف تعطيك فهرس العنصر السابق لفهرس العنصر المدخل.

NEXT
اعطيها مدخل (فهرس) لعنصر ما في المصفوفة , وسوف تعطيك فهرس العنصر التالي لفهرس لعنصر المدخل

TRIM
هذه دالة لم تعمل معي , ولكن يقولون انها تحذف اخر عنصر من المصفوفة .. غبية هذه الدالة ولا احبها , وستعرف لماذا .

DELETE
هذه الدالة هي الافضل للحذف , اعطيها مدخل (رقم الفهرس) وستحذف القيمة التي به ..
او بامكانك ان لا تعطيها أي مدخل , فسوف تحذف كل العناصر (كل القيم الموجودة بالمصفوفة ) وتصبح كأنها مصفوفة فارغة .
الان انظر الى الصورة رقم 1702 , اعتقد انها واضحة ان شاء الله .. (صورة كبيرة نسبيا .. 200 كيلوبايت )


http://img8.picsplace.to/img8/15/1702.jpg


الان اليك مثال برنامج عن هذه الدوال , البرنامج طويل , ثلاثين سطر تقريبا , يجب عليك ان تقرأه .
بامكاني اعطائك امثلة صغيرة لكل دالة , ولكن تعمدت اعطائك مثال كبير قليلا لكي تتعود ان تشاهد البرامج الكبيرة ذات الاسطر .... :



declare
type t1 is table of number index by binary_integer ;
A t1;
begin
A(-5):=87;
A(-2):=14;
A(0):=47;
A(1):=50;
A(2):=13;
dbms_output.put_line('the elements is :'||A(-5)||','||A(-2)||','||A(0)||','||A(1)||','||A(2));
dbms_output.put_line('the number of elements now :'||A.COUNT);
dbms_output.put_line('the index of first element is :'||A.first||' ,its value:'||A(A.first));
dbms_output.put_line('the index of last element is :'||A.last||' ,its value:'||A(A.last));
dbms_output.put_line('the index of next element of A(-5) is :'||A.NEXT(-5)||' ,its value:'||A(A.NEXT(-5)));
dbms_output.put_line('the index of prior element of A(0) is :'||A.PRIOR(0)||' ,its value:'||A(A.PRIOR(0)));
dbms_output.put_line('-----------------------------------------------------');
if A.EXISTS(0) then
dbms_output.put_line('A(0) is exist befor delete');
else
dbms_output.put_line('A(0) is not exist befor delete');
end if ;
A.DELETE(0);
if A.EXISTS(0) then
dbms_output.put_line('A(0) is exist after A.DELETE(0)');
else
dbms_output.put_line('A(0) is not exist after A.DELETE(0)');
end if ;
A.DELETE;
dbms_output.put_line('the number of elements after A.DELETE is :'||A.COUNT);
end;
/


تتبع البرنامج وحاول ان تكتب وتخمن ما هي النتائج لهذا البرنامج ..
وهذا تحدي بسيط (التحدي الاول), بدون استخدام البرنامج ... اكرر بدون استخدام البرنامج اريك ان تقرأ الكود السابق وان تطبع لي النتيجة (أي تتبع البرنامج trace the code) كما قرأته مع شرح هذه النتيجة لما ظهرت هكذا ... ارجوا ان لا تطبق البرنامج قبل ان ترى نتيجتك , واي سؤال انا حاضر .

The Coder
30-05-2006, 03:58 AM
الان هنالك بعض الامور المهمة جدا جدا واريدك ان تدركها .
فستجد في السطر العاشر من الكود السابق انني عرضت كل العناصر الموجودة في المصفوفة , كما تشاهد بعض الاحيان لا نقول هكذا :
A(1):=95;
A(2):=90;
A(3):=87;
….الخ
بل سنجد بعض الاحيان انه لا يوجد ترتيب في فهارس (عناوين) العناصر , لماذا ؟ تخيل اننا نريد ان نحذف العنصر ذو الفهرس رقم اثنين :
A.DELETE(2);
الان قلي ما هي عناصر المصفوفة الان ؟ ستصبح كما يلي :
A(1):=95;
A(3):=87;
….الخ
طبعا انحذف العنصر ذو العنوان رقم 2 , هو موجود في الحقيقة , ولكن بهذه الصيغة (انتبه جيدا ):
A(1):=95;
A(2):=NULL;
A(3):=87;
….الخ
قيمة خالية , سوف يجدها قيمة خالية ويتجاهلها , ارجو ان تكون هذه النقطة واضحة .
الان بعض الاحيان لا نستطيع ان نعرف أي من العناصر موجودة في المصفوفة او لا , لذا فهذه الدوال مهمتها عمل ذلك , قبل ان تقرأ البرنامج اريد ان اقول لك ... اننا نعامل أي مصفوفة على اساس اننا لا نعرف كم عنصر بداخلها , اغلب الاحيان اننا لا نعرف كم عنصر , وهي حقيقة .
انظر الى البرنامج التالي وهو برنامج يطبع لنا جميع العناصر في مصفوفة معينة :



declare
type t1 is table of number index by binary_integer ;
A t1;
v number ;
begin
A(-5):=87;
A(1):=50;
A(2):=13;
A(-2):=14;
A(0):=47;
v:=A.first;
loop
dbms_output.put_line(A(v));
v:=A.next(v);
if v = A.last then
dbms_output.put_line(A(v)); exit; end if ;
end loop;
end;
/

اليك النتيجة :



87
14
47
50
13

النتيجة مرتبة على حسب ارقام الفهارس من الفهرس الاصغر الى الفهرس الاكبر , صح ؟
انظر , تأكد ... ستجد انه عرض A(-5) اولا ثم A(-2) ....... الخ
نبدأ بشرح البرنامج السابق ... انظر الى البرنامج السابق ولكن مرقم :



SQL> declare
2 type t1 is table of number index by binary_integer ;
3 A t1;
4 v number ;
5 begin
6 A(-5):=87;
7 A(1):=50;
8 A(2):=13;
9 A(-2):=14;
10 A(0):=47;
11 v:=A.first;
12 loop
13 dbms_output.put_line(A(v));
14 v:=A.next(v);
15 if v = A.last then
16 dbms_output.put_line(A(v)); exit; end if ;
17 end loop;
18 end;
19 /

السطر السادس الى التاسع :
عادي , وضعنا بعض القيم العشوائية في فهارس عشوائية .

السطر الحادي عشر :
طبعا يوجد لدينا هذا المتغير v الذي عرفناه في السطر الرابع , وهو رقمي ...
وضعنا في هذا المتغير القيمة A.first ... ما معنى هذه القيمة او ماذا ستعطينا هذه الدالة ؟ سوف تعطينا فهرس اول عنصر في المصفوفة , هذه الدالة عظيمة , نحن كما قلت سابقا لا نعرف في بعض الاحيان ماهي العناصر الموجودة وكم عددها وأي منها الاولى وأي منها الاخيرة , وحل هذه المعضلات هي دوال المصفوفات ..
طبعا في هذا المثال نجد ان فهرس اول عنصر هو -5 !!

السطر الثاني عشر الى السابع عشر ...
تكرار ....

في السطر الثالث عشر :
سوف يطبع A(V) , انتبه معي ,, ماهي قيمة v الان في بداية حلقة التكرار ؟
قيمتها هي "فهرس اول عنصر في المصفوفة A " صح ؟ سوف يطبع اول عنصر اذن

السطر الرابع عشر :
انتقل الى العنصر التالي ... كيف ؟ كما تشاهد دالة رهيبة هنا , تعطينا فهرس العنصر التالي لعنصر ما ... ماهو قصدي من عنصر ما ؟ هنا في المثال قلنا A.NEXT(v) يعني اعطيني فهرس العنصر التالي للفهرس v ..
و v بها الان الرقم -5 , ماهو قيمتها الان ؟ كما يلي :

v:= A.NEXT(v);
v:= A.NEXT(-5);
v:= -2 ;
وهكذا انتقل الى العنصر التالي , ولاحظ كيف رتبها اوتوماتيكيا ! اذ انه بدأ بـ -5 , ثم -2 , ثم 0 , ثم 1 ..... الخ
يعني بالاصغر الى الاكبر ..

السطر الخامس عشر والسادس عشر :
اذا كانت v هي قيمة اخر عنصر ... اطبع هذا العنصر الاخير واخرج من حلقة التكرار ..

كما ترى , البرنامج جميل , ومنطقي , وذكي , فحاول ان تفهمه بعمق شديد ثم حاول ان تتعلم كيف تتبع هذا البرنامج وغيره من البرامج جيدا , اعملها على ورق , واعمل كما عملت لك في عرض الفلاش ..


الان اليك تحدي بسيط (التحدي الثاني), اريد عرض جميع عناصر أي مصفوفة (اعمل انت مصفوفة عشوائية او نفس المصفوفة في البرنامج السابق ) . لكن اريد ان تعرض لي هذه العناصر بهذا الشكل(على سبيل المثال ) :




A(-8) : 87
A(-1) : 14
A(2) : 47
A(44): 50
A(49): 13

- - - - - - -
تحدي اخر وسهل جدا (التحدي الثالث) ,
اريد عرض العناصر لمصفوفة ما , ولكن بالمقلوب , يعني من العنصر الاخير الى الاول .

اليك برنامج نفس برنامجنا السابق ولكن يوجد تغيير بسيط في حلقة التكرار , وهو تسهيل اكثر :



declare
type t1 is table of number index by binary_integer ;
A t1;
v number ;
begin
A(-5):=87;
A(1):=50;
A(2):=13;
A(-2):=14;
A(0):=47;
v:=A.first;
while v is not null loop
dbms_output.put_line(A(v));
v:=A.next(v);
end loop;
end;
/

انظر الى البرنامج التالي هو برنامج يعرض لنا عناصر مصفوفة ولكن ليست مصفوفة عددية !
بل مصفوفة غريبة علينا , مصفوفة نصية , ومفهرسة بالنص وليس بالعدد ! :



declare
idx varchar2(20);
type word_list is table of varchar2(15) index by idx%type;
the_list word_list;
begin
the_list('ahmad'):='dentist';
the_list('abdullah'):='teacher';
the_list('saad'):='doctor';
the_list('osama'):='salesman';
idx := the_list.First();
while idx is not null loop
Dbms_Output.Put_line (idx || ' : ' || the_list(idx) );
idx := the_list.Next(idx);
end loop;
end;
/


المخرجات



abdullah : teacher
ahmad : dentist
osama : salesman
saad : doctor

البرنامج غريب جدا , في السطر الثاني عرفنا متغير نصي حده عشرين حرف ,
السطر الثالث عرفنا نوع مصفوفة تدعى بـ word_list هذه المصفوفة نصية وحدها 15 حرف لكل عنصر .
الغريب انها ليست مفهرسة بأعداد ! بل مفهرسة بنفس نوع المتغير idx ,, هل فهمت النقطة !
يعني الجملة index by idx%type تعني "يا اوراكل !! لا تفهرس المصفوفة بعدد او تاريخ ..... بل فهرس المصفوفة بنفس نوع المتغير idx "
سوف يرى الاوراكل ماهو نوع هذا المتغير , ويجده نصي حده 20 حرف !
لم تفهم ؟ لا تخف ..
السطر الرابع :
عرفنا متغير نوعه مصفوفة نصية مفهرسة نصيا .
في السطور من السطر السادس الى التاسع :
ستجد شيء غريب , وهو ما كنا نقصد ! المصفوفة فهرسها نصي ... وكما قلنا يصل هذا النص الى 20 حرف ..
يعني لو قلنا :
The_list('abc'):='???';
صحيح ..
ولو قلنا :
The_list('asdfghjklzxcvbnmqwerty'):='???';
فهذا خطأ , لأن الفهرس تعدى حده (يوجد اكثر من عشرين حرف)!
تخيل رسمتنا رقم 1701 , ولكن بهذه الفهرسة النصية , وبالعناصر النصية ... اعتقد انه لا مشكلة انظر الى الصورة 1703

http://img8.picsplace.to/img8/15/1703.jpg

The Coder
30-05-2006, 04:03 AM
وقد عرفت كيفية عمل هذه المصفوفة الغريبة , ولكن السؤال ... لماذا نفهرسها بالنص ؟
انا عن نفسي لا اعرف كل استخداماتها , ولكن في رأسي استخدام واحد لعلي اطرحه فيما بعد , وارى انه افضل ان نفهرس بالنصوص في تلك الحالة .

السطر العاشر , وضعنا فهرس اول مصفوفة (كما قلنا الفهرس نصي) في هذا المتغير النصي ...
مع ملاحظة انهما نفس النوع ونفس الحد !

السطر الحادي عشر
طالما ان المتغير ليس فارغ , كرر ...

السطر الثاني عشر اطبع فهرس العنصر الحالي + قيمة العنصر الحالي

السطر الثالث عشر :
ضع فهرس العنصر التالي للعنصر الذي فهرسه idx في المتغير idx .... ركز في ما قلت ..

الان سوف تتكرر هذه المسئلة حتى تنتهي عناصر المصفوفة , لكن هل فكرت .... أي عنصر هو الاول ؟ انظر الصورة 1703 مرة ثانية ..

ستجد اننا وضعنا قيم عشوائية وفهارس بشكل غير مرتب , وهو اوتوماتيكيا رتبها !
لو انها ارقام لكان الامر هين , ولكن هذه حروف .. كيف رتب الحروف ؟ بسيطة ...
سوف يرتبها على حسب ترتيب الحروف , مثلا لو واجهنا هذين الفهرسين ...
Abdullah , ahmad ايهما الاول ؟ كلاهما يبدأ بالحرف a , اذن .. ننظر في الحرف الثاني ..
Abdullah حرفه الثاني هو b , و ahmad حرفه الثاني هو h ... وهكذا ,,,
اذن ترتيب Abdullah هو اولا ثم ahmad ... ارجوا ان تكون الصورة واضحة وسهلة , فهذه الطريقة موجودة في قواميسنا وبعضنا لا يعرف ذلك ...

الان رأينا المصفوفات عن قرب , ولا ادري بعضكم لم يفهم فيها شيء , ولا ادري هل فهم بعضكم فكرتها , ولكن ارى ان المصفوفة حلت مشاكل جمة , ومنها :
- انها سهلت كتابة الكود بشكل رائع , واختصرته بشكل جميل ... طبعا لن تشعر بهذه النقطة حتى ترى المصفوفات الضخمة جدا !
- المصفوفة كالمتغيرات لها فائدة في اعادة الاستخدام لمجموعة قيم كبيرة , ولكن بطريقة سهلة .
- المصفوفة تجعل الكود البرمجي لا يتمدد لأننا سنضطر احيانا تعريف عدد غير معلوم من المتغيرات , وسنرى بعد قليل كيف حلت المصفوفة هذه المسألة (اقصد من المسئلة هي ترتيب البيانات!) .

هذه بعض مما ذكرنا , ولا ادري يوجد غيرها او لا .. لما لا ....

الان اليك التحدي الرابع !!
تتبع البرنامج التالي واعطيني نتيجته (مخرجاته output ) بدون تنفيذه (يعني نفذه في عقلك وتوقع النتائج)
ارجوا الاتشغله حتى تضع تخمينك ...




declare
type t1 is table of number index by binary_integer ;
A t1;
B t1;
begin
for i in 0..10 loop
A(i):=i*5;
end loop;
for i in 0 ..10 loop
B(i):=A(10-i);
end loop ;
dbms_output.put_line('B , A');
for i in 0..10 loop
dbms_output.put_line(B(i)||' , '||A(i));
end loop;
end;
/

..
وهذا التحدي الخامس... ذو الصعوبة القصوى :
اريد منك ان تعمل برنامج , تدخل هذه القيم في مصفوفة ما :


A(-12):=78;
A(-11):=1;
A(-4):=11;
A(0):=45;
A(5):=-23;
A(14):=61;
A(99):=30;
البرنامج سيرتب المصفوفة كما يلي :

A(-12) =-23
A(-11) =1
A(-4) =11
A(0) =30
A(5) =45
A(14) =61
A(99) =78
طبعا اجعل البرنامج يطبع عناصر المصفوفة بعد الترتيب .... ولاحظ اننا رتبنا "قيم" المصفوفة تصاعديا !
وايضا لو اردت ان تدخل أي قيم اخرى واي عدد من العناصر من المفترض ان البرنامج يقبل بترتيب ذلك !
هذا التحدي صعب جدا ويحتاج لتقنيات في الترتيب , حاول ان تعمل فكرة البرنامج على ورق .
لا تخف اذا لم تستطع حله , فهو فعلا صعب .

الان سوف افترض انك فهمت ولو جزء بسيط في ما يسمى بـ"المصفوفة" , كل ما قلته في هذا الدرس مجرد افكار عن المصفوفة والتي تنفعك حتى في اللغات الاخرى (باختلافات بسيطة او كبيرة) .

الان اريد بعض تطبيقات المصفوفة في لغتنا هذه , وهي التطبيقات التي افترضها حقيقية !
انظر الى هذا المثال :
اعمل الجدول التالي مع اضافة سجلات :



create table emp_1
(empno number , ename varchar(20) , sal number );

insert into emp_1 values (100 , 'any_1' , 1000);
insert into emp_1 values (101 , 'any_2', 2000);
insert into emp_1 values (102 , 'any_3',2500);
insert into emp_1 values (103 , 'any_4',2750);

انظر الى الجدول الان :




SQL> select * from emp_1;

EMPNO ENAME SAL
---------- -------------------- ----------
100 any_1 1000
101 any_2 2000
102 any_3 2500
103 any_4 2750

كما شاهدنا الجدول , نلاحظ ان الارقام متتالية (مجرد افتراض)...
الان هذا البرنامج يأخذ البيانات من الجدول ويخزنها في مصفوفة , وطبعا نعرض ما بداخل المصفوفة :




declare
type t_array is table of emp_1%rowtype index by binary_integer ;
arr t_array ;
v_count number :=103;
begin
for i in 100 .. v_count loop
select * into arr(i) from emp_1 where empno=i;
end loop;
for i in arr.first .. arr.last loop
dbms_output.put_line('the no:'||arr(i).empno);
dbms_output.put_line('the name:'||arr(i).ename);
dbms_output.put_line('the sal :'||arr(i).sal);
dbms_output.put_line('----------------------');
end loop ;
end;
/

هنالك شيء جديد في درسنا , في السطر الثاني عرفنا مصفوفة نوعها رقمي ؟ نصي ؟ لا !
بل نوعها "نفس نوع سجل الجدول emp_1" !!
يعني مصفوفة من سجلات , مجموعة سجلات , يعني كأنها تخزن جدول كامل !
هل متخيل الوضع ؟
ومفهرسة بالارقام .
السطر الرابع عرفنا متغير , مجرد متغير وبه قيمة اكبر رقم موظف في جدولنا ... مجرد مثال .
السطر السادس : تكرار على حسب عدد الصفوف (السجلات... الموظفين ....الخ) في الجدول ..
السطر السابع : جملة استعلام , وضعنا ناتجها في المتغير arr(i) .... يعني تخيل ان الـ i=100 مثلا ..
فان ناتج الاستعلام سيكون :

100 any_1 1000
طبعا سوف يخزن في العنصر arr(100) .. كيف ؟ هكذا :

Arr(100).empno:=100
Arr(100).ename='any_1'
Arr(100).sal:=1000
هل فهمت ؟ وطبعا في التكرار الثاني ...سيكون ناتج الاستعلام :

101 any_2 2000

وسيخزن النتيجة في العنصر arr(101) كما يلي :

arr (101).empno:=101;
arr (101).ename:='any_2';
arr (101).sal:=2000;
وهكذا ...
انظر الصورة 1704


http://img8.picsplace.to/img8/15/1704.jpg
انظر الى الفهرسة الرقمية , عادية جدا ,
ولكن انظر الى العنصر نفسه ! ليس عنصر واحد !! بل عنصر مركب , قيمة مركبة من ثلاث قيم ...
كما تشاهد لو اردنا قيمة ما , فإننا ننادي اسم المصفوفة و عنوانها (فهرسها ) ومن ثم نقطة ثم اسم المتغير الداخلي

السطور الخاصة بالطباعة , انظر اليها جيدا , وحاول ان تفهمها من الصورة او من البرنامج .
انظر الى المخرجات :



the no:100
the name:any_1
the sal :1000
----------------------
the no:101
the name:any_2
the sal :2000
----------------------
the no:102
the name:any_3
the sal :2500
----------------------
the no:103
the name:any_4
the sal :2750
----------------------


اعتقد ان درس اليوم اقد انتهى , على امل ان نلتقي ثانية ...

The Coder
30-05-2006, 04:30 AM
اوه سوووري ..... ملف الفلاش (عرض الفلاش 17001)


http://z08.zupload.com/download.php?file=getfile&filepath=23855
سوري انه مش عربي ..
وسوري على انجليزيتي الضعيفة
وسوري على سوء الديزاين ... بس والله ياخذو وقت .... اهم شي توصيل فكرة ما ....

اي استفسار على الفلاش .... تل مي ^^

MuhammadYassein
25-06-2006, 04:57 PM
الاستاذ المحترم - حمزه
انا فعلاً احسدك على الثواب العظيم الذي ارجو الله تعالى ان يكتبه لك..
اتمنى ان اكون مثلك سباقاً للخير...
اتمنى ان اتعلم و اتقن الاوراكيل و ان
اساعد ولو بقدر بسيط في تعليم
المسلمين..................
جزاك الله خيراً

اخوك محمد علي ياسين
www.MuhammadYassein@yahoo.com (http://www.MuhammadYassein@yahoo.com)
ww.MuhammadYassein@Hotmail.com
www.MuhammadYassein@Gmail.com (http://www.MuhammadYassein@Gmail.com)

The Coder
26-06-2006, 05:45 AM
حياك الله تسلم ,,,
انشر العلم , للفائدة ^^


واي استفسار ... يوجد موضوع استفسارات اوراكل في منتدى البرمجة هذا ^^

nas_ksa
09-02-2007, 06:32 AM
الاساتذه الكرام :
السلام عليكم ورحمة الله وبركاته

هل هناك ملف اكروبارت او ملف ورد للدوره كامله حيث لا استطيع مشاهده الصور في الشرح وكذلك طبيعة عملي لاتسمح لي بتواصل معكم بستمرار
الله يساعدتكم الدوام عندنا 28 يوم في البر و اسبوع عند اهل اريد ان استفيد من هذه الدوروانا في مقر عملي مع الشكر والتقدير الى الاستاذ معد الدورة وجميع الاعضاء
ممكن مساعدة بالحصول على ملف الدور كاملا بشكل ملف او ملفات من الورد او الاكروبارت
شاكر ومقدر لكم هذا
دمتم في حفظ الله

اخوكم / بومحمد

The Coder
10-02-2007, 01:43 PM
السلام عليكم اخي
كيفك ,,
اخي فيه مشكلة انه لا يوجد اي ملف حاليا
وانا اقوم الان في اعادة الدروس مرة اخرى وتنقيحها
ووضع صور جديدة لان القديمة طااارت


الشغلة مطولة , يعني انا والله مش فاضي
والدروس يبغالها ثلاث الى اربع اشهر اعيد كتابتها بشكل افضل
والله يعينك لازم تنتظر او .... سامحنا عاد


ان شاء الله لكل درس اطرح ملف اكروباد او وورد

موفق ,,

Ajwad
04-03-2007, 03:25 AM
مراقبنا العزيز ما زلت منتظر الدروس المنقحه
والله ثم و الله اني في امس الحاجه ليها

The Coder
04-03-2007, 07:04 AM
السلام عليكم

اجواد ... اخي ...
اسف على الاطالة لكن ..... ظروفي مازالت قاهرة
انتظر اخي شويتين .... لعلي اتغلب على الظروف ...
واسف جدا جدا على المماطلة .

kaarouch
22-03-2007, 05:13 PM
لو تضع ىملف وورد او pdf احسن اخي وبارك الله فيك

The Coder
24-03-2007, 06:18 AM
السلام عليكم
ان شاء الله اخي ابشر ....
هاليومين ابدأ بالدروس التجديدية ان شاء الله

وفي نهاية كل قسم نعمل ملف اكروباد .....

بالتوفيق

catcotah
20-04-2007, 11:52 PM
أخي الكريم الصور لم تظهر ؟؟؟؟؟؟؟
ارجوك اظهارها

catcotah
21-04-2007, 12:04 AM
اخي الكريم الصور لا تظهر

The Coder
25-04-2007, 05:21 PM
اخي الكريم , اهلا بك

انسى هذه الدروس وابدأ معنا من جديد
لحسن حظك اني واصل عند الدرس الرابع وانا الان سوف ارفع الدرس الخامس ان شاء الله
ابحث سلسلة الدروس ودعك من هذا الموضوع القديم .....
كل درس سأضعه في موضوع خاص مستقل .