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

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

صورة
- - - - -

عمل كيرسو لتحديث الراتب


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

#1 awn78

awn78

    عضو نشط

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

تاريخ المشاركة 20 May 2008 - 11:57 AM

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

اريد عمل كيرسر لزيادة رواتب الموظفين بشرط اذا كان الراتب اكبر من 3000 فيتم زيادتهم ب 8% اما اذا اقل فيتم زيادتهم ب 10% على جدول ال emp في اليوزر scott


وشكر




وفقكم الله جميعا
صورة

#2 weloooo

weloooo

    مشرف

  • فريق الإشراف
  • 249 مشاركة
  • البـلـد: Country Flag

تاريخ المشاركة 20 May 2008 - 10:37 PM

السالم عليكم.

هناك طريقتين لعمل هذا :
الأولى: بإستخدام ال explicit cursor ومعه ال for loop.
الثانيه: بإستخدام ال implicit cursor وبإستخدام ال bulk collect وال forall loop (ينصح بها).

إن الطريقه الأولى (التقليديه) تنفذ ما تريده ولا تشكل فارق كبير بينها وبين الطريقه الثانيه إذا كان عدد الصفوف التي سوف تحدثها قليله (كما في مثالك) ولكن إذا كانت عدد الصفوف كبيره جداً (مثلاً 50000 صف) فمن المستحسن إستخدام الطريقه الثانيه لأن كفاءتها أعلى ولا تأخذ وقتاً في التنفيذ مثل الأولى.

أما الثانيه فتتضح فوائدها من شرح الأولى من زيادة الكفاءه حيث ان عملية الfetching تحدث مره واحده لكل الصفوف ولكن الأول تحدث مره لكل صف (تحدث 50 الف مره لكل 50 ألف صف !) . كذلك الطريقه الثانيه تستخدم ال implicit cursor والذي في أغلب الأحوال أفضل من ال explicit cursor (فعلاً !)

لتلاحظ الفرق أكتب هذا الأمر :

set timing on

إضغط Enter

الطريقه الأولى:

declare
cursor my_curs is select empno,sal
from emp; begin for i in my_curs loop
if i.sal>3000
then
update emp
set sal=i.sal+((i.sal/100)*8)
where empno=i.empno;
else
update emp
set sal=i.sal+((i.sal/100)*10)
where empno=i.empno;
end if;
end loop;
end;


أما الطريقه الثانيه (كبيره لكنها أحسن بكثير):

declare
type sal_table is table of emp.sal%type index by pls_integer;
type empid_table is table of emp.empno%type index by pls_integer;
my_empid empid_table;
my_empid2 empid_table;
my_sal2 sal_table;
my_sal sal_table;
begin select empno,sal bulk collect into my_empid,my_sal from emp
where sal>3000;
select empno,sal bulk collect into my_empid2,my_sal2 from emp
where sal<3000;
forall indx in my_empid.first .. my_empid.last
update emp
set sal=sal+((sal/100)*8)
where empno=my_empid(indx);
forall indx in my_empid2.first .. my_empid2.last
update emp
set sal=sal+((sal/100)*10)
where empno=my_empid2(indx);
end;


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

أحمد يحيى


Oracle Apps Senior Technical Consultant


#3 awn78

awn78

    عضو نشط

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

تاريخ المشاركة 20 May 2008 - 10:51 PM

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

emp_ec my_curs;

بعد اذنك طبعا
صورة

#4 weloooo

weloooo

    مشرف

  • فريق الإشراف
  • 249 مشاركة
  • البـلـد: Country Flag

تاريخ المشاركة 20 May 2008 - 11:31 PM

متشكر على كلامك الذوق جداً. كلامك صحيح ولكن هذا في حالة ما إذا كنت ستستخدم ال basic loop أما في حالة ال for loop فيتم تعريف الكيرسر أثناء كتابة جملة ال for loop


for i in my_curs loop


في هذا المثال فإن ال " i " هو ال variable الذي سوف يتعامل مع البيانات الموجوده في الكيرسر. لاحظ أني إستخدمت المتغير " i " في جملة التحديث :


if i.sal>3000
then
update emp
set sal=i.sal+((i.sal/100)*8)
where empno=i.empno;


عند إستخدام ال for loop فإنك غير مضطر لفتح الكيرسر وغلقه وكذلك تعريف متغير من نوع الكيرسر في جزء ال declare وعمل خطوة ال fetch من الكيرسر إليه.


وفقك الله...................

أحمد يحيى


Oracle Apps Senior Technical Consultant


#5 Slamonty

Slamonty

    عضو

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

تاريخ المشاركة 23 May 2008 - 02:05 PM

جزاك الله كل الخير ايها الاخ الكريم احمد يحيي
لا إله إلا الله وحده لا شريك له له الملك و له الحمد يحيي و يميت و هو علي كل شيء قدير

#6 hossam160

hossam160

    عضو نشط

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

تاريخ المشاركة 19 June 2008 - 06:14 AM

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

حمل مواد تعليمية للأوركل فيديو


http://www.mediafire.../?frl5nakibiejr


رضينا بالديفولبر والديفولبر مشراضى بينا


ارفع ملفاتك مع اسرع موقع للرفع والتحميل فى نفس الوقت

صورة


#7 mostafa_fa

mostafa_fa

    عضو

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

تاريخ المشاركة 28 June 2008 - 12:32 AM

السلام عليكم

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

الثانيه: بإستخدام ال implicit cursor وبإستخدام ال bulk collect وال forall loop (ينصح بها).

الطريقة الثانية جميلة جدا ولكن اعتقد ليس اسمها implicit cursor ولكنها عباره عن جدول باستخدام الفهرس ويكون عباره عن حقلين
حقل به الفهرس والثاني اي نوع تحدده انت ويطلق عليه اسم Index by table
ويفضل ان يكون Index نوعه Pls_integer

فعلا عامل الوقت مهم جدا جدا
وشكرا مرة اخرى اخي الكريم
الحمد لله الذي هدانا لهذا وما كنا لنهتدي لولا ان هدانا الله


صورة