إنتقال للمحتوى

  • تسجيل الدخول عبر الفيس بوك تسجيل الدخول عبر تويتر Log In with LinkedIn Log In with Google      تسجيل دخول    
  • إنشاء حساب

صورة
- - - - -

دروس متقدمة في الــ Pl/sql الدرس الثاني Error Handling


8 رد (ردود) على هذا الموضوع

#1 khaled

khaled

    مشرف سابق وعضو مميز

  • المجموعة الماسية
  • 251 مشاركة

تاريخ المشاركة 20 June 2007 - 12:20 PM

بسم الله الرحمن الرحيم


اعزائي زوار واعضاء منتدى عرب اوركل المحترمين تحية طيبة .
تكملة لما قد بدأناه من قبل(دروس متقدمة في الـ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 الاب وهكذا الى ان يصل الى اخر نقطه في طبقات التنفيذ وهنا تظهر رساله للمستخدم او المطور يخبره بوجود خطاء غير معالج (اين حصل الخطاء وماهو هذه الخطاء وما الذي سبب الخطاء ؟ والإجابه غير معوف والسبب هو عدم معالجه الخطاء ) هذا هو الفرق بين الاكواد التي تعالج الأخطاء والتي لا تعالج .
إذا من الان وصاعداً يجب ان ننتبه لهذة الجزئية المهمة اثناء كتابة الاكواد البرمجية .

تم التعديل بواسطة khaled, 23 June 2007 - 04:01 PM.

خالد مبارك العوبثاني
اليمن-حضرموت
Email :Aboanter84@hotmail.com

#2 k_ocp

k_ocp

    مشترك

  • الأعضــاء
  • 110 مشاركة
  • البـلـد: Country Flag

تاريخ المشاركة 20 June 2007 - 01:25 PM

جزاك الله خيرا و جعله الله فى ميزان حسناتك

#3 المبرمج الصاعد

المبرمج الصاعد

    مشرف عام

  • الفريق الإداري
  • 713 مشاركة
  • البـلـد: Country Flag
  • الاهتمامات:بكل جديد من التقنية..

تاريخ المشاركة 20 June 2007 - 08:44 PM

السلام عليكم؟

أستاذنا الكبير كلامك أكثر من رائع ونحب نشوفك أكثر يا أستاذي الفاضل...

IT Manager


#4 khaled

khaled

    مشرف سابق وعضو مميز

  • المجموعة الماسية
  • 251 مشاركة

تاريخ المشاركة 21 June 2007 - 08:39 AM

الاخوان ( k_ocp , المبرمج الصاعد ) شكراً لمروركم الكريم
خالد مبارك العوبثاني
اليمن-حضرموت
Email :Aboanter84@hotmail.com

#5 Genius01

Genius01

    عضو

  • الأعضــاء
  • 2 مشاركة

تاريخ المشاركة 03 July 2007 - 11:06 PM

اشكرك على على تكملة الدرس اخوي ولك اجمل التحيات من G4D

#6 احمد الراسى

احمد الراسى

    عضو

  • الأعضــاء
  • 49 مشاركة
  • الاسم الأول:احمد
  • اسم العائلة:الراسى
  • البـلـد: Country Flag

تاريخ المشاركة 19 September 2007 - 11:51 PM

اخى الحبيب بارك الله فيك
وجزاك الله كل الخير
مجهودك مشكوووور
انى لك من المتابعين

تفوت أيـام تمـوت أحــلام تعــدى شـــهور

تــدور الأرض والدنيـــا وهـــو يــــــــــــدور

ولسه بيجرى ويعافر ولسه عيونة بتسافر

ولســـــه قلبة لـــم يتعب من المشـــاوير


#7 msb_designer

msb_designer

    مشترك

  • الأعضــاء
  • 105 مشاركة

تاريخ المشاركة 20 September 2007 - 05:14 AM

الف شكر ليك اخى
بارك الله فيك

ORA-MSB
OCP



*** كلمـــــــــــــــــات من ذهـــــــــــــــــــب ***
** اللهم أتنا فى الدنيا حسنة وفى الاخرة حسنة وقنا عذاب النار **
** لا إله إلا أنت سبحانك إنى كنت من الظالمين **
** سبحان الله وبحمده سبحان الله العظيم **


#8 waziry

waziry

    مشترك

  • الأعضــاء
  • 199 مشاركة

تاريخ المشاركة 16 October 2008 - 10:19 AM

جزاك الله خير على هذا الشرح الماتع

ويا رت تعمل فورمه لهذه الفانكشن وترسلها لنا على جدولemp

ونرى عليها كيفيه نعالج الاخطاء

#9 waziry

waziry

    مشترك

  • الأعضــاء
  • 199 مشاركة

تاريخ المشاركة 16 October 2008 - 10:46 AM

أرجوا المساعدة

انا لاادرى هل اعمل الفانكشن على مستوى الداتا بيز ام على مستوى الفورم

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

وجزاكم الله خير