khaled بتاريخ: 20 يونيو 2007 تقديم بلاغ مشاركة بتاريخ: 20 يونيو 2007 (معدل) بسم الله الرحمن الرحيم اعزائي زوار واعضاء منتدى عرب اوركل المحترمين تحية طيبة .تكملة لما قد بدأناه من قبل(دروس متقدمة في الـPL/SQL) سوف اتطرق اليوم الى شرح الـError Handling وعلى طريقتي الخاصة . وسوف افتح المجال للنقاش بإذن الله .وبألامثلة سوف نعرج على الاتي :1- ماهو الـ Exception ومتى يستخدم .2- مامعنى معالجة الاخطاء وماالفرق بين الاكواد التي تحوي جزء معالجة الأخطاء والتي لا تحيوي 3- مثالين احدهم بالForm Builder والأخر بالVB.NET للتوضيح التعامل مع اجراءات تم انشائها في قاعدة الييانات , لفهم الفائدة من معالجة الأخطاء .ملاحظة: هذا الدرس غير منقول من اي كتاب ولا منتدى فهو من اعدادي الخاص , فلا تتوقعوا ان يكون درس مثالي خالي من الأخطاء , لذلك ارحب بكل اقتراحاتكم وتعديلاتكم . 1. 1 ماهو PL/SQL EXCEPTION هل انت مبرمج هل سبق وان تعاملت مع لغة الفجول بيسك او الفجول بيسك دوت نت او الجافا او الــ PL/SQL ؟ اذا كانت الإجابة بنعم فانت تعرف الـException ومابقي عليك هو ان تعرف متى وكيف تستفيد من هذا الجزء في الكود البرمجي وان كانت الإجابة بلا فإليك التفصيل .الــ Exception :هو جزء او Block له نقطة بداية ونقطة نهاية نقطة بداية Exception 'Handel error' نقطة نهايةEnd; ويكون موجود في نهاية جزء تنفيذي لغرض معالجة الأخطى المتوقعة والغير متوقعة Begin جزء تنفيذي Execution part Exceptionمعالجة الخطاء المتوقع والغير متوقع في الجزء التنفيذي 'Handel error' End; ويتم تنفيذ الكود الموجود في جزء معالجة الأخطاء فقط عند اجبار البرنامج على الذهاب الى قسم معالجة الأخطى عن طريق الامر Raise او في حالة حصول خطاء منطقي . للتوضيح خذ المثال التالي :(المثال عبارة عن فنكشن نمرر لها رقم الموظف وتعطينا اسم الموظف إعتماداً على جدول الموظفين الموجود في المستخدم الإفتراضيSCOTT ) create or replace function Get_emp_name(p_empno emp.empno%type) return varchar2 is l_ename emp.ename%type; l_result emp.ename%type; begin if p_empno is null Then raise_application_error(-20001,'لم يتم العثور على رقم الموظف'); end if; select ename into l_ename from emp where empno =p_empno; return l_ename; Exception when others then raise_application_error(-20001,'Error in get_Emp_name :' || sqlerrm); end; ذكرنا ان كود معالجة الأخطاء يتم تنفيذة فقط عندما يحصل خطاء منقطي او عند اجبار البرنامج على الذهاب الى كود الأخطاء ومعنى هذا انه اذا تم انفيذ الكود او الإجراء دون اين يتحقق احد الشرطين المذكورين فان البرنامج سوف ينتهي دون الذهاب الى جزء معالجة الأخطاء . 1- في حالة إجبار البرنامج على الذهاب الى جزء معالجة الأخطاء :لاحظ جملة الشرط الموجودة مباشرة بعد كلمة Begin والتي تقضي الى اجبار البرنامج على الذهاب الى جزء معالجة الأخطاء بمجرد اكتشاف ان رقم الموظف ( والذي يعتبر مفاح اساسي لارجاع الاسم في هذه الفنكشن ) غير موجود اعتقد انه من المنطقي جداً انهاء الإجراء وإعطاء المستخدم رسالة توضح سبب انهاء الإجراء , وهذا ماسيحصل في حالة استدعاء الفنكشن وتمرير قيمة null لرقم الموظف .لإثبات مانقول دعنا ننشى شاشة بالدفلوبر تحوي push_button وتحت الحدث when-button-pressed اكتب هذا الكود ثم نفذ . declare l_name varchar2(200); begin l_name := get_emp_name(null); message(l_name); exception when others Then message(sqlerrm); end; هذا الخطاء كان متوقعاً (ان يتم تمرير قيمة فارغة لرقم الموظف )لذلك عملت على معالجته واضهرت الرسالة المناسبة للمستخدم . اما اذا كان الخطاء غير متوقع فان الكود الموجود في قسم معالجة الأخطاء (sqlerrm) سوف يظهر رسالة توضح سبب الخطاء . 2- في حالة حصول خطاء منطقي :لو ان خطاء منطقي حصل في البرنامج كان يتم تنفيذ جملة Select تؤدي الى ارجاع اكثر من سجل او ارجاع صفر سجل (سب وان تحدثنا عن هذا الموضوع في درس الCursor ) فان الPL/SQL سوف تذهب مباشرة الى قسم الأخطاء للبحث عن كود يعالج الخطاء .مثلاً لو مررنا رقم موظف غير موجود اصلا في الجدول , فان جملة الSelect سوف ترجع صفر سجلات وهذا خطاء منطقي سوف يؤدي الى الانتقال مباشرة الى قسم معالجة الأخطى واعطاء الرسالة التي توضح ذلك . declare l_name varchar2(200); begin l_name := get_emp_name(999999); message(l_name); exception when others Then message(sqlerrm); end; 12. متى يستخدم الـ Exception : انا شخصياً افضل استخدام الException في معظم الإجراءات سواً كانت على مستوى قاعدة البيانات (Back-End ) او على مستوى الواجهات (Front-End ) والسبب هو ان يتم التوقف عند كل خطاء متوقع او غير متوقع لمعرفة سبب الخطاء ومعالجته . ولكن هذا لايعني ان اعمل exception في كل الإجراءات على الاطلاق فبعض الإجرات قد تكون اجراءات من المستحيل ان تحوي اخطاء وذلك بسبب طريقة كتابتها , او ان بعض الإجراءات تكون اجراءات فرعية او خاصة Private يتم الوصل اليها عن طريق اجراءات عامة Public , وفي هذه الحالة نستطيع ان نعالج الخطاء في الإجراء العام . هذا ماسنتطرق الي في النقطه رقم 3 (رمي الخطاء الى الإجراء العام او معالجته في الإجراء الحالي) انشاء الله .2- مامعنى معالجة الاخطاء وماالفرق بين الاكواد التي تحوي جزء معالجة الأخطاء والتي لا تحيوي معالجة الخطى لا تعني التغلب على الخطاء وجعل البرنامج يعمل وكأن شي لم يحصل , لان الException هو في الاساس جزء من الكود يستفاد منه لمعالجة الأخطاء التي لا يستطيع المبرمج التنبى بها او التي غفل عنها , والدور الاكبر لمعالجة الاخطاء ليس من مهمة الException part الموجود في الكود البرمجي , بل يكمن الدور الاساسي لتفادي الأخطاء على المبرمج نفسه , فيجب ان يحرص كل الحرص على كتابة الكود بصورة تمنع وجود اي شؤائب او اخطاء متوقعة او غير متوقعة في الكود (كفحص القيم والتأكد من سلامتها قبل استخدامها في اي عملية داخل الكود , وكذلك التأكد من سلامة ووجود كل المدخلات اللازمة والتي يحتاجها الكود حتى ينفذ بصورة سلسة وسليمة ) , ومابقي والتي لا تستطيع ان تحصرها يأتي دور الException part في التعامل معها وليس معالجتها بصورة نهائية .صور معالجة الاخطاءتأتي صور معالجة الأخطاء بأشكال مختلفة وغير محصورة ’ وذلك يعتمد على طبيعة الخطاء والكود البرمجي الذي ظهر فيه الخطاء ولكن معظم الException Part تحوي او تعطي رسائل للبيئة التي استدعت الكود موضحة فيها سبب الخطاء ومكان او اسم الكود الذي تسبب في الخطاء واي بيانات اخرى كمصدر الخطاء هل هو قاعدة البيانات او الشاشات .مثال : (تستخدم هذه الفنكشن لاعطاء نتيجة عملية حسابية بين رقمين ) create or replace function my_calc(p_num1 number, p_num2 number , p_opr char :='+') return number is l_Result number(4); l_num1 number(2); l_num2 number(2); begin l_num1:=p_num1; l_num2:=p_num2; if p_opr ='-' Then l_Result := l_num1 - l_num2; elsif p_opr='*' Then l_Result := l_num1 * l_num2; elsif p_opr='/' Then l_Result := l_num1 / l_num2; else l_Result := l_num1 + l_num2; end if; return(l_Result); exception when others then raise_application_error(-20001,'Error in my_calc ' || sqlerrm); end my_calc; لو نلاحظ ان طبيعة المعالجة في هذا المثال هي عبارة عن رسالة توضيحية فقط توضح سبب الخطاء واسم الفنكشن التي حصل فيها الخطاء . ولكن قد يأتي مبرمج أخر ويقول اني سوف اضيف كود اضافي في الـException Part وذلك تسجيل رسالة الخطاء ووقت حدوث الخطاء ومن هو المستخدم الذي تسبب في ظهور الخطاء (وهذا شكل اخر من اشكال معالجة الخطاء) , واليك المثال السابق بعد التعديل create or replace function my_calc(p_num1 number, p_num2 number , p_opr char :='+') return number is l_Result number(4); l_num1 number(2); l_num2 number(2); l_error_txt varchar2(200); begin l_num1:=p_num1; l_num2:=p_num2; if p_opr ='-' Then l_Result := l_num1 - l_num2; elsif p_opr='*' Then l_Result := l_num1 * l_num2; elsif p_opr='/' Then l_Result := l_num1 / l_num2; else l_Result := l_num1 + l_num2; end if; return(l_Result); exception when others then l_error_txt :=sqlerrm; insert into error_log values (user,sysdate,l_error_txt); commit; raise_application_error(-20001,'Error in my_calc ' || sqlerrm); end my_calc; نفذ الفنكشن وحاول ادخال القيم التالية كمعطيات للفنكشن[font=Tahoma]1- my_calc(1,1) تنفيذ بدون مشاكل2- my_calc(1,0,'/') خطاء قسمة على صفربعد التنفيذ واعطاء القيم الموضحه في الحالة رقم 2 سوف تلاحظ ظهور راسلة خطاء وفي نفس الوقت تسجيل معلومات الخطاء في الجدول (error_log ) ملاحظه : يجب انشاء الجدول error_log قبل انشاء وتنفيذ الفنكشن الموضحه في المثال .[/font] الفرق بين الاكواد التي تعالج الأخطاء والتي لا تعالج الاخطاء قد يؤدي الكود الذي يحوي خطاء والذي لم يتم معالجته في اي مرحلة من مراحل التنفيذ الى سلوك غير متوقع في النظام (إنهاء التنفيذ كلياً) كما ان الاكواد التي لا تحوي اجزاء معالجة الاخطاء تؤدي على تعقيد مهمة المطور او المبرمج في متابعة الكود ومعرفة الجزئية التي تسببت في حدوث الخطاء في البرنامج (لان وفي حالات كثيرة تجد ان package او الFunction او الProcedure يعمل على استدعاء كود او subroutine اخر وهذا الsubroutine قد ستدعي اخر وهكذا) فعندما يحصل اي خطاء في subroutine معين ولم يتم معالجه الخطاء داخل الsubroutine فانه سوف يحالو معالجته في الsubroutine الاب وهكذا الى ان يصل الى اخر نقطه في طبقات التنفيذ وهنا تظهر رساله للمستخدم او المطور يخبره بوجود خطاء غير معالج (اين حصل الخطاء وماهو هذه الخطاء وما الذي سبب الخطاء ؟ والإجابه غير معوف والسبب هو عدم معالجه الخطاء ) هذا هو الفرق بين الاكواد التي تعالج الأخطاء والتي لا تعالج .إذا من الان وصاعداً يجب ان ننتبه لهذة الجزئية المهمة اثناء كتابة الاكواد البرمجية . تم تعديل 23 يونيو 2007 بواسطة khaled اقتباس رابط هذا التعليق شارك المزيد من خيارات المشاركة
k_ocp بتاريخ: 20 يونيو 2007 تقديم بلاغ مشاركة بتاريخ: 20 يونيو 2007 جزاك الله خيرا و جعله الله فى ميزان حسناتك اقتباس رابط هذا التعليق شارك المزيد من خيارات المشاركة
المبرمج الصاعد بتاريخ: 20 يونيو 2007 تقديم بلاغ مشاركة بتاريخ: 20 يونيو 2007 السلام عليكم؟أستاذنا الكبير كلامك أكثر من رائع ونحب نشوفك أكثر يا أستاذي الفاضل... اقتباس رابط هذا التعليق شارك المزيد من خيارات المشاركة
khaled بتاريخ: 21 يونيو 2007 كاتب الموضوع تقديم بلاغ مشاركة بتاريخ: 21 يونيو 2007 الاخوان ( k_ocp , المبرمج الصاعد ) شكراً لمروركم الكريم اقتباس رابط هذا التعليق شارك المزيد من خيارات المشاركة
Genius01 بتاريخ: 3 يوليو 2007 تقديم بلاغ مشاركة بتاريخ: 3 يوليو 2007 اشكرك على على تكملة الدرس اخوي ولك اجمل التحيات من G4D اقتباس رابط هذا التعليق شارك المزيد من خيارات المشاركة
احمد الراسى بتاريخ: 19 سبتمبر 2007 تقديم بلاغ مشاركة بتاريخ: 19 سبتمبر 2007 اخى الحبيب بارك الله فيك وجزاك الله كل الخيرمجهودك مشكوووورانى لك من المتابعين اقتباس رابط هذا التعليق شارك المزيد من خيارات المشاركة
msb_designer بتاريخ: 20 سبتمبر 2007 تقديم بلاغ مشاركة بتاريخ: 20 سبتمبر 2007 الف شكر ليك اخىبارك الله فيك اقتباس رابط هذا التعليق شارك المزيد من خيارات المشاركة
waziry بتاريخ: 16 أكتوبر 2008 تقديم بلاغ مشاركة بتاريخ: 16 أكتوبر 2008 جزاك الله خير على هذا الشرح الماتع ويا رت تعمل فورمه لهذه الفانكشن وترسلها لنا على جدولempونرى عليها كيفيه نعالج الاخطاء اقتباس رابط هذا التعليق شارك المزيد من خيارات المشاركة
waziry بتاريخ: 16 أكتوبر 2008 تقديم بلاغ مشاركة بتاريخ: 16 أكتوبر 2008 أرجوا المساعدة انا لاادرى هل اعمل الفانكشن على مستوى الداتا بيز ام على مستوى الفورم رجاء اريد تنفيذ هذه الفانكشن عملى على فورم حتى احس بكيفية معالجه الاخطاء وجزاكم الله خير اقتباس رابط هذا التعليق شارك المزيد من خيارات المشاركة
Recommended Posts
انضم إلى المناقشة
يمكنك المشاركة الآن والتسجيل لاحقاً. إذا كان لديك حساب, سجل دخولك الآن لتقوم بالمشاركة من خلال حسابك.