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

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

صورة
- - - - -

من مزايا أوراكل 10g الحزمة Dml Error Logging


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

#1 sky information

sky information

    عضو نشط

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

تاريخ المشاركة 02 August 2007 - 01:26 PM

DML Error Logging




هل حاولت مرة أن تحدث مجموعة كبيرة من السجلات وبعض عدة ثواني تفشل المحاولة بسب سجل واحد تعارض مع القيد, أو هل أدخلت سجلات عن طريق عبارة
insert-as-select ثم تفشل المحاولة في إدخال فرضا 999 سجل من 1000 سجل بسب إدخال قيمة كبيرة في عمود ما ؟؟؟ لكن باستخدام DML error logging و بإضافة عبارة واحدة إلى عبارة Select سوف تسبب نجاح إدخال الـ999 سجل والسجل المسبب للخطأ سوف يسجل خارجا في جدول

لنبدأ :


نعمل جدول يحوي مع بعض القيود لغرض الانتهاك(انتهاك القيد الفريد):
SQL> create table dmlel 
(pkey varchar2(100) primary key,
 field1 varchar2(1), 
field2  varchar2(10) not null);

الآن لنعمل سكربت يفشل بدون استخدام DML error logging
, السكربت التالي سيقوم إدخال بعض الصفوف وبعد ذلك سوف يفشل بسبب قيمة كبيرة للعمود:

Declare
 i number;
Begin
i := 0;
while i <= 10 loop
insert into dmlel (pkey, field1, field2)
values (i, i, i);
i := i+1;
end loop;
End;
/
*
[color=#990000]ERROR at line 1:
ORA-12899: value too large for column "BULKLOAD"."DMLEL"."FIELD1" (actual: 2, maximum: 1)
ORA-06512: at line 5[/color]

من الملاحظ أن القيمة كبيرة جدا على العمود FIELD1 لأن عدد الخانات المحددة له هي خانة واحدة وحين تصل حلقة الدوران إلى العدد 10 سيكون قيمة i=10 وهي أكبر من القيمة المحددة للعمود ولذلك حصل الخطأ الذي أدى إلى فشل إدخال جميع السجلات .
لكي نعالج هذا الخطأ باستخدام DML error logging يجب أولا إنشاء جدول لأخطاء DML لكي تسجل فيه.

إنشاء Error Logging Table
:

هنالك طريقتان لإنشاء هذا الجدول الطريقة الأولى بشكل آلي أما الثانية بشكل يدوي ,سوف نتكلم عن الطريقة الآلية فقط إن الأوراكل يوفر built-in pl/sql package تسمى DBMS_ERRLOG وهي خصوصا لهذا الغرض.

SQL> begin
 dbms_errlog.create_error_log('DMLEL','ERROR_LOG_DMLEL');
  end;
	/

PL/SQL procedure successfully completed.

SQL> desc error_log_dmlel
 Name									  Null?	Type
 ----------------------------------------- -------- ----------------------------
 ORA_ERR_NUMBER$								 NUMBER
 ORA_ERR_MESG$									   VARCHAR2(2000)
 ORA_ERR_ROWID$									 ROWID
 ORA_ERR_OPTYP$									 VARCHAR2(2)
 ORA_ERR_TAG$										  VARCHAR2(2000)
 PKEY															  VARCHAR2(4000)
 FIELD1														   VARCHAR2(4000)
 FIELD2														   VARCHAR2(4000)

ملاحظة :
إذا لم يتم تعيين أسم للجدول سوف يتم تسميته بالاسم الافتراضي وهو ERR$_ متبوع باول 25 حرف من أسم الجدول.

تسجيل الخطأ:

عندما ينشأ الجدول لتسجيل أخطاء DML لجدول معين ,فإن كل ما يحتاج لتسجيل الأخطاء اتجاه ذلك الجدول هو إضافة عبارة تسجيل الخطأ للأمر insert أو update أو delete أو merge
Declare
 i number;
Begin
i := 0;
while i <= 10 loop
insert into dmlel (pkey, field1, field2)
values (i, i, i)
LOG ERRORS INTO ERROR_LOG_DMLEL REJECT LIMIT 1;
i := i+1;
end loop;
End;
/
PL/SQL procedure successfully completed.

ملاحظة:
يجب معرفة أن عبارة REJECT LIMIT هي اختيارية فإن القيمة الافتراضية هي 0 لذا إذا لم يتم تحديد قيمة لـ REJECT LIMIT فستكون غير فعالة
وبهذه الطريقة تم إدخال جميع السجلات أما السجل الذي تسبب بالخطأ ora-12899لن يعيق عملية إدخال السجلات الأخرى ثم تم تسجيله إلى error_log_dmlel :

SQL>set lines 110
SQL> col num$ for 9999999  
SQL> col ora_err_mesg$ for a50
SQL> col ora_err_rowid$ for a25
SQL> col typ for a3 
SQL> col pkey for a4
SQL> col field1 for a4
SQL> select ora_err_number$ num$, ora_err_mesg$,
		  ora_err_rowid$, ora_err_optyp$ typ, pkey, field1 
		 from error_log_dmlel
SQL> /

	  NUM$ ORA_ERR_MESG$									  ORA_ERR_ROWID$			TYP PKEY FIEL
---------- -------------------------------------------------- ------------------------- --- ---- ----------------------------
	 12899  ORA-12899: value too large for column "BULKLOAD"."							   I	  10		10  
				DMLEL"."FIELD1" (actual: 2, maximum: 1)

مخرجات جملة السيلكت :

رقم الخطأ للأوراكل تم حفظه في ORA_ERR_NUMBER$ وأيضا الرسالة تم حفظها في ORA_ERR_MESG$ أما بالنسبة لـقيمة rowid فهي null لأن عملية الإدخال فشلت كما هو موضح لنوع العملية (ORA_ERR_OPTYP$ of I)حيث I يدل على Insert , لكن سيتم تسجيل قيم rowid للسجلات إذا كانت العمليات الفاشلة هي update,delete,merge .
أما بالنسبة لـ ORA_ERR_TAG$ فيستخدم في عنونة الخطأ و يمكن أن يستخدم لتمييز أي من البيانات قد سبب الخطأ وهنا مثال يوضح :

المثال :

في هذا المثال سوف نستخدم الحزمة DBMS_RANDOM لتوليد أرقام عشوائية من 0 إلى 9 في جملة الإدخال حيث سيدخل 101 , تدخل القيم في العمود dmlel.pkey الذي يحوي القيد primary key

declare 
i number;
begin
  i := 0;
dbms_random.initialize(2);
while i <= 100 loop
insert into dmlel (pkey, field1, field2)
values (trunc(dbms_random.value*10), 0, 0)
LOG ERRORS INTO ERROR_LOG_DMLEL ('Iteration number: ' || to_char(i))
REJECT LIMIT 1;
i := i+1;
end loop;
end;
/
ْ

SQL> select count(*) from dmlel;

  COUNT(*)
----------
		10

SQL> select count(*) from error_log_dmlel;

  COUNT(*)
----------
	  91

من الملاحظ أن 10 سجلات تم إدخالها في الجدول بينما 91 سجل تم رفضهم .
الآن نستطيع تمييز من 101 ما هي العبارات التي تسببت بالخطأ من خلال ORA_ERR_TAG$ field :

نفذ السكربت التالي :
SQL>set lines 110
SQL> col num$ for 999999  
SQL> col ora_err_mesg$ for a65
SQL> col pkey for a4
SQL> col ora_err_tag$ for a25
SQL> ora_err_mesg$, pkey, ora_err_tag$
	 from error_log_dmlel
	 order by to_number(substr(ora_err_tag$,19,4))

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

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

#2 Amgad

Amgad

    مشرف عام ومشرف قسم تحليل النظم

  • الفريق الإداري
  • 4,559 مشاركة
  • الاسم الأول:امجد
  • اسم العائلة:حلمي
  • البـلـد: Country Flag
  • المنصب الحالي:Business Systems Analyst at al Fanar Co. Riyadh KSA

تاريخ المشاركة 02 August 2007 - 01:44 PM

الأخ / sky information

اضافة متميزه .. من عضو متميز

شكرا لك .. وجزاك الله خيرا

لا تنسى

ترقبوا المرة القادمة ستكون هنالك مواضيع أكثر أهمية



فى انتظارك

لا إله إلا الله الحليم الكريم
لا اله إلا الله العلى العظيم
لا اله إلا الله رب السماوات السبع و رب العرش العظيم
‏اللهم ارزقني قبل الموت توبة وعند الموت شهادة وبعد الموت جنة
اللهم ارزقني حسن الخاتمة
اللهم هون علينا سكرات الموت ... ونور علينا قبورنا
اللهم ارزقني الموت وأنا ساجد لك يا ارحم الراحمين
اللهم ثبتني عند سؤال الملكين
اللهم اجعل قبري روضة من رياض الجنة ولا تجعله حفرة من حفر النار
اللهم اني اعوذ بك من فتن الدنيا
اللهم ارحم ابائنا وامهاتنا واغفر لهما وتجاوز عن سيئاتهما وادخلهم فسيح جناتك ... والحقنا بهما يا رب العالمين
اللهم ارحم موتانا وموتى المسلمين واشفي مرضانا ومرضى المسلمين
اللهم اغفر للمسلمين والمسلمات والمؤمنين والمؤمنات الأحياء منهم والأموات
وبارك اللهم على سيدنا محمد صلى الله عليه وسلم
اللهم آمين ... اللهم آمين ... اللهم آمين


....


#3 sky information

sky information

    عضو نشط

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

تاريخ المشاركة 02 August 2007 - 01:59 PM

مشكــــــــــور أخوي أمجد لحضورك وأنا عندي وعدي بأذن الله

#4 mido_fawzy84

mido_fawzy84

    عضو

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

تاريخ المشاركة 22 October 2007 - 04:30 PM

والله مشكورين بصراحة على المجهود العظيم وربنا يوفقكم دائما لما فيه الخير

وأتمنى أن تستمروا على هذا المنوال في إضافة المعلومات القيمة

#5 جلال شواقفه

جلال شواقفه

    عضو مميز

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

تاريخ المشاركة 23 October 2007 - 12:15 PM

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

جلال محمود شواقفه
مدير دائرة الحاسوب
بلدية المفرق الكبرى
المملكه الاردنيه الهاشميه.

#6 ahmedselim

ahmedselim

    عضو

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

تاريخ المشاركة 18 November 2007 - 08:55 AM

جزاك الله خيراً

#7 omar-alreyati

omar-alreyati

    عضو مميز

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

تاريخ المشاركة 18 November 2007 - 10:54 AM

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

بالله عليكم لا تنسوني من دعاءكم الصالح
لا تنسوا أهل غزة والعراق والمجاهدين من دعاءكم