الانتقال إلى المحتوى
View in the app

A better way to browse. Learn more.

مجموعة مستخدمي أوراكل العربية

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

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

Featured Replies

بتاريخ:

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

للتوضيح مثلاً عندي 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
  • المشاهدات 6.9k
  • البداية
  • اخر رد

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

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

بتاريخ:

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

بتاريخ:

الزيادة والنقصان أو أي عملية حسابية تتم علي الجداول
أنصحك بأن لا تقوم بعمل التريجر علي الداتا بعمل حتي لاتقوم بزيادة الترافيك علي الداتا بيز
وكله يبقي علي الفورمز
لكن لو عايز تريجر علي الداتا بيز
تحدد وقت عمل التريجر بمعني 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

بتاريخ:

ملحقات الحل:

alfaris_net_1236876363.jpg

alfaris_net_1236876389.jpg

بتاريخ:
  • كاتب الموضوع

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

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

بتاريخ:
  • كاتب الموضوع

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

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

post-75354-1236908039_thumb.png

تم تعديل بواسطة sonic

بتاريخ:

الخطأ واضح بتعليمة السيليكت...بجملة Where ... عندك خطأ باسم العامود (ID)

بتاريخ:
  • كاتب الموضوع

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

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

بتاريخ:

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

desc BloodType;

بتاريخ:
  • كاتب الموضوع
ما بعرف بس الكومبايلر عم يقلك ما عم يلاقي عامود اسمو 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;
/

بتاريخ:
  • كاتب الموضوع

جزاك الله كل خير اخي TROYMAN وامدك بالصحة والعافية والعلم والدين وزادك من فضله اللهم امين :(

تم تعديل بواسطة sonic

بتاريخ:

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

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

بتاريخ:

شكراً لك أخي الكريم ... الفضل لله وحده ...

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

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

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

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

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

Account

Navigation

البحث

إعداد إشعارات المتصفح الفورية

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.