توجد عدة انواع من Trigger منها على مستوى الـ FORM ومنها على مستوى BLOCK ومنها على مستوى ITEM وغيرها
فيحبدا لو تكرم احد اعضاء المنتدى باعطائنا نبدة على هذه الانواع والفرق بينها واستخداماتها وكل مايتعلق حولها
والسلام عليكم ورحمة الله وبركاته
توجد عدة انواع من Trigger منها على مستوى الـ FORM ومنها على مستوى BLOCK ومنها على مستوى ITEM وغيرها
فيحبدا لو تكرم احد اعضاء المنتدى باعطائنا نبدة على هذه الانواع والفرق بينها واستخداماتها وكل مايتعلق حولها
والسلام عليكم ورحمة الله وبركاته
يختلف الTrigger ومهمته حسب إسمه، فمثلا الTrigger المسمى KEY_DELREC من مهامه مسح السجل المعين، وهكذا لكل منها مهمة معينة، وبالتدريب وكثرة العمل يمكن للمبرمج فهم عمل كل منها دونما يحفظ الإسم والعمليه المصاحبة. وهناك الأمر الآخر وهو متى تقوم الأوراكل بتشغيل هذا الزناد، وهنا يمكن القول بأه هناك عدد من المستويات لوضعة إما على مستوى الحقل المعين Field Level، أو على مستوى الحزمة Block Level، أو على مستوى البرنامج ككل Form Level، وكل يقوم بالعمليه المنوطة به حسب وضعه في البرنامج وإسمه والكود الذي تعطيه إياه ليقوم بتنفيذه،كما ان ليس كل ال Triggers يمكن وضعهم في أي مكان، فهناك من هو مخصص للحقول، وهناك من هو مخصص للحزم وايضا من هو مخصص للبرنامج ككل. وينقسم إسم الزناد عادة إيى قسمين يفصلهما علامة Under Score، وقد يحتوى الإسم على ثلاث اجزاء، ولكن ذلك بسبب التسكية ومتطلباتها، القسم الأول من اللإسم يعرف وضعية ومكان تشغيل الزناد، وهناك أنواع معينه منها
[*] KEY وهو للزناد الذي يرتبط بعملية تنفيذ مرتبطة بمفتاح معين في اللوحة (F8,F9) مثلا، وهو أمر واجب التنفيذ عند المرور بمرحلته
[*]ON وهو مشابه لأول ولكنه قد لا يرتبط بحقل معين، وهو امر مشروط يتم تنفيذه بشرط إسمه (ON-LOCK,ON-INSERT)
[*] PRE وهو يفيد ان الكود المرافق لهذا الزناد هو عمليه سابقة لتنفيذ الجزء الثاني من الإسم مثلاً PRE-FILED تفيد ان الكود المصاحب لهذا الزناد يتم تشغيله بمجرد ما قام البرنامج بالمحاولة للإنتقال الى الحقل الذي كتب عليه هذا الزناد.
[*] POST وهو عكس سابقه، اذ ان العمليه هنا بعديه
ارجو ان اكون قد اوضحت
جزاك الله خير اخي السني لقد كتبنا في نفس الوقت :) ولكن زيادة الخير خيرين .
السلام عليكم ورحمة الله
اخي العزيز محمد عندماتطلب شرح عن الـ Trigger فإنك تطلب شرح عن Form فالموضوع طويل جدا ومتشعب ايضا . انا لااريد ان اقلل من حماسك ولكن حتى تعرف انه يحتاج الى صبر وليس من السهل شرحه بسرعه وببساطه ولأن هناك ايضا امور يجب معرفتها في Form قبل الدخول الى الـ Trigger مثلا ان تنشأ حقل على الشاشه ليس له علاقه بالجدول وانما للعرض ومن ثما استخدامه في Trigger واضهار النتائج عليه. ان تكون على درايه طيبه بـ PL/SQL انواع رسائل الخطأ وطريقة اخمادها..... الخ . لذا اقترح ان يتعاون اكثر من شخص في كتابة هذا الدرس اي كل شخص يأخذ جزء منه . وانا سوف ابدأ به على شكل اجزاء ومن اراد ان يكتب معي فجزاه الله خير او على الأقل يضيف الى مااكتبه او يعدل اذا اخطأت او يوضح اذا لم يكن شرحي واضح ( وعلى الله توكلنا) .
[F=5][F=Red] What is a Trigger ?[/F][/F]
هو عباره عن برنامج PL/SQL ينفذ عند حدث معين .
يتكون من :
[F=Navy]- Trigger type
- Trigger code
- Trigger scope[/F]
- تحديد خاصية الحدث الذي عنده ينطلق الـ Trigger .
- ماذا يفعل بعد الانطلاق (اي pl/sql البرنامج ) .
- مكان انطلاقه ومستواه .
[C][F=Green]Trigger Scope[/F][/C]
1- على مستوى الـ FORM
2- على مستوى الـ BLOCK
3- على مستوى الـ ITEM
[C][F=Green]Trigger Type[/F][/C]
1- Pre --- قبل حدوث شيء ما
2- Post --- بعد حدوث شيء ما
3- When --- لحظه حدوث شيء ما
4- On
5- Key
اخي محمد انا لم انتهي بعد وانا مضطر للتوقف الآن على ان اعود لاحقا لأكماله .
ابو عبدالآله
بعد التحية
أخواني الأعزاء هذه بعض الأمثلة على Triggers ارجوا ان تكون مفيدة لكم :- وهي من Database Trigger وليست من نوع
Forms Tigger .....
المثال الأول
***********************************************************
CREATE OR REPLACE TRIGGER SECURE_EMP
BEFORE INSERT ON EMP
BEGIN
IF (TO_CHAR(SYSDATE,'DY') IN ('SAT','SUN') OR TO_CHAR(SYSDATE,'HH24') NOT BETWEEN '08' AND '13'
RAISE_APPLICATION_ERROR(-20500,'You may only insert into emp during normal hours.');
end if;
end;
**********************************
فائدة ال trigger السابق هي كالتالي :-
1-منع المستخدمين من أضافة سجلات جديدة إذا كان اليوم هو السبت أو الأحد .
2-منع المستخدمين من أضافة سجلات جديدة إذا بين الساعة 8 والساعة 13 .
3-اظهار رسالة خطاء للمستخدم عندما تنطبق شروط هذا ال trigger
المثال الثاني
***********************************************************
أولا نقوم بإنشاء الجدول التالي
create table loging (
user_id varchar2(20),
log_date date,
action varchar2(20),
ttime varchar2(10))
***********************************
بعد ذلك نقوم بإنشاء ال trigger التالي وهو
create or replace trigger logon_trig
after logon on schema
begin
insert into loging(user_id,log_date,action,ttime)
values(user,sysdate,'loging on',to_char(sysdate,'HH12:mi:ss'));
end;
فائدة ال trigger السابق هي
1-تسجيل أسماء المسنخدمين وتورايخ دخولهم ونوع العملية هل هي دخول او خروج ووقت الدخول على قاعدة البيانات في جدول loging
2-مراقبة الدخول على قاعدة البيانات .
ملاحظة :-هذا النوع من ال triggers لايعمل إلا مع أصدرات أوراكل
8 او أعلى والله أعلم لم أجربه مع أوراكل 7
*****************************************
طبعا يمكننا عمل trigger ينطلق عند خروج المستخدم من قاعدة البيانات كالتالي
create or replace trigger logoff_trig
before logoff on schema
begin
insert into logof(user_id,log_date,action,ttime)
values(user,sysdate,'loging off',to_char(sysdate,'HH:mi:ss'));
end;
فائدة ال trigger السابق هي
1-تسجيل أسماء المسنخدمين وتورايخ دخولهم ونوع العملية هل هي دخول او خروج ووقت الخروج من قاعدة البيانات في جدول loging
2-مراقبة الخروج من قاعدة البيانات .
وان شاء الله هناك المزيد ......
محمد الشنقيطي
اخواني ابو عبدالآله ومحمد الشنقيطي والسني
اشكركم على الاهتمام والرد واطلب من اخي محمد بدوي ان يضم هذه الدروس بعد انتهائها الى قسم الدروس وبارك الله في اخواني والله يفتح عليكم
والسلام عليكم ورحمة الله وبركاته
السلام عليكم ورحمة الله
اخي محمد هذه امثله بسيطه اتمنى ان تجد فيها الفائده وتلبي طلبك .
مثال :
-FORM LEVEL-
عند الحدث WHEN-NEW-FORM-INSTANCE
SET_WINDOW_PROPERTY(forms_mdi_window,WINDOW_STATE,MAXIMIZE);
SET_WINDOW_PROPERTY('COLLEG',WINDOW_SIZE,350,200);
GO_BLOCK('USER_INFO');
EXECUTE_QUERY;
Read_Image_File('C:WINDOWSDesktopflashSAUDI-F.GIF', 'ANY', 'USER_INFO.image');عند انشائك لفورم ما تجد ان الفورم لم يوضع في المكان الصحيح على الشاشه إضافة لذلك إطار الويندوز الخلفيه ليست على وضع maximize مما يجعلك ترى سطح المكتب هذا الـ Trigger يقوم بتكبير إطار الويندوز ويقوم بتوسيط إطار الفورم على حسب القياسات المعطاه ( COLLEGE هو اسم الفورم) ومن ثم يعرض البيانات ويظهر صوره قد تكون شعار للشركه مثلا .
:SYSTEM.MESSAGE_LEVEL:='5';
GO_BLOCK('S_EMP');
PREVIOUS_RECORD;
IF FORM_SUCCESS THEN
EXECUTE_QUERY;
ELSE MESSAGE('NO..NO..NO..NO..NO..???');
END IF;
:SYSTEM.MESSAGE_LEVEL:='0';اذا لم تفهم المثال انتظر الشرح في درس EXCIPTIONS
-Data Block-
عند الحدث (WHEN-VALIDATE-RECORD) التحقق من الصحه
هذا المثال يمنع ان يسبق تاريخ الطلب تاريخ اليوم .
IF :S_ORD.DATE_ORDERED>SYSDATE THEN
MESSAGE('ORDER DATE IS LATER THAN TODAY !');
RAISE FORM_TRIGGER_FAILURE;
END IF;طبعا اكيد انك تعرف الـ ALERT واذا لم تكن تعرف اخبرني لأشرحها والآن انا افرض انك تعرف الـ ALERT .
لوكان لديك حقل تدخل فيه مبلغ الدفع المستحق ، نعمل Trigger يقوم بإظهار رساله تقول : شكرا على تسديد المبلغ ،زرنا مره اخرى .
-ITEM LEVEL-
عند الحدث (PRE-TEXT-ITEM)
DECLARE
S NUMBER;
BEGIN
S:=SHOW_ALERT('AL_MESSA');
IF S=ALERT_BUTTON2 THEN
RAISE FORM_TRIGGER_FAILURE;
END IF;
END;-DATA BLOCK-
عند الحدث (PRE-INSERT)
هذا المثال يقوم بوضع عداد تلقائي
select seq_emp.nextval into :s_emp.id from sys.dual;
حيث :
seq_emp : اسم العداد الذي انشأته مسبقا
nextval : القيمه التاليه
-ITEM LEVEL-
عند الحدث (WHEN-VALIDATE-ITEM) للتحقق من الصحه
هذا المثال يظهر رساله تقول عليك ادخال قيمه بين 1000 و 2000
ويمنع اي رقم غير ذلك .
DECLARE
X NUMBER;
BEGIN
IF :SALARY NOT BETWEEN 1000 AND 2000 THEN
X:=SHOW_ALERT('AL_E');
IF X=ALERT_BUTTON1 THEN
:SALARY:=NULL;
RAISE FORM_TRIGGER_FAILURE;
END IF;
END IF;
END;والآن الـ Trigger على الأزرار (BUTTON)
بعد ان تنشأ الزر تضغط على زر الماوس الأيمن طبعا وانت تقف على الزر وتختار WHEN-BUTTON-PRESSED وتكتب الكود
عند تريد ان تمسح سجل. نقوم بإظهار رساله تقول : هل فعلا تريد مسح السجل (نعم/لا). عند اختيار نعم يمسح وعند اختيار لا يلغي العمليه.
DECLARE
chk_button Number;
BEGIN
GO_BLOCK('USER_INFO');
chk_button :=SHOW_ALERT('aldel');
IF chk_button = alert_button1 THEN
DELETE_RECORD;
COMMIT;
END IF;
END;حيث aldel هو اسم الـ ALERT
كذلك إظهار رساله قبل الخروج تقول : هل فعلا تريد الخروج (نعم/لا)
DECLARE
chk_button NUMBER;
BEGIN
chk_button :=show_alert('alexit');
IF chk_button = alert_button1 THEN
EXIT_FORM(NO_COMMIT);
END IF;
END;حيث : alexit اسم الـ ALERT .
إن شاء الله ان تكون قد وجدت فيها الفايده
ابو عبدالآله
اخي ابو عبدالآله
السلام عليكم ورحمة الله وبركاته
يوجد تحليل لمشروع خاص بالصيدليات في المشروع الاول في اوراكل الموجود في دروس في اوراكل
بداءت في بناء الforms للمشروع
بداءت بالادوية ثم الشركات والموردين والزبائن
وبعد ذلك بدات بالخزينة ولكن ظهرت لي بعض المشاكل التى لم اجد لها حل
الفكرة
تم تقسيم الform الى 2 bloks
block يحتوي على العناصر التالية
1-رقم الفاتورة 2-تاريخ الفاتورة 3-اسم الزبون (lov)
4-القيمة الاجمالية للفاتورة 5- نوع الفاتورة
والاخر يحتوى على جدول به الحقول التالية
1- تسلسل 2-رقم الدواء(lov) ـ3- اسم الدواء (display item)
4- الكمية 5- السعر (display item)
6-القيمة(display item)
طريقة العمل
عند حقل رقم الفاتورة اخترت key_next_item وكتبت الجمل التالية
كود
:inv_date :=sysdate;
go_item('inv_date');
وعند النوع اخترت key_next_item وكتبت
كود
go_item('cust_id');
وعندالحقل رقم الزبون اخترت key_next_item وكتبت الجمل
كود
go_item('med_id');
:text_med := :text_med + 1;
وعند حقل رقم الدواء اخترت key_next_item وكتبت
كود
go_item('qty');
وعند الكمية key_next_item
كود
declare
xx number;
begin
:display_price := :qty * :price;
xx := :display_price + xx;
:global.xx := xx;
:cash.d_inv_total := xx; -- لتجميع القيمة الاجمالية للفاتورة
next_record;
:dis_seq := :dis_seq + 1; --لاعطاء تسلسل للادوية
go_item('add_med'); end
add_med هذا buttom لاضافة دواء حتى يتم الرجوع الى رقم الدواء وهكذا
المشاكل التى اريد لها حل
القيمة الاجمالية للفاتورة لم تظهر
التسلسل للادوية بالفاتورة لم يظهر
عندما اريد تعديل كمية في الفاتورة وانا في مرحلة الادخال كيف يتم
للشرح اكثر
انا في اثناء الطلبية ادخلت عدة ادوية وكميتها واحد الادوية ارادنا تعديل الكمية فما العمل
اسف ان اطلت عليك يأخي ابو عبدالآله
وإن شاء الله الشرح واضح
السلام عليكم ورحمة الله
اخي محمد سؤالك لم يكن واضح حيث انني لااعرف الحقول المرتبطه بقاعدة البيانات من حقول العرض . ايضا لم تحدد هل تريد ان تجمع ويكون المجموع على الشاشه فقط ام تريدها في قاعدة البيانات .
لكن سوف اعطيك حلول وسوف تجد الأجابه بينها وان متأكد من ذلك ان شاء الله .
من قائمة خصائص للحقل اذهب الى CALCULATION
ثم CALCULATION MODE
واختار SUMMARY
ومن SUMMARY FUNCTION اختار SUM
ومن SUMMARIZED BLOCK اكتب اسم البلوك
ومن SUMMARIZED ITEM اكتب اسم الحقل الذي سوف يكون فيه المجموع
[C][F=Navy] =================[/F][/C]
BLOCK
(POST-QUERY)
:total:=:salary*12;
[C][F=Navy]===================[/F][/C]
من خصائص الحقل اذهب الى FORMULA واكتب
:S_ITEM.PRICE*:S_ITEM.QUANTITY
حاول ان تجرب من احد الأمثله السابقه وسوف يكون الحل
بالنسبه للعداد حاول ان تجرب الطريقه التي ذكرتها في الأمثله السابقه :
-DATA BLOCK-
عند الحدث (PRE-INSERT)
هذا المثال يقوم بوضع عداد تلقائي
select seq_emp.nextval into :s_emp.id from sys.dual;
حيث :
seq_emp : اسم العداد الذي انشأته مسبقا
nextval : القيمه التاليه
ولك تحياتي
ابو عبدالآله
هذا الموضوع مغلق.