delphi4arab منتديات دلفي للعرب

نسخة كاملة : كيفية التعامل مع الـ Trigger
أنت حالياً تتصفح نسخة خفيفة من المنتدى . مشاهدة نسخة كاملة مع جميع الأشكال الجمالية .
مرحبا

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

وفي الحدث Before Delete لجدول الاباء نكتب الامر التالي
كود :
Delete * From Table2 where Table2.Index=Table1.ID

لاحظ ان Table2 جدول الابناء والاخر جدول الاباء ويتم ربط السجلات ببعضها عن طريق المفتاح الفريد ID بالحق Index

وسوف نكمل مع عمليات الاضافة والتعديل
وهذا مثلا في قواعد البيانات مثل SQLITE او FIREBIRD او SQLSERVER وغيرها
يستخدم عبارة New وايضا Old للاشارة الى القيمة الجديدة او القديمة انظر للمثال التالي
كود :
UPDATE orders SET address = new.address WHERE customer_name = old.name;

new.address تعني قيمة الحقل الجديدة
old.name تعني القيمة القديمة للحقل Name
ونتيجة التنفيذ ستكون شئ مثل
كود :
UPDATE customers SET address = '[color=Red]1 Main St.[/color]' WHERE name = '[color=Red]Jack Jones[/color]';
انظر لمثال الاضافة هذا
كود :
INSERT INTO AUDIT(EMP_ID, ENTRY_DATE) VALUES (new.ID, datetime('now'));
لاحظ يتم اخذ قيمة الـ ID وتعني الرقم الجديد الذي نشاء من عملية الاضافة لادراجه في الحقل EMP_ID
بارك الله فيك اخي واصل
حسنا كنت اعتقد ان الشرح مبهم وغير واضح لتسرعي وطالما انتم مهتمون سنكمل ايضاً

الصيغة الكاملة للتترايقر ليست كما بالامثلة السابقة وانما كما بالشكل التالي :

PHP كود :
CREATE TRIGGER TEST_TRIG FOR TEST
 ACTIVE BEFORE INSERT POSITION 0
 
AS
 
begin
    
if (new.id is null) then
       
new.id=gen_id (GLOB_ID,1);
 
end 

ولكني تجاهلت البقية لان برامج انشاء قواعد البيانات تكتب ذلك عنك وتقدمه بشكل مرئي

بداية انظرو الى هذه الصورة

كود :
http://www.ibexpert.net/ibe/uploads/Doc/dmiles1347.gif

من برنامج ibexpert

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

لماذا القديمة والجديدة ...؟

لانها تقول Old.Salary أي القيمة القديمة بالسجل و New.salary تعني القيمة الجديدة التي ادخلها المستخدم .

اذا كانت لا تساوي فسيضيف سجل جديد بالجدول Salary History ومن الواضح انها المستخدم المسئول عن هذا التغيير وتاريخه والقيم المطلوبة

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

والاحداث هي اما قبل Before او بعد After وتستخدم مع Update وايضا Delete وكذلك Insert

اي قبل الاضافة او بعدها او قبل التحديث ام بعد والحذف كذلك


طبعا من هنا يمكنك اجراء ما تريد كاستدعاء اجراءات مخزنة او استعلامات .

ارسال متغيرات واستقبالها بشكل صيغة SQL عادية جدا
السلام عليكم

بارك الله فيك

PHP كود :
CREATE TRIGGER TEST_TRIG FOR TEST
 ACTIVE BEFORE INSERT POSITION 0
 
AS
 
begin
    
if (new.id is null) then
       
new.id=gen_id (GLOB_ID,1);
 
end 

كاظافة في حالة اردت الحصول على القيمة الحالية للـ generator (تقوم برفع العداد بقيمة 0 بدل 1) :
PHP كود :
CREATE TRIGGER TEST_TRIG FOR TEST
 ACTIVE BEFORE INSERT POSITION 0
 
AS
 
begin
    
if (new.id is null) then
       
new.id=gen_id (GLOB_ID, 0]);
 
end 

بهذه الطريقة يمكنك ان تعرف السجل القادم عن طريق اضافة 1 بعد استدعاء الكود السابق عن طريق stored procedure من خلال برنامجك اضف انك لن تهدر قيم الـ generator

FireBird لا يتوفر على الترقيم التلقائي بنفس مفهوم اكسس على سبيل المثال و انما يمكن تطبيق نفس المبدأ عن طريق عدادات تسمى generator او sequence و للتنويه اسمان يعنيان نفس الامر
generator = sequence قبل الاضافة ترفع قيمة العداد باستخدام Before Insert Trigger يعجبني تفكير FireBird Rolleyes

ان شاء الله افدتكم
شكرا أخ S.FATEH

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

واسمح لي ان اوضح بشكل مبسط لمن ربما يحتاج الى تفصيل قليل .

اغلب من يتعاملون مع الاكسس والذي عند انشاء حقل ترقيم تلقائي يقوم تلقائياً باضافة رقم الى الحقل مع كل سجل وهو نفس الشي ما يتحدث عنه الاخ S.FATEH فمولدات الارقام ترجع لنا رقماً متسلسل يمكن استخدامه في اي شئ وان كان منها اقتناص الحدث Before Insert لاضافة رقم الى الحقل المراد استخدامه كحقل ترقيم تلقائي .

كود :
if (new.id is null) then new.id=gen_id (GLOB_ID,1);

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

مع انني ارى ان هذا الشكل ايضاً صحيح

كود :
new.id=gen_id (GLOB_ID,1);

فطالما اننا بحالة الاضافة فبالتاكيد القيمة تساوي لا قيمة .

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

وبحال التعديل توجد العبارتين .

كما بحال الاضافة يمكن مراقبة القيم المدخلة كما بالشكل التالي :

كود :
if (trim(new.MNAME) is null or trim(new.MNAME) = '') then begin end

فاذا كانت القيمة فارغة ننفذ ما نريد ويكون مثل :

كود :
if (trim(new.MNAME) is null or trim(new.MNAME) = '') then begin exception EXCEE_MPTY; end

رفع استثناء يفيد بنوع الخطاء الذي حصل .

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

وهنا يعتبر كل شئ قد تم الغاءه او العملية برمتها .

ايضاً من الممكن ان تستعلم عن القيمة المدخلة هل هي مكررة ام لا

كود :
select count(MNAME) from T1 where MNAME = new.MNAME into NUM; if (NUM > 0) then begin exception EXCE_DOUBLE; end

فاذا كانت مكررة تم الغاء المهمة ورفع الاستثناء .

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

كود :
try except on E: Exception do [color=Red] ShowMessage(E.Message);[/color] end;

واظهار نص الرسالة

وبحال استخدمت متغيرات فيجب ان تعلن عنها كما بالشكل التالي :

كود :
as [color=Red]declare variable NUM integer;[/color] begin

بعد العبارة as يتم الاعلان عن المتغيرات

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

على كل حال

ما بقى الان الا الاجراءات المخزنة Procedure

انظرو الى هذا المثال هنا مثلا

كود :
begin select count(mname) from t1 where mname=:mname into num; end

لاحظ ان هناك بارامتر هو Mname وايضا Num

فالاول هو داخلي Input ويجب ان نرسلة عند استدعاء الاجراء

كمثال على ذلك

كود :
if (NEW_PROCEDURE(Trim(new.mname)) > 0) then begin exception NEW_EXCEPTION; end

حيث ان NEW_PROCEDURE هو اسم الاجراء

والبارامتر الثاني هو خارجي Output ويتم اسقبالة من الاجراء نفسه مثل الدوال Function

انظر للمثال السابق حيث نقراء القيمة فاذا كانت اكبر من 0 رفعنا الاستثناء
السلام عليكم

بارك الله فيك اخي يمكنك المواصلة ...

من يوافقني الرأي ان PSQL و طريقة كتابة الكود في الـ Firebird متأثرة بالـ c ام انه مجرد احساس خاص بي احب ان ارى مأيد لهذا الرأي Rolleyes
s.fateh كتب :السلام عليكم

بارك الله فيك اخي يمكنك المواصلة ...

من يوافقني الرأي ان psql و طريقة كتابة الكود في الـ firebird متأثرة بالـ c ام انه مجرد احساس خاص بي احب ان ارى مأيد لهذا الرأي Rolleyes


اجل انها كذلك على ما يبدو
ارغب ان اضيف تعقيب بسيط وهو ان حذف جدول الابناء كما شرحت سابقاً بهذا الشكل

إقتباس :Delete * From Table2 where Table2.Index=Table1.ID

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

الكثير يسألون كيف يكون ربط الجداول في قواعد البيانات مثل FireBird او Sqlite وغيرها ....!

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

وهنا يكون الربط اكثر اتساعاً فالمجال مفتوح امامك لتقوم بالعديد من العمليات في هذا الحدث