آموزش PL/SQL قسمت نهم – CURSOR در PL/SQL

دیتابیس اوراکل برای هر دستور SQL یک فضای حافظه به نام CONTEXT AREA ایجاد می کند که اطلاعات پردازشی دستور در این محل ذخیره می شود.

CURSOR یک اشاره گر به CONTEXT AREA است و PL/SQL با استفاده از CURSOR این فضا را کنترل می کند و اطلاعات آن را نمایش می دهد. برای مثال با استفاده از CURSOR می توان تعداد کل سطرهای دستکاری شده توسط یک دستور DML را مشاهده نمود یا محتویات داده در هر سطر از یک QUERY را بدست آورد.

انواع CURSOR

1.CURSORهای از نوع IMPLICIT یا ضمنی

هر زمان که یک دستور DMLای یا یک دستور SELECT INTO توسط اوراکل اجرا می شود به صورت اتوماتیک و به روش ضمنی یک CURSOR برای آن دستور ایجاد می شود.

برای دستورات INSERT محتویات CURSOR شامل اطلاعاتی است که باید درج شود و برای دستورات UPDATE و DELETE سطرهایی که مورد تاثیر قرار می گیرند.

برنامه نویس نمی تواند این نوع از CURSORها و اطلاعات آنها را کنترل کنند ولی می توانند اطلاعات و وضعیت CURSOR را از طریق ویژگی ها جدول زیر مشاهده کنند. با استفاده از این ویژگی ها که با عبارت SQL آغاز می شود می توان به اطلاعات آخرین CURSOR از نوع ضمنی دست یافت.

مثال: جدول مشتریان به این شکل می باشد:

حال برنامه زیر را اجرا می کنیم:

DECLARE

total_rows number(2);

BEGIN

UPDATE customers

SET salary = salary + 500;

IF sql%notfound THEN

dbms_output.put_line(‘no customers selected’);

ELSIF sql%found THEN

total_rows := sql%rowcount;

dbms_output.put_line( total_rows || ‘ customers selected ‘);

END IF;

END;

/

در این برنامه به حقوق تمام مشتریان 500 واحد اضافه شده است. بنابراین CURSOR که به صورت ضمنی تعریف شده است دارای مقدار صحیح برای ویژگی FOUND% است و ویژگی ROWCOUNT% آن نیز برابر با تعداد سطرهای UPDATE شده خواهد بود.

خروجی:

6 customers selected

PL/SQL procedure successfully completed.

خروجی جدول:

نکته: با توجه به ماهیت CURSOR از نوع ضمنی و زمانی که صفر یا چند سطر توسط دستور برگردانده می شود ممکن است به خطای EXCEPTION از نوع NO_DATA_FOUND یا TOO_MANY_ROWS برخورد کنیم.

2.CURSOR از نوع صریح یا EXPLICIT

این نوع از CURSORها توسط برنامه نویسان و به منظور کنترل اطلاعات CONTEXT AREA ایجاد می شود.

CURSORهای از نوع صریح در قسمت DECLARE بلاک برنامه تعریف می شوند. هر CURSOR از نوع صریح برای یک دستور SELECT که بیشتر از یک سطر را برمی گرداند ایجاد می شود.

در ادامه سینتکس ساخت CURSOR از نوع صریح را می بینید:

CURSOR cursor_name IS select_statement;

زمانی که از CURSOR  به روش صریح استفاده می شود دیتابیس اوراکل یک سیکل اجرایی برای آن CURSOR تعریف می کند. در ادامه شکل مربوط به این سیکل اجرایی را می بینید و هر مرحله از این سیکل را توضیح می دهیم.

مرحله DECLARE:

ابتدا باید در قسمت DECLARE یک بلاک یا پکیج به شکل زیر CURSOR را تعریف کنیم:

CURSOR c_customers IS

SELECT id, name, address FROM customers;

مرحله OPEN:

با استفاده از دستور زیر یک CURSOR از نوع صریح OPEN می شود و از این مرحله به بعد آماده دستیابی خواهد بود.

OPEN c_customers;

بعد از OPEN شدن یک CURSOR اوراکل دستور SELECT مربوط به آن را پارس کرده و سپس اجرا می کند و CURSOR را روی اولین سطری که آن دستور برمی گرداند تنظیم می کند. در این مرحله CONTEXT AREA تشکیل می شود.

مرحله FETCH

در این مرحله به یک سطر از  دستور توسط CURSOR اشاره می شود و مقدارهای این سطر در متغیرها ذخیره می شوند.

FETCH c_customers INTO c_id, c_name, c_addr;

هر FETCH یک سطر را دستیابی می کند و با FETCH بعدی سطر بعدی دستیابی می  شود.

مرحله CLOSE

با CLOSE کردن یک CURSOR فضای CONTEXT AREA آزاد می شود.

CLOSE c_customers;

نکته 1: اگر اجرای یک بلاک از نوع ANONYMOUS، تابع یا پروسیجرخاتمه یاید به صورت اتوماتیک CURSORهای از نوع صریح CLOSE می شوند.

نکته 2: اگر یک CURSOR که هنوز OPEN نشده است را CLOSE کنیم خطای EXCEPTION از نوع INVALID_CURSOR دریافت می کنیم.

نکته 3: ویژگی هایی که می توان بعد از نام یک CURSOR از نوع صریح استفاده کرد را در جدول زیر می بینید:

 

مثال: نام و شماره تمام مشتریان را نمایش دهید.

DECLARE

c_id customers.id%type;

c_name customerS.Name%type;

c_addr customers.address%type;

CURSOR c_customers is

SELECT id, name, address FROM customers;

BEGIN

OPEN c_customers;

LOOP

FETCH c_customers into c_id, c_name, c_addr;

EXIT WHEN c_customers%notfound;

dbms_output.put_line(c_id || ‘ ‘ || c_name || ‘ ‘ || c_addr);

END LOOP;

CLOSE c_customers;

END;

/

در این برنامه تا زمانی که ویژگی NOTFOUND% برای CURSOR برقرار نشده است، نام و شماره مشتریان چاپ می شود.

خروجی:

1 Ramesh Ahmedabad

2 Khilan Delhi

3 kaushik Kota

4 Chaitali Mumbai

5 Hardik Bhopal

6 Komal MP

PL/SQL procedure successfully completed.

نکته: می توان به CURSORهای از نوع صریح، پارامتر ارسال نمود. بنابراین می توان هر زمان آن CURSOR را با آرگومنت های متفاوت OPEN کنیم.

مثال: یک مرتبه CURSOR را با حداقل و حداکثر قیمت بین 50 و 100 و بار دیگر با 800 و 1000 درنظر می گیریم.

DECLARE

    r_product products%rowtype;

    CURSOR c_product (low_price NUMBER, high_price NUMBER)

    IS

        SELECT *

        FROM products

        WHERE list_price BETWEEN low_price AND high_price;

BEGIN

    — show mass products

    dbms_output.put_line(‘Mass products: ‘);

    OPEN c_product(50,100);

    LOOP

        FETCH c_product INTO r_product;

        EXIT WHEN c_product%notfound;

        dbms_output.put_line(r_product.product_name || ‘: ‘ ||r_product.list_price);

    END LOOP;

    CLOSE c_product;

 

    — show luxury products

    dbms_output.put_line(‘Luxury products: ‘);

    OPEN c_product(800,1000);

    LOOP

        FETCH c_product INTO r_product;

        EXIT WHEN c_product%notfound;

        dbms_output.put_line(r_product.product_name || ‘: ‘ ||r_product.list_price);

    END LOOP;

    CLOSE c_product;

 

END;

/

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد.