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

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

صورة
- - - - -

لغز أواكلي كيف يمكنك من procedure و عن طريق الsql


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

#1 undo

undo

    مشترك

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

تاريخ المشاركة 12 January 2005 - 02:42 AM

السلام عليكم

حالياً اقوم بدراسة الاوراكل و بدأت مؤخراً في الPL/SQL و ووجدت انه على عكس الSql لا يمكنك استخدام الselect للحصول على اكثر من row واحد فحسب,, لو عايز اكثر من row فعليك استخدام الcursor

اللغز
كيف يمكنك من procedure و عن طريق السيكول و بدون الcursors عرض جميع الصفوف في جدول؟؟
مثال: عرض اسماء الموظفين في جدول scott.emp

تم تغيير عنوان الموضوع ليدل على محتواه , راجع شروط الكتابه في المتندي
إداره المنتدي


#2 AdNaN

AdNaN

    عضو

  • الأعضــاء
  • 29 مشاركة
  • الاسم الأول:Adnan
  • اسم العائلة:BaHatheq
  • البـلـد: Country Flag

تاريخ المشاركة 12 January 2005 - 10:27 AM

<span style='font-family:Traditional Arabic'></span>

بسم الله الرحمن الرحيم


حقيقة أخ UNDO وحسب معلوماتي المتواضعه فأنة يمكنك الحصول على اكثر من ROW باستخدام Select في داخل الفورم
ولكن المشكلة تكمن في انه كيف يمكننا أخبار الديفيلوبر ان يأخذ كل Row ثم يضعه في سجل على الشاشة تابع ل بلوك ما.
ثم يأتي بال Row الثاني ويضعه في السجل الثاني في نفس البلوك ... وهكذا
لحل هذه المشكلة فاننا نحتاج هنا لاستخدام cursor حيث سيقوم هذاcursor بارجاع one Row في كل مرة
وحتى نضع Row ألثاني في السجل الثاني في البلوك
فاننا نستخدم الأمر Next_Record في هذا البلوك

أعتقد أصبحت النقطة واضحه الأن :rolleyes:

#3 Osama Soliman

Osama Soliman

    مشرف سابق وعضو مميز

  • المجموعة الماسية
  • 1,611 مشاركة
  • الاسم الأول:Osama
  • اسم العائلة:Soliman
  • البـلـد: Country Flag
  • المنصب الحالي:Oracle Technical Consultant - Asfour Crystal International

تاريخ المشاركة 12 January 2005 - 04:59 PM

create or replace procedure print_all_emp
is
v_count number :=0;
v_id s_emp.id%type;
v_last_name s_emp.last_name%type;
begin
select count(*)
into v_count
from s_emp;
for i in 1..v_count loop
select id, last_name
into v_id, v_last_name
from s_emp
where id = i;
dbms_output.put_line(v_id ||' '||v_last_name);
end loop;
end;
/

تم التعديل بواسطة Osama Soliman, 12 January 2005 - 05:31 PM.

وقل رب زدنى علماً
Osama M. Soliman
Oracle Certified Professional
Oracle Technical Consultant

 Asfour Crystal International
Cairo - Egypt
Osama.Soliman@hotmail.com
Osama.Soliman@asfourcystal.com


#4 Amgad

Amgad

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

  • الفريق الإداري
  • 4,558 مشاركة
  • الاسم الأول:امجد
  • اسم العائلة:حلمي
  • البـلـد: Country Flag
  • المنصب الحالي:Business Systems Analyst at al Fanar Co. Riyadh KSA

تاريخ المشاركة 12 January 2005 - 09:18 PM

السلام عليكم ،،
الأخ / اسامه
شكرا على المثال .. واسترجاع بيانات الجدول يعتمد على رقم الموظف وبافتراض ان ارقام الموظفين فى تسلسل مستمر اى ( 1-2-3-4-5 ) ولكن فى حالة عدم وجود موظف رقم 3 مثلا .. فلن ترجع بيانات للمسلسل رقم 3 ..

اعتقد انه لن يمكن تنفيذ هذا الامر مع جدول emp فى scott لان ارقام الموظفين غير مسلسله ..

اي بمعنى اخر .. اذا كان البحث من جدول ليس به ارقام مسلسله مثل رقم الموظف .. فما هو الحل ؟؟

شكرا لك مقدما

تم التعديل بواسطة Amgad, 12 January 2005 - 09:22 PM.

لا إله إلا الله الحليم الكريم
لا اله إلا الله العلى العظيم
لا اله إلا الله رب السماوات السبع و رب العرش العظيم
‏اللهم ارزقني قبل الموت توبة وعند الموت شهادة وبعد الموت جنة
اللهم ارزقني حسن الخاتمة
اللهم هون علينا سكرات الموت ... ونور علينا قبورنا
اللهم ارزقني الموت وأنا ساجد لك يا ارحم الراحمين
اللهم ثبتني عند سؤال الملكين
اللهم اجعل قبري روضة من رياض الجنة ولا تجعله حفرة من حفر النار
اللهم اني اعوذ بك من فتن الدنيا
اللهم ارحم ابائنا وامهاتنا واغفر لهما وتجاوز عن سيئاتهما وادخلهم فسيح جناتك ... والحقنا بهما يا رب العالمين
اللهم ارحم موتانا وموتى المسلمين واشفي مرضانا ومرضى المسلمين
اللهم اغفر للمسلمين والمسلمات والمؤمنين والمؤمنات الأحياء منهم والأموات
وبارك اللهم على سيدنا محمد صلى الله عليه وسلم
اللهم آمين ... اللهم آمين ... اللهم آمين


....


#5 h_elshawaf

h_elshawaf

    مشترك

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

تاريخ المشاركة 12 January 2005 - 09:57 PM

عن طريق الـ cursor for loop

create or replace procedure print_all_emp
is
begin
for i_rec in (select id, last_name
from s_emp) loop
dbms_output.put_line(i_rec.id||' '||i_rec.last_name);
end loop;
end;
/

أدرى بأن هناك فجرا .. وأن بعد العسر يسرا
لكنهم ساموا الفتى وبلاده عسفا وقهرا
والعالم الحيران يشهد ما يحل بأمتى
وأنا هنا .. فى غربتى .. فى لوعتى
أبكى وأمسح فى ذهول دمعتى
وأظل أنظر للسماء .. والقلب يخفق بالدعاء
يارب .. أوقظ أمتى


متى يبلغ البنيان يوما تمامه
إذا كنت تبنيه وغيرك يهدمه
لو كان سهما واحدا لإتقيته
ولكنه سهم وثان وثالث

#6 undo

undo

    مشترك

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

تاريخ المشاركة 12 January 2005 - 11:13 PM

فأنة يمكنك الحصول على اكثر من ROW باستخدام Select في داخل الفورم
ولكن المشكلة تكمن في انه كيف يمكننا أخبار الديفيلوبر ان يأخذ كل Row ثم يضعه في سجل على الشاشة تابع ل بلوك ما.
ثم يأتي بال Row الثاني ويضعه في السجل الثاني في نفس البلوك ... وهكذا
لحل هذه المشكلة فاننا نحتاج هنا لاستخدام cursor حيث سيقوم هذاcursor بارجاع one Row في كل مرة
وحتى نضع Row ألثاني في السجل الثاني في البلوك

و الله انا ذو المعلومات المتواضعة :rolleyes:
انا لا ادري شيئاً عن الاوراكل فورمز و لكني تكلمت من خلال علمي البسيط في الpl/SQL .. المطلوب هو STORED PROCEDURE

اخي اسامة::
كلام امجاد سليم للغاية.. انا ابحث عن كود ينفع مع اي جدول و بدون الاعتماد حتى على أي حقل في الجدول..

أخي الشواف:
:D :D :ph34r: برضه استخدمت CURSOR رغم انه IMPLICIT ..

#7 Osama Soliman

Osama Soliman

    مشرف سابق وعضو مميز

  • المجموعة الماسية
  • 1,611 مشاركة
  • الاسم الأول:Osama
  • اسم العائلة:Soliman
  • البـلـد: Country Flag
  • المنصب الحالي:Oracle Technical Consultant - Asfour Crystal International

تاريخ المشاركة 13 January 2005 - 01:36 AM

اخى امجد
فعلاً كلام صحيح مائة بمائة
والمفروض فى هذه الاحوال استخدام Cursor
وهو الحل الامثل
CREATE OR REPLACE PROCEDURE PRINT_10 IS
v_empno s_emp.id%TYPE;
v_ename s_emp.last_name%TYPE;
CURSOR emp_cursor IS
SELECT id, last_name
FROM s_emp;
BEGIN
OPEN emp_cursor;
FOR i IN 1..10 LOOP
FETCH emp_cursor INTO v_empno, v_ename;
DBMS_OUTPUT.PUT_LINE (TO_CHAR(v_empno)
||’ ’|| v_ename);
END LOOP;
CLOSE emp_cursor;
END ;

وقل رب زدنى علماً
Osama M. Soliman
Oracle Certified Professional
Oracle Technical Consultant

 Asfour Crystal International
Cairo - Egypt
Osama.Soliman@hotmail.com
Osama.Soliman@asfourcystal.com


#8 Osama Soliman

Osama Soliman

    مشرف سابق وعضو مميز

  • المجموعة الماسية
  • 1,611 مشاركة
  • الاسم الأول:Osama
  • اسم العائلة:Soliman
  • البـلـد: Country Flag
  • المنصب الحالي:Oracle Technical Consultant - Asfour Crystal International

تاريخ المشاركة 13 January 2005 - 01:40 AM

مثال اخر :
DECLARE
CURSOR emp_cur IS
SELECT id, last_name,salary
FROM s_emp;
emp_rec emp_cur%ROWTYPE;
BEGIN
OPEN emp_cur;
LOOP
FETCH emp_cur INTO emp_rec;
EXIT WHEN emp_cur%NOTFOUND;
INSERT INTO emp_history (id,name,salary)
VALUES (emp_rec.id, emp_rec.last_name,emp_rec.salary);
END LOOP;
COMMIT;
CLOSE emp_cursor;
END;

وقل رب زدنى علماً
Osama M. Soliman
Oracle Certified Professional
Oracle Technical Consultant

 Asfour Crystal International
Cairo - Egypt
Osama.Soliman@hotmail.com
Osama.Soliman@asfourcystal.com


#9 Osama Soliman

Osama Soliman

    مشرف سابق وعضو مميز

  • المجموعة الماسية
  • 1,611 مشاركة
  • الاسم الأول:Osama
  • اسم العائلة:Soliman
  • البـلـد: Country Flag
  • المنصب الحالي:Oracle Technical Consultant - Asfour Crystal International

تاريخ المشاركة 13 January 2005 - 01:45 AM

واقرا هذه الطريقة فهى مهمة جدا

Cursor FOR Loops
A cursor FOR loop processes rows in an explicit cursor. It is a shortcut because
 The cursor is opened
 Rows are fetched once for each iteration in the loop
 The loop exits when the last row is processed
 The cursor is closed automatically.
 The loop itself is terminated automatically at the end of the iteration where the last row is fetched.
Syntax:
FOR record_name IN cursor_name LOOP
statement1;
statement2;
. . .
END LOOP;
Where
record_name is the name of the implicitly declared record.
cursor_name is a PL/SQL identifier for the previously declared cursor.
Guidelines:
 Do not declare the record that controls the loop because it is declared implicitly.
 Test the cursor attributes during the loop, if required.
 Supply the parameters for a cursor, if required, in parentheses following the cursor name in the FOR statement. More information on cursor parameters is covered in a subsequent lesson.
 Do not use a cursor FOR loop when the cursor operations must be handled explicitly.
Note: You can define a query at the start of the loop itself. The query expression is called a SELECT substatement, and the cursor is internal to the FOR loop. Because the cursor is not declared with a name, you cannot test its attributes.

وقل رب زدنى علماً
Osama M. Soliman
Oracle Certified Professional
Oracle Technical Consultant

 Asfour Crystal International
Cairo - Egypt
Osama.Soliman@hotmail.com
Osama.Soliman@asfourcystal.com


#10 Osama Soliman

Osama Soliman

    مشرف سابق وعضو مميز

  • المجموعة الماسية
  • 1,611 مشاركة
  • الاسم الأول:Osama
  • اسم العائلة:Soliman
  • البـلـد: Country Flag
  • المنصب الحالي:Oracle Technical Consultant - Asfour Crystal International

تاريخ المشاركة 13 January 2005 - 01:50 AM

واخيراً اليك هذا المثال :

Example
CREATE OR REPLACE PROCEDURE PRINT_DEPT_EMP
(p_dept_id S_DEPT.ID%TYPE) IS
CURSOR emp_cur IS
SELECT id, last_name, salary,dept_id
FROM s_emp;
BEGIN
FOR emp_rec IN emp_cur LOOP
IF emp_rec.dept_id = p_dept_id THEN
DBMS_OUTPUT.PUT_LINE (’Employee data : ’ || emp_rec.last_name||emp_rec.salary);
END IF;
END LOOP;
END ;
When you use a subquery in a FOR loop, you do not need to declare a cursor.
CREATE OR REPLACE PROCEDURE PRINT_DEPT_EMP_2
(p_dept_id S_DEPT.ID%TYPE) IS
BEGIN
FOR emp_rec IN (SELECT id, last_name, salary,dept_id
FROM s_emp)
LOOP
IF emp_rec.dept_id = p_dept_id THEN
DBMS_OUTPUT.PUT_LINE (’Employee data : ’ || emp_rec.last_name||emp_rec.salary);
END IF;
END LOOP;
END ;

تم التعديل بواسطة Osama Soliman, 13 January 2005 - 09:48 AM.

وقل رب زدنى علماً
Osama M. Soliman
Oracle Certified Professional
Oracle Technical Consultant

 Asfour Crystal International
Cairo - Egypt
Osama.Soliman@hotmail.com
Osama.Soliman@asfourcystal.com


#11 undo

undo

    مشترك

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

تاريخ المشاركة 13 January 2005 - 02:31 AM

السلام عليكم

الحلول صحيحة لكن كلها باستخدام الCURSORS .. انا لا اريد استخدام اي CURSOR ..
لكن اقرب الحلول لما اقصده هو حلك الأول يا اسامة و ليس حلولك التالية.. ففي الحل الأول استخدمت SELECT فقط في حلقة تكرارية و لكن لم تستطع التغلب على مشكلة الوصول للصفوف بصورة متتالية بدون الاعتماد على الجدول نفسه..

#12 Osama Soliman

Osama Soliman

    مشرف سابق وعضو مميز

  • المجموعة الماسية
  • 1,611 مشاركة
  • الاسم الأول:Osama
  • اسم العائلة:Soliman
  • البـلـد: Country Flag
  • المنصب الحالي:Oracle Technical Consultant - Asfour Crystal International

تاريخ المشاركة 17 January 2005 - 12:23 AM

والله اخى undo الحلول التالية تعتمد فعلا على الـ Cursor وقصدت بالمشاركة بها توضيح فوائد الـ Cursor وانصح كل الاخوة الاعضاء الذين لا يستخدمون الـ Cursor عليهم بالبحث فى موضوعه
  • abu_kalid معجب بهذا

وقل رب زدنى علماً
Osama M. Soliman
Oracle Certified Professional
Oracle Technical Consultant

 Asfour Crystal International
Cairo - Egypt
Osama.Soliman@hotmail.com
Osama.Soliman@asfourcystal.com


#13 undo

undo

    مشترك

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

تاريخ المشاركة 17 January 2005 - 12:43 AM

للرفع..

اللغز ليس اختبار للمعلومات و لكن للتفكير و أعتقد ان المشكلة هنا انكم تحاولون استخدام معلوماتكم هنا..

انا عارف ان اللغز مستفز و لكن هذه هي أضمن طريقة لكي أجد من يحله :rolleyes:

#14 h_elshawaf

h_elshawaf

    مشترك

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

تاريخ المشاركة 17 January 2005 - 02:00 PM

السلام عليكم ورحمة الله وبركاته
أخى العزيز
بداية يستحيل بكل الطرق الممكنة عمل ما تريد بدون استخدام الcursor
بل لا يمكن عمل استعلام أو ما شابه فى الأوراكل بدون استخدام الcursor
وذلك لأن لتنفيذ الاستعلام يقوم الاوراكل بفتح implicit cursor حتى لو كان استعلام بسيط عباره عن جملة select فقط
لذا فإن عمل cursor forloop هو الأقرب لما تريد .
أما فكرتك نفسها فقد فكرت فيها فى بداية تعلمى للغة الpl/sql وفكرت فى انى لا استخدم الexplicit cursor ولكن استخدم correlated subquery حتى استطيع أن أمر على قيمه قيمه من الجدول مع العلم أن هذا سيتطلب من أوراكل فتح implicit cursor
ولكن لأبقى معك فى كلامك ونكتفى بجمل الselect بغض النظر عن الimplicit cursor ولكن أنا لم أخرج من حيز التفكير الى حيز التنفيذ
مجرد فكره ربما يكون لديك الوقت لتجربتها .
شكرا لهذا اللغز .
والى الغاز اخرى
والسلام خير ختام

أدرى بأن هناك فجرا .. وأن بعد العسر يسرا
لكنهم ساموا الفتى وبلاده عسفا وقهرا
والعالم الحيران يشهد ما يحل بأمتى
وأنا هنا .. فى غربتى .. فى لوعتى
أبكى وأمسح فى ذهول دمعتى
وأظل أنظر للسماء .. والقلب يخفق بالدعاء
يارب .. أوقظ أمتى


متى يبلغ البنيان يوما تمامه
إذا كنت تبنيه وغيرك يهدمه
لو كان سهما واحدا لإتقيته
ولكنه سهم وثان وثالث

#15 undo

undo

    مشترك

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

تاريخ المشاركة 18 January 2005 - 03:15 AM

وذلك لأن لتنفيذ الاستعلام يقوم الاوراكل بفتح implicit cursor حتى لو كان استعلام بسيط عباره عن جملة select فقط
لذا فإن عمل cursor forloop هو الأقرب لما تريد .


و الله كلامك سليم 100% و فعلاً انتبهت لهذه النقطة ...

و ايضا تنبؤك سليم لأني فكرت بالمشكلة قبل ان ادرس ال cursors وبالتالي لم اكن اعرف حلها بالكيرسور..

لكنًي ما زلت مصمم ان اجد من يحلها بدون cursor او for cursor ..:rolleyes:

تم التعديل بواسطة undo, 18 January 2005 - 03:18 AM.