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

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


undo

Recommended Posts

السلام عليكم

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

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

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

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

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

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



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

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

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

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
رابط هذا التعليق
شارك

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

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

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

شكرا لك مقدما

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

عن طريق الـ 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;
/

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

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

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

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

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

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

اخى امجد
فعلاً كلام صحيح مائة بمائة
والمفروض فى هذه الاحوال استخدام 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 ;

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

مثال اخر :
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;

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

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

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.

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

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

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
رابط هذا التعليق
شارك

السلام عليكم

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

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

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

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

للرفع..

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

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

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

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

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

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

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


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

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

لكنًي ما زلت مصمم ان اجد من يحلها بدون cursor او for cursor ..:rolleyes: تم تعديل بواسطة undo
رابط هذا التعليق
شارك

  • بعد 5 أسابيع...
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;
/

Al salam Alikom
i think that the first example that OSAMA mentioned is true
with the following changes

where rownum=i;

because rownum psuedocolumn add a sequence number to the result set of data
رابط هذا التعليق
شارك

declare


v_empno emp.empno%type;
v_ename emp.ename%type;
v_min_empno emp.empno%type;
v_max_empno emp.empno%type;
begin
select min(empno),max(empno)
into v_min_empno,v_max_empno
from emp;
for i in v_min_empno..v_max_empno loop
begin
select empno,ename
into v_empno,v_ename
from emp
where empno=i;
dbms_output.put_line(v_empno||' '||v_ename);
exception
when no_data_found then null;
end;
end loop;
end;
:D

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

Al salam Alikom
i think that the first example that OSAMA mentioned is true
with the following changes

where rownum=i;

because rownum psuedocolumn add a sequence number to the result set of data


u can't use rownum=i

try this
select * from emp
where rownum=5

use rownum with <or <= and
try this
select * from emp where rownum<=4
تم تعديل بواسطة louy-s
رابط هذا التعليق
شارك

  • بعد 6 سنة...

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


يا اخوه المشاركون فعلا ماقاله الاخ اسامه سليمان . لابد من استخدام cursor اليوم او غدا لااهميته .
رابط هذا التعليق
شارك

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

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

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

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

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

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

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