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

كيفية عمل تحديث Update لجدولين واخراج نتيجة باستخدام Pl/sql


‫وردة حمراء‬‎

Recommended Posts

السلام عليكم .. مطلوب مني اختيار اسماء العاملين ورواتبهم وارقامهم من جدول emp وقد فعلت ذلك باستخدام cursor . سؤالي كيف احدث هذا الجدول لكي يخرج اسماء العاملين مع اقسام العمل والمنطقه من جدول dept ؟ يجب علي ان اعمل join بين الجدولين ثم يمكنني ان اخرج الناتج صحيح ؟ 

 

 

اول جدول  emp :

(empno,ename,job,MGR,hiredate,sal,comm,deptno);

ثاني جدول  DEPT:

(deptno,dname,loc)

 

 

وهذا الجدول الذي اريده  

 

 

 

eName, deptno,loc,empno,sal

 

 

     

 

 

هذا حلي :

set serveroutput on;

DECLARE

  CURSOR staff_cursor IS

    SELECT ename, empno,sal from emp;

  v_lname emp.ename%type;

  v_dob emp.empno%type;

  v_lna emp.sal%type;

BEGIN     

  DBMS_OUTPUT.PUT_LINE ('******************');

  OPEN staff_cursor;

  FETCH staff_cursor into v_lname, v_dob ,v_lna;

  WHILE staff_cursor%found LOOP

     DBMS_OUTPUT.PUT_LINE (v_lname);

     DBMS_OUTPUT.PUT_LINE (v_dob);

     DBMS_OUTPUT.PUT_LINE (v_lna);

     DBMS_OUTPUT.PUT_LINE ('******************');

     FETCH staff_cursor into v_lname, v_dob,v_lna;

  END LOOP;

  CLOSE staff_cursor;

END; 

 

 

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

 

Cursor emp_cursor IS select ename, empno,sal,loc,dname

From emp e,dept d

          WHERE e.deptno=d.deptno

For update

Begin

For emp_up IN emp_cursor LOOP

Update emp

Set

DBMS_OUTPUT.PUT_LINE (ename);

     DBMS_OUTPUT.PUT_LINE (dname);

      DBMS_OUTPUT.PUT_LINE (loc);

     DBMS_OUTPUT.PUT_LINE ('******************');

 

End loop;

End;

 

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

انت كده الدنيا بايظة خالص عندك يا باشا

مبدأيا , اقرأ عن الكرسورز عموما واستعمل احسن cursor for loop 

اول مشكلة علي حلك انت

DECLARE

  CURSOR staff_cursor IS

    SELECT ename, empno,sal from emp;

  v_lname emp.ename%type;

  v_dob emp.empno%type;

  v_lna emp.sal%type;

BEGIN     

  DBMS_OUTPUT.PUT_LINE ('******************');-- ده مش عارف لزمته ايه !!

OPEN staff_cursor;

loop

  FETCH staff_cursor into v_lname, v_dob ,v_lna;

  exit when staff_cursor%notfound

     DBMS_OUTPUT.PUT_LINE (v_lnam || v_dob || v_Ina) ;

end loop ;

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

والكود التاني ده انت معملتش فيه update اصلا .

انت عارف for update دي بتاعت ايه ؟

وانت طابع حاجات ليه لما انت بتعمل update

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

انت كده الدنيا بايظة خالص عندك يا باشا

مبدأيا , اقرأ عن الكرسورز عموما واستعمل احسن cursor for loop 

اول مشكلة علي حلك انت

DECLARE

  CURSOR staff_cursor IS

    SELECT ename, empno,sal from emp;

  v_lname emp.ename%type;

  v_dob emp.empno%type;

  v_lna emp.sal%type;

BEGIN     

  DBMS_OUTPUT.PUT_LINE ('******************');-- ده مش عارف لزمته ايه !!

OPEN staff_cursor;

loop

  FETCH staff_cursor into v_lname, v_dob ,v_lna;

  exit when staff_cursor%notfound

     DBMS_OUTPUT.PUT_LINE (v_lnam || v_dob || v_Ina) ;

end loop ;

 

 

أهلا .. هل يوجد فرق بين Loops  ؟والترتيب ؟  الكود يعمل لدي بشكل صحيح . 

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

والكود التاني ده انت معملتش فيه update اصلا .

انت عارف for update دي بتاعت ايه ؟

وانت طابع حاجات ليه لما انت بتعمل update

اعرف طريقة التحديث  update table

                                            set columns

 

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

 

 

   Update the PL/SQL code of the  query to include after each employee the department name and location

 

eName, deptno,loc,empno,sal

 

بهذا الشكل 

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

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

 

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

 

عندك خيارين اما انشاء view عن طريقها اجيب معلومات العاملين او عمل جملة select بسيطة 

 

الخيار الاول

CREATE OR REPLACE FORCE VIEW EMP_DETAILS_VIEW
(
   empno,
   ename,
   deptno,
   dname, 
   loc,
   sal
)
   AS
   SELECT empno,
   e.ename,
   d.deptno,
   d.dname,
   e.loc,
   e.sal
     FROM emp e,
          dept d
    Where     e.deptno = d.deptno 	;

ومن ثم يتم الاستعلام عن معلومات الموظف عن طريق جملة السيليكت التالية

لاستعراض البيان حسب رقم الموظف

select * from VIEW EMP_DETAILS_VIEW
where empno=:v_empno

or

لاستعراض جميع بيانات الموظفين

select * from VIEW EMP_DETAILS_VIEW

الخيار الثاني

SELECT empno,
   e.ename,
   d.deptno,
   d.dname,
   e.loc,
   e.sal
     FROM emp e,
          dept d
    Where     e.deptno = d.deptno 	;
رابط هذا التعليق
شارك

 

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

 

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

 

عندك خيارين اما انشاء view عن طريقها اجيب معلومات العاملين او عمل جملة select بسيطة 

 

الخيار الاول

CREATE OR REPLACE FORCE VIEW EMP_DETAILS_VIEW
(
   empno,
   ename,
   deptno,
   dname, 
   loc,
   sal
)
   AS
   SELECT empno,
   e.ename,
   d.deptno,
   d.dname,
   e.loc,
   e.sal
     FROM emp e,
          dept d
    Where     e.deptno = d.deptno 	;

ومن ثم يتم الاستعلام عن معلومات الموظف عن طريق جملة السيليكت التالية

لاستعراض البيان حسب رقم الموظف

select * from VIEW EMP_DETAILS_VIEW
where empno=:v_empno

or

لاستعراض جميع بيانات الموظفين

select * from VIEW EMP_DETAILS_VIEW

الخيار الثاني

SELECT empno,
   e.ename,
   d.deptno,
   d.dname,
   e.loc,
   e.sal
     FROM emp e,
          dept d
    Where     e.deptno = d.deptno 	;

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

 

شكرا للتوضيح .. جزاك الله  خيرا .. هل يمكن ان نستخدم cursor  لل update ? 

تم تعديل بواسطة ‫وردة حمراء‬‎
رابط هذا التعليق
شارك

وعليكم السلام طبعا يمكن استخدامها

 

مثال على ذلك

Option 1: Bulk update using FORALL.

DECLARE
  TYPE TBL IS TABLE OF DEPT%ROWTYPE INDEX BY PLS_INTEGER;
  CURSOR C
  IS
  SELECT * FROM DEPT WHERE LOC = 'NEW YORK';
  lTbl TBL;
BEGIN
  OPEN C;
  LOOP
    FETCH C BULK COLLECT INTO lTbl LIMIT 100;
    
    FORALL I IN 1..lTbl.count
      UPDATE EMP
         SET SAL = SAL+SAL*.01
       WHERE DEPTNO = lTbl(i).DEPTNO;

    EXIT WHEN C%NOTFOUND;
  END LOOP;
  CLOSE C;
END;
/

Option 2: Update using implicit cursor (From 10g on oracle does a array fetch of 100 with implicit cursor)

BEGIN
  FOR I IN (SELECT * FROM DEPT WHERE LOC = 'NEW YORK')
  LOOP
    UPDATE EMP
       SET SAL = SAL+SAL*.01
     WHERE DEPTNO = I.DEPTNO;
  END LOOP;
END;
/

Option 3: The oldest and the dead one (Row by Row update)

DECLARE
  CURSOR C
  IS
  SELECT * FROM DEPT WHERE LOC = 'NEW YORK';

  REC C%ROWTYPE;
BEGIN
  OPEN C;

  LOOP
     FETCH C INTO REC;

     EXIT WHEN C%NOTFOUND;

     UPDATE EMP
        SET SAL = SAL+SAL*.01
      WHERE DEPTNO = REC.DEPTNO;

  END LOOP;

  CLOSE C;
END;
/ 
تم تعديل بواسطة أسامة موسى
رابط هذا التعليق
شارك

 

وعليكم السلام طبعا يمكن استخدامها

 

مثال على ذلك

Option 1: Bulk update using FORALL.

DECLARE
  TYPE TBL IS TABLE OF DEPT%ROWTYPE INDEX BY PLS_INTEGER;
  CURSOR C
  IS
  SELECT * FROM DEPT WHERE LOC = 'NEW YORK';
  lTbl TBL;
BEGIN
  OPEN C;
  LOOP
    FETCH C BULK COLLECT INTO lTbl LIMIT 100;
    
    FORALL I IN 1..lTbl.count
      UPDATE EMP
         SET SAL = SAL+SAL*.01
       WHERE DEPTNO = lTbl(i).DEPTNO;

    EXIT WHEN C%NOTFOUND;
  END LOOP;
  CLOSE C;
END;
/

Option 2: Update using implicit cursor (From 10g on oracle does a array fetch of 100 with implicit cursor)

BEGIN
  FOR I IN (SELECT * FROM DEPT WHERE LOC = 'NEW YORK')
  LOOP
    UPDATE EMP
       SET SAL = SAL+SAL*.01
     WHERE DEPTNO = I.DEPTNO;
  END LOOP;
END;
/

Option 3: The oldest and the dead one (Row by Row update)

DECLARE
  CURSOR C
  IS
  SELECT * FROM DEPT WHERE LOC = 'NEW YORK';

  REC C%ROWTYPE;
BEGIN
  OPEN C;

  LOOP
     FETCH C INTO REC;

     EXIT WHEN C%NOTFOUND;

     UPDATE EMP
        SET SAL = SAL+SAL*.01
      WHERE DEPTNO = REC.DEPTNO;

  END LOOP;

  CLOSE C;
END;
/ 

شكرا ..مفهوم :)

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

سؤال أخير .

أريد أن انشا جدول جديد باتربوت من جدول اخر ثم عمل cursor لايجاد العمال الذين يعملون ك  ‘CLERK’

 

  create a table named ‘NewTable’ and populate it with all employees in EMP relation whose job title is ‘CLERK’. Use a cursor to display the employees who have been selected.

 

 

 محاولتي ..

 

create table Newtable1 (empno, ename,job,mgr,hiredate, sal,comm,deptno ) AS (select empno, ename,mgr,hiredate, sal,comm,deptno from emp);

 

set serveroutput on;
DECLARE
  CURSOR staff_cursor IS
    SELECT ename, empno,sal,job,mgr,hiredate,comm,deptno from Newtable1 where job='CLERK';
  v_lname emp.ename%type;
  v_dob emp.empno%type;
  v_lna emp.sal%type;
  v_job emp.job%type;
  v_mgr emp.mgr%type;
  v_hiredate emp.hiredate%type;
  v_comm emp.comm%type;
  v_deptno emp.deptno%type;
  
BEGIN
  DBMS_OUTPUT.PUT_LINE ('******************');
  OPEN staff_cursor;
  FETCH staff_cursor into v_lname, v_dob ,v_lna,v_job,v_mgr,v_hiredate,v_comm,v_deptno;
  WHILE staff_cursor%found LOOP
     DBMS_OUTPUT.PUT_LINE (v_lname);
     DBMS_OUTPUT.PUT_LINE (v_dob);
     DBMS_OUTPUT.PUT_LINE (v_lna);
     DBMS_OUTPUT.PUT_LINE (v_job);
     DBMS_OUTPUT.PUT_LINE (v_mgr);
     DBMS_OUTPUT.PUT_LINE (v_hiredate);
     DBMS_OUTPUT.PUT_LINE (v_comm);
     DBMS_OUTPUT.PUT_LINE (v_deptno);
     FETCH staff_cursor into v_lname, v_dob,v_lna,v_job,v_mgr,v_hiredate,v_comm,v_deptno;
  END LOOP;
  CLOSE staff_cursor;
END;
تم تعديل بواسطة ‫وردة حمراء‬‎
رابط هذا التعليق
شارك

انت كده مش هتوصل لحاجة ولو بعد سنتين حتي .

نصيحة : ذاكر ( بطريقة منظمة ) .

عايز تربط , يبقى تذاكر JOINS

عايز تعمل كرسور يبقى تذاكره وهكذا .

لكن كده هتيجي تبص بعد سنتين هتلاقى نفسك مستواك ضعيف جدا وهيبقى صعب تلاقى شغل .

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

انت كده مش هتوصل لحاجة ولو بعد سنتين حتي .

نصيحة : ذاكر ( بطريقة منظمة ) .

عايز تربط , يبقى تذاكر JOINS

عايز تعمل كرسور يبقى تذاكره وهكذا .

لكن كده هتيجي تبص بعد سنتين هتلاقى نفسك مستواك ضعيف جدا وهيبقى صعب تلاقى شغل .

 

أكيد مستواي ضعيف بدات قبل 4 ايام .لا باس مع المستقبل ان شاء الله اتطور .

 

 

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

800
SMITH
CLERK
20

 

set serveroutput on;
DECLARE
  CURSOR staff_cursor IS
    SELECT name,job,deptno  from Newtable1 where job='CLERK';
  v_lname staff_cursor %rowtype;
BEGIN
  DBMS_OUTPUT.PUT_LINE ('******************');
  OPEN staff_cursor;
  FETCH staff_cursor into v_lname;
  WHILE staff_cursor%found LOOP
     DBMS_OUTPUT.PUT_LINE (v_lname.name);
    DBMS_OUTPUT.PUT_LINE (v_lname.job);
         DBMS_OUTPUT.PUT_LINE (v_lname.deptno);
 
  END LOOP;
  CLOSE staff_cursor;
END;
تم تعديل بواسطة ‫وردة حمراء‬‎
رابط هذا التعليق
شارك

برده نفس الغلطة الي صلحتهالك قبل كده بتاعت الـ FETCH

اقرأ عن الكرسورز كويس

 

- انا بتكلم علي طريقة المذاكرة مش المدة , لو هتمشي بالطريقة دي مش هتوصل لحاجة حتي ولو بعد مدة طويلة

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

برده نفس الغلطة الي صلحتهالك قبل كده بتاعت الـ FETCH

اقرأ عن الكرسورز كويس

 

- انا بتكلم علي طريقة المذاكرة مش المدة , لو هتمشي بالطريقة دي مش هتوصل لحاجة حتي ولو بعد مدة طويلة

 

الحمد لله عرفت . صح هالطريقة لانشاء جدول newtable . create table Newtable1 (empno, ename,job,mgr,hiredate, sal,comm,deptno ) AS (select empno, ename,mgr,hiredate, sal,comm,deptno from emp);   بحيث يكون   populate it with all employees in EMP relation ؟؟؟؟

 

set serveroutput on;
DECLARE
  CURSOR staff_cursor IS
    SELECT * from Newtable1 where job='CLERK';
  v_lname staff_cursor%rowtype;
BEGIN
  DBMS_OUTPUT.PUT_LINE ('******************');
  OPEN staff_cursor;
  Loop
  FETCH staff_cursor into v_lname;
  exit when staff_cursor%notfound;
     DBMS_OUTPUT.PUT_LINE (v_lname.name);
    DBMS_OUTPUT.PUT_LINE (v_lname.job);
    DBMS_OUTPUT.PUT_LINE (v_lname.deptno);
    DBMS_OUTPUT.PUT_LINE (v_lname.comm);
    DBMS_OUTPUT.PUT_LINE (v_lname.salary);
    DBMS_OUTPUT.PUT_LINE (v_lname.empno);
    DBMS_OUTPUT.PUT_LINE (v_lname.mgr);
    DBMS_OUTPUT.PUT_LINE (v_lname.hiredate);
DBMS_OUTPUT.PUT_LINE ('******************'); 
  END LOOP;
  CLOSE staff_cursor;
END;
 
 
anonymous block completed
******************
SMITH
CLERK
20
 
800
7369
7902
17/12/80
******************
ADAMS
CLERK
20
 
1100
7876
7788
12/01/83
******************
JAMES
CLERK
30
 
950
7900
7698
03/12/81
******************
MILLER
CLERK
10
 
1300
7934
7782
23/01/82
******************
رابط هذا التعليق
شارك

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

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

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

×   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.

جاري التحميل
×
×
  • أضف...

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

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