Edit D:\app\Administrator\product\11.2.0\dbhome_1\oc4j\j2ee\oc4j_applications\applications\em\em\online_help\tdddg\tdddg_subprograms041.htm
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <script src="./callback.js" type="text/javascript"></script> <noscript>Your browser does not support JavaScript. This help page requires JavaScript to render correctly.</noscript> </head> <meta http-equiv="Content-Type" content="text/html; charset=us-ascii" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <meta http-equiv="Content-Script-Type" content="text/javascript" /> <meta name="generator" content="Oracle DARB XHTML Converter (Mode = ohj/ohw) - Version 5.1.1 Build 005" /> <meta name="date" content="2009-04-21T9:46:24Z" /> <meta name="robots" content="noarchive" /> <meta name="doctitle" content="Tutorial: Using a Cursor Variable to Retrieve Result Set Rows One at a Time" /> <meta name="relnum" content="11g Release 2 (11.2)" /> <meta name="partnum" content="E10766-01" /> <link rel="copyright" href="./dcommon/html/cpyr.htm" title="Copyright" type="text/html" /> <link rel="stylesheet" href="./dcommon/css/blafdoc.css" title="Oracle BLAFDoc" type="text/css" /> <link rel="contents" href="toc.htm" title="Contents" type="text/html" /> <link rel="prev" href="tdddg_subprograms040.htm" title="Previous" type="text/html" /> <link rel="next" href="tdddg_subprograms042.htm" title="Next" type="text/html" /> <title>Tutorial: Using a Cursor Variable to Retrieve Result Set Rows One at a Time</title> </head> <body> <div class="zz-skip-header"><a href="#BEGIN">Skip Headers</a></div> <table class="simple oac_no_warn" summary="" cellspacing="0" cellpadding="0" width="100%"> <col width="86%" /> <col width="*" /> <tr valign="bottom"> <td align="left"></td> <td align="center"><a href="tdddg_subprograms040.htm"><img width="24" height="24" src="./dcommon/gifs/leftnav.gif" alt="Previous" /><br /> <span class="icon">Previous</span></a> </td> <td align="center"><a href="tdddg_subprograms042.htm"><img width="24" height="24" src="./dcommon/gifs/rightnav.gif" alt="Next" /><br /> <span class="icon">Next</span></a></td> </tr> </table> <p><a id="BABBEABD" name="BABBEABD"></a><a id="TDDDG99955" name="TDDDG99955"></a></p> <div class="sect2"><!-- infolevel="all" infotype="General" --> <h1>Tutorial: Using a Cursor Variable to Retrieve Result Set Rows One at a Time</h1> <a name="BEGIN" id="BEGIN"></a> <p><a id="sthref489" name="sthref489"></a>This tutorial shows how to change the <code>EMP_EVAL</code>.<code>eval_department</code> procedure so that it uses a cursor variable instead of an explicit cursor, which lets it process multiple departments. The change includes adding a procedure that uses the cursor variable.</p> <p>This tutorial also shows how to make <code>EMP_EVAL</code>.<code>eval_department</code> and <code>EMP_EVAL</code>.<code>add_eval</code> more efficient: Instead of passing one field of a record to <code>add_eval</code> and having <code>add_eval</code> use three queries to extract three other fields of the same record, <code>eval_department</code> passes the entire record to <code>add_eval</code>, and <code>add_eval</code> uses dot notation to access the values of the other three fields.</p> <a id="TDDDG240" name="TDDDG240"></a> <p class="subhead2">To change the EMP_EVAL.eval_department procedure to use a cursor variable:</p> <ol> <li> <p>In the <code>EMP_EVAL</code> package specification, add the procedure declaration and the <code>REF</code> <code>CURSOR</code> type definition, as shown in bold font:</p> <pre xml:space="preserve" class="oac_no_warn"> create or replace PACKAGE emp_eval AS PROCEDURE eval_department (dept_id IN employees.department_id%TYPE); <span class="bold">PROCEDURE eval_everyone;</span> FUNCTION calculate_score(eval_id IN scores.evaluation_id%TYPE , perf_id IN scores.performance_id%TYPE) RETURN NUMBER; TYPE SAL_INFO IS RECORD ( j_id jobs.job_id%type , sal_min jobs.min_salary%type , sal_max jobs.max_salary%type , salary employees.salary%type , sal_raise NUMBER(3,3)); <span class="bold">TYPE emp_refcursor_type IS REF CURSOR RETURN employees%ROWTYPE;</span> END emp_eval; </pre> <p>(For instructions for changing a package specification, see <a href="tdddg_subprograms015.htm#CIHIEAGC">"Tutorial: Changing a Package Specification"</a>.)</p> </li> <li> <p>In the <code>EMP_EVAL</code> package body, add a forward declaration for the procedure <code>eval_loop_control</code> and change the declaration of the procedure <code>add_eval</code>, as shown in bold font:</p> <pre xml:space="preserve" class="oac_no_warn"> create or replace PACKAGE BODY EMP_EVAL AS FUNCTION eval_frequency (emp_id IN EMPLOYEES.EMPLOYEE_ID%TYPE) RETURN PLS_INTEGER; PROCEDURE salary_schedule(emp IN sal_info); <span class="bold">PROCEDURE add_eval(emp_record IN EMPLOYEES%ROWTYPE, today IN DATE);</span> <span class="bold">PROCEDURE eval_loop_control(emp_cursor IN emp_refcursor_type);</span> ... </pre> <p>(For a step-by-step example of changing a package body, see <a href="tdddg_subprograms019.htm#CIHBGDBA">"Tutorial: Declaring Variables and Constants in a Subprogram"</a>.)</p> </li> <li><a id="CIHCCIHH" name="CIHCCIHH"></a> <p>Change the <code>eval_department</code> procedure to retrieve three separate result sets based on the department, and to call the <code>eval_loop_control</code> procedure, as shown in bold font:</p> <pre xml:space="preserve" class="oac_no_warn"> PROCEDURE eval_department(dept_id IN employees.department_id%TYPE) AS <span class="bold">emp_cursor emp_refcursor_type;</span> <span class="bold">current_dept departments.department_id%TYPE;</span> BEGIN <span class="bold">current_dept := dept_id;</span> <span class="bold">FOR loop_c IN 1..3 LOOP</span> <span class="bold">OPEN emp_cursor FOR</span> <span class="bold">SELECT *</span> <span class="bold">FROM employees</span> <span class="bold">WHERE current_dept = dept_id;</span> DBMS_OUTPUT.PUT_LINE ('Determining necessary evaluations in department #' || <span class="bold">current_dept</span>); <span class="bold">eval_loop_control(emp_cursor);</span> DBMS_OUTPUT.PUT_LINE ('Processed ' || emp_cursor%ROWCOUNT || ' records.'); CLOSE emp_cursor; <span class="bold">current_dept := current_dept + 10;</span> <span class="bold">END LOOP;</span> END eval_department; </pre></li> <li> <p>Change the <code>add_eval</code> as shown in bold font:</p> <pre xml:space="preserve" class="oac_no_warn"> PROCEDURE add_eval(<span class="bold">emp_record IN employees%ROWTYPE</span>, today IN DATE) AS <span class="bold">-- (Delete local variables)</span> BEGIN INSERT INTO EVALUATIONS ( evaluation_id, employee_id, evaluation_date, job_id, manager_id, department_id, total_score ) VALUES ( evaluations_seq.NEXTVAL, -- evaluation_id <span class="bold">emp_record.employee_id, -- employee_id</span> today, -- evaluation_date <span class="bold">emp_record.job_id, -- job_id</span> <span class="bold">emp_record.manager_id, -- manager_id</span> <span class="bold">emp_record.department_id, -- department_id</span> 0 -- total_score ); END add_eval; </pre></li> <li> <p>Before <code>END</code> <code>EMP_EVAL</code>, add the following procedure, which fetches the individual records from the result set and processes them:</p> <pre xml:space="preserve" class="oac_no_warn"> PROCEDURE eval_loop_control (emp_cursor IN emp_refcursor_type) AS emp_record EMPLOYEES%ROWTYPE; all_evals BOOLEAN; today DATE; BEGIN today := SYSDATE; IF (EXTRACT(MONTH FROM today) < 6) THEN all_evals := FALSE; ELSE all_evals := TRUE; END IF; LOOP FETCH emp_cursor INTO emp_record; EXIT WHEN emp_cursor%NOTFOUND; IF all_evals THEN add_eval(emp_record, today); ELSIF (eval_frequency(emp_record.employee_id) = 2) THEN add_eval(emp_record, today); END IF; END LOOP; END eval_loop_control; </pre></li> <li> <p>Before <code>END</code> <code>EMP_EVAL</code>, add the following procedure, which retrieves a result set that contains all employees in the company:</p> <pre xml:space="preserve" class="oac_no_warn"> PROCEDURE eval_everyone AS emp_cursor emp_refcursor_type; BEGIN OPEN emp_cursor FOR SELECT * FROM employees; DBMS_OUTPUT.PUT_LINE('Determining number of necessary evaluations.'); eval_loop_control(emp_cursor); DBMS_OUTPUT.PUT_LINE('Processed ' || emp_cursor%ROWCOUNT || ' records.'); CLOSE emp_cursor; END eval_everyone; </pre></li> <li> <p>Compile the <code>EMP_EVAL</code> package specification.</p> </li> <li> <p>Compile the <code>EMP_EVAL</code> package body.</p> </li> </ol> <div class="helpinfonotealso"> <h2>Related Topics</h2> <p><a href="tdddg_subprograms040.htm#BABEHCAJ">Using a Cursor Variable to Retrieve Result Set Rows One at a Time</a></p> <p><a href="tdddg_subprograms032.htm#CIHHCJDI">Using Records and Cursors</a></p> </div> </div> <!-- class="sect2" --> <!-- class="sect1" --> <!-- Start Footer --> <div class="footer"> <table class="simple oac_no_warn" summary="" cellspacing="0" cellpadding="0" width="100%"> <col width="86%" /> <col width="*" /> <tr> <td align="left"><span class="copyrightlogo">Copyright © 1996, 2009, Oracle and/or its affiliates. All rights reserved.</span><br /> <a href="./dcommon/html/cpyr.htm"><span class="copyrightlogo">Legal Notices</span></a></td> <td align="center"><a href="tdddg_subprograms040.htm"><img width="24" height="24" src="./dcommon/gifs/leftnav.gif" alt="Previous" /><br /> <span class="icon">Previous</span></a> </td> <td align="center"><a href="tdddg_subprograms042.htm"><img width="24" height="24" src="./dcommon/gifs/rightnav.gif" alt="Next" /><br /> <span class="icon">Next</span></a></td> </tr> </table> </div> <!-- class="footer" --> </body> </html>
Ms-Dos/Windows
Unix
Write backup
jsp File Browser version 1.2 by
www.vonloesch.de