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

كيف وضع كود يقوم بحساب الزيادة والنقصان


sonic

Recommended Posts

السلام عليكم ورحمة الله وبركاته

للتوضيح مثلاً عندي Table يوجد به A و B

Table
A
B

مثلاً عند وضع قمية وعددها 1000 للجهة A سوف تكون الجهة A= 1000

وعند وضع 1500 للجهة B سوف تكون الجهة B=1500

،،
لنفرض سوف نقوم باضافة كمية اخرى ل A، والقيمة تساوي 2000
تصبح قيمة A=3000 لان تم جمع قيمة A القديمة +قيمة A الحديثة = المجموع الكلي

لنفرض اني سوف اخذ من قيمة A=500

اذاً سوف تساوي قيمة A=2500
وB لم نضف عليها اي شي جديد وهي B=1500

والمطلوب الذي اريد معرفته هل يمكن استخدام Trigger لكي اضيف قيمه لهم ويتم جمعها بصورة الية ؟اي ممكن الكود الذي يقوم بعمل هذه الطريقة وكيف استخدمه؟ جزاكم الله كل خير

وشكراً لكم

تم تعديل بواسطة sonic
رابط هذا التعليق
شارك

  • الردود 30
  • البداية
  • اخر رد

أكثر المشاركين في هذا الموضوع

  • sonic

    16

  • TROYMAN

    11

  • mohamed_shoair

    3

  • mustafagamiel

    1

أكثر المشاركين في هذا الموضوع

الصور المنشورة

السلام عليكم...
بالنسبة للزيادة إذا بدك ياها تتم بشكل ألي المفروض تحدد العملية يلي بدها تم فيها...
متى ستتم العملية الحسابية (الزيادة أو النقصان) ؟؟
و أين ستتم العملية الحسابية ؟؟

رابط هذا التعليق
شارك

الزيادة والنقصان أو أي عملية حسابية تتم علي الجداول
أنصحك بأن لا تقوم بعمل التريجر علي الداتا بعمل حتي لاتقوم بزيادة الترافيك علي الداتا بيز
وكله يبقي علي الفورمز
لكن لو عايز تريجر علي الداتا بيز
تحدد وقت عمل التريجر بمعني after & before
وتحديد العملية التي ستتم علي الداتا بيز insert / update / delete
ثم الكود الذي تريده

مثال توضيحي :
سوف أقوم بعمل تريجر يقوم بنسخ القيمة القديمة في الجدول والتي سيتم حذفها أو التعديل فيها إلي جدول آخر ( وذلك لمعرفة من يقوم بالتعديل في الداتا بيز )

وده مثال عليه :


create or replace trigger fr before delete on emp
for each row
begin insert into ks(empno,ename,sal) values(:old.empno,:old.ename,:old.sal);
end;
/
sho err;





هذا الكود سيقوم بعمل insert للقيمة القديمة في الجدول الذي نعمل عليه في حالة حذفها أو التعديل فيها إلي الجدول ( ks )
والسطر المكتوب فيه ( sho err; ) لإظار الأخطاء لو كانت هناك أخطاء في كود التريجر


لكن أنصحك مرة أخري بعمل التريجر علي الفورم وليس علي الداتا بيز

رابط هذا التعليق
شارك

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

رابط هذا التعليق
شارك

السلام عليكم...
بالنسبة للزيادة إذا بدك ياها تتم بشكل ألي المفروض تحدد العملية يلي بدها تم فيها...
متى ستتم العملية الحسابية (الزيادة أو النقصان) ؟؟
و أين ستتم العملية الحسابية ؟؟

وعليكم السلام ورحمة الله وبركاته

اخي الكريم ستتم عملية الزيادة عند اضافة قيمة، والنقصان تحدث عند اخذ قيمة اي حذف قيمة (مثل طريقة بنك الدم)

وجزاك الله كل خير على الرد اخي الكريم

اخي mohamed_shoair واخي mustafagamiel جزاكم الله كل خير
المشلكة انني لم استخدم الاوراكل فورمز سوف استخدم Asp.net

اشكركم جميعاً

وهذا هو ما اقصده الصورة فقط للتوضيح والفهم، والطريقة مثل طريقة بنك الدم تحتوي على عدة فصائل AB+and AB-and O-,and O+and so on

وانا اريد عند التبرع مثلاً لفصيلة AB+ الحجم 1000 بالليتر ويتم اضافة هذه القيمة الى AB+ ويمكن ان تزيد او تنقص عند ادخال او اخذ كميه بالليتر وكذلك بالنسبة للفصائل الاخرى

وهذه هي الصورة واتمنى اني استطعت التوضيح

post-75354-1236774692_thumb.png

وفقكم الله
رابط هذا التعليق
شارك

الأخ الفاضل مصطفي جميل
أنا لست ضد التريجر علي الداتا بيز لكن في حالة أن تكون الداتا بيز كبيرة وعليها شغل كتير ويوزرز كتير ينصح بتقليل التريجرز عليها لتقليل الترافيك عليها
لكن هناك تريجرز لازم تكون علي الداتا بيز . ولكن الأرجح أن تحاول تقليل التريجرز علي الـــ D B

ولك جزيل الشكر في تقبل كلامي ورأيي

رابط هذا التعليق
شارك

أما بخصوص الفورمز اللي هتكون asp.net

لست لي خبرة بهذا الموضوع لأن شغلي كله أوراكل فورمز

وممكن تسأل أحد المشرفين وهويدلك هتعمل إيه

واقبل تحياتي ( ياريت كان بإيدي مساعدتك ، لكن ما باليد حيلة )

رابط هذا التعليق
شارك

مقدر جهدك اخي الكريم بارك الله فيك :rolleyes:

ولكن لاتوجد طريقة استخدم فيها ال Trigger مثلما وضحها لي الاخ جزاه الله خير في حساب العمر بالموضوع السابق؟

اي اقصد استخدم ال trigger لحساب الزيادة والنقصان؟

تم تعديل بواسطة sonic
رابط هذا التعليق
شارك

السلام عليكم...
تفضل الحل حسب ما استطعت فهمه من السؤال...

klshe-bf270abb98.jpg

klshe-81b538ca49.jpg

create or replace trigger tri_BloodType
before insert on Operations
for each row
declare
Obalance number:=0;
Nbalance number:=0;
begin select Balance into Obalance from BloodType
where ID=:new.BloodTypeID;
if :new.OperationType='grant' then
Nbalance := Obalance +:new.QuantityPerLiter;
elsif  :new.OperationType='revoke' then
Nbalance := Obalance - :new.QuantityPerLiter;
if Nbalance<0 then
raise_application_error(-20210,'You try to revoke quantity greater than available');
end if;
end if;
update BloodType set Balance = Nbalance where ID=:new.BloodTypeID;
end;
/




SQL> insert into operations values(1,'hassan',1,'grant',1,sysdate)

1 row created.

SQL> insert into operations values(2,'ammar',1,'grant',1.5,sysdate);

1 row created.

SQL> insert into operations values(3,'fouad',2,'grant',0.5,sysdate);

1 row created.

SQL> insert into operations values(4,'abed',1,'revoke',2,sysdate);

1 row created.

SQL> select * from bloodtype;



ID BLOODTYPE               BALANCE
---------- -------------------- ----------
        1 AB+                          .5
        2 AB-                          .5

رابط هذا التعليق
شارك

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

ان شاء الله الآن ساجربه واخبرك بالنتائج

رابط هذا التعليق
شارك

لا اعرف ما السبب كتبت الكود لدي وقارنت النتائج مع نتائجك اقصد اي جدولي مثل جدولك باختلاف الاسماء، ولكن بعد ما حفظ ال Trigger اخبرني ان هناك خطأ بال Trigger

وهذا هو الكود واسفله الاخطاء التي ظهرت لي
ارسلته صورة لان لم يظهر بالصفحة

post-75354-1236908039_thumb.png

تم تعديل بواسطة sonic
رابط هذا التعليق
شارك

ولكن الاسم نقلته مثل ما هو في جدولي وحاولت التاكد من ذلك ولا يوجد اختلاف، هل من الممكن وجود مشكلة اخرى بجدول اخر ممكن ان تؤثر على هذا التريجر؟

شكرا على الرد اخي الكريم

رابط هذا التعليق
شارك

ما بعرف بس الكومبايلر عم يقلك ما عم يلاقي عامود اسمو ID بجدول BloodType
جرب نفذ هي التعليمة:
desc BloodType;


حاولت مسح ال ID ووضعت بدلا منه BLOOD_TYPE_ID (لا اعرف هل الذي عملته صح ام خطأ)

واصبحت التريجر سليمة الكود بالصورة
post-75354-1236940206_thumb.png


ولكن بعد ما ادخلت البيانات بجدول ال Operations اظهرت لي هذه الرسالة
post-75354-1236940176_thumb.png
اسف على كثرة الاسئلة والازعاج تم تعديل بواسطة sonic
رابط هذا التعليق
شارك

ولا يهمك..ما في مشكلة
الخطأ عندك بالسطر السادس عند أول If
شو قصدك بـالعامود Stauts_ID كأنك معرفو Number و المفروض يكون varchar2 تأكد من المشكلة و إذا ما مشي الحال حط كود إنشاء الجداول و كود الإدخال للجدول Operations

رابط هذا التعليق
شارك

شكراً لك اخي على تحملي، والسخاء النبيل منك

نجحت الطريقة مثلما وضحت لي، بفضل الله ثم بفضلك، جزاك الله كل خير وبارك فيك

ولدي سؤال اخر لو سمحتوا، وجداً محرج من كثرة الاسئلة

يمكن عمل طريقة حساب فيها الدم الذي لم يستخدم لمدة مثلاً 3 سنوان وما زال في المخزون اي عمل له مسح من قاعدة البيانات؟ لان كأني قرات ان الدم من الممكن ان تنتهي صلاحيته ولكن لا اعرف كم المدة؟

تم تعديل بواسطة sonic
رابط هذا التعليق
شارك

حاولت مع كود العمر وبدلا من قسمته على 12 استخدمت الضرب في 2

اي تاريخ اليوم*2 =التاريخ القادم

واستخدمته بهذه الصيغة ولكن لم ينجح :(

begin select trunc(months_between(PROCESS_DATE)*2) into :new.NEXTF from dual;
end;

تم تعديل بواسطة sonic
رابط هذا التعليق
شارك

اضفت في جدول ال Operations عامود جديد اسميته NextDate وهذا يقوم بضرب تاريخ العملية الحالية ب 2 لكي يحدد للمتبرع التبرع للشهر القادم (بعد مرور شهران)
وكتبت هذا ال Trigger للجدول ونجح

begin select trunc(ADD_MONTHS(SYSDATE,2)) into :new.NEXTDATE from dual;
end;



ولكن عند التبطيق في جدول ال Operation تفصل قاعدة البيانات ويحدث Disconnect لا اعرف لماذا ولا يتحقق الشرط :(

تم تعديل بواسطة sonic
رابط هذا التعليق
شارك

بالنسبة لحذف كميات الدم المنتهية الصلاحية باعتبار مدة الصلاحية 3 سنوات:

create or replace procedure pro_Exp
is
cursor cur is select * from operations where (sysdate-OperationDate)/360>3;
f boolean :=false;
begin for rec in cur loop
if f then
f:=true;
end if;
update BloodType set Balance=Balance-rec.QuantityPerLiter
where ID=rec.BloodTypeID;
delete from Operations where OperationID=rec.OperationID;
end loop;
commit;
end;
/



و لتنفيذ الكود كل يوم بشكل دوري نستخدم DBMS_SCHEDULE

begin dbms_scheduler.create_program(program_name => 'PRO_EXP_JOB',
program_type => 'STORED_PROCEDURE',
program_action => 'PRO_EXP',
enabled => true);
end;
/



begin dbms_scheduler.create_schedule('SCH_EXP_JOB',
start_date => sysdate + (1/1440),
repeat_interval => 'FREQ=DAILY');
end;
/



begin dbms_scheduler.create_job('JOB_Operations_EXP',
program_name => 'PRO_EXP_JOB',
schedule_name => 'SCH_EXP_JOB',
enabled => true);
end;
/

رابط هذا التعليق
شارك

بالنسبة للقيد الذي يحصر المتبرع من حيث عدد مرات التبرع (مرة واحدة كل شهرين)
لا داعي للحقل الذي قمت بإضافته , بل عدّل جسم التريجر ليصبح كالتالي:

create or replace trigger tri_BloodType
before insert on Operations
for each row
declare
Obalance number:=0;
Nbalance number:=0;
Mdate date;
Pcount number;
ID number;
begin select count(*) into Pcount from operations where Name=:new.Name;
/* if that person granted before*/
if Pcount>0 then
select BloodTypeID into ID from Operations where Name=:new.Name;
/* if that person's Blood type is matched*/
if ID!=:new.BloodTypeID then
raise_application_error(-20212,'You try to Grant more than type of Blood!');
end if;
select Max(OperationDate) into Mdate from Operations 
where Name=:new.Name;
/* if that person's last granting date is greater than 2 months*/
if (sysdate-Mdate)/30<2 then
raise_application_error(-20211,'You can'||'t grant again before passing two months at least');
end if;
else
select Balance into Obalance from BloodType
where ID=:new.BloodTypeID;
if :new.OperationType='grant' then
Nbalance := Obalance +:new.QuantityPerLiter;
elsif  :new.OperationType='revoke' then
Nbalance := Obalance - :new.QuantityPerLiter;
if Nbalance<0 then
raise_application_error(-20210,'You try to revoke quantity greater than available');
end if;
end if;
update BloodType set Balance = Nbalance where ID=:new.BloodTypeID;
end if;
end;
/

تم تعديل بواسطة TROYMAN
رابط هذا التعليق
شارك

ما شاء الله تبارك الله العلي العظيم

أغرقتنا بكرمك اخي الكريم

اسال الله العظيم رب العرش العظيم ان يوفقك دنيا واخرة بما يحبه ويرضاه ويرزقك من فضله كل خير اللهم امين

تم تعديل بواسطة sonic
رابط هذا التعليق
شارك

انضم إلى المناقشة

يمكنك المشاركة الآن والتسجيل لاحقاً. إذا كان لديك حساب, سجل دخولك الآن لتقوم بالمشاركة من خلال حسابك.

زائر
أضف رد على هذا الموضوع...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   تمت استعادة المحتوى السابق الخاص بك.   مسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

جاري التحميل



×
×
  • أضف...

برجاء الإنتباه

بإستخدامك للموقع فأنت تتعهد بالموافقة على هذه البنود: سياسة الخصوصية