Oracle basic cursor

Cursor

  Cursors are used to process multiple rows of records retrieved from the database (using SELECT statements). Using cursors, programs can process and traverse the entire recordset returned once retrieved one by one.

     To process the SQL statement, Oracle will allocate a region in memory, which is the context area. This section contains the number of processed rows, pointers to the analyzed statement, and the entire section is the data row set returned by the query statement. The cursor refers to the handle or pointer of the context area.

 

Two. Classification of cursors:

  1、Static cursor: the static cursor is the cursor that knows its SELECT statement at compile time. There are two types of static cursors, implicit cursors and display cursors.

  2、Dynamic cursor: The query that the user uses for the cursor can not be determined until it runs, and can be met with the REF cursor and cursor variables. In order to use reference cursors, you must declare cursor variables. There are two types of REF cursors: strongly typed REF cursors and weak type REF cursors.

 

 

Three. Show the usage of cursor:

  The cursor is used to process SELECT statements that return multiple rows of data, and the cursor name is passed through CURSOR. The.IS statement is displayed to the SELECT statement.

       ((1) use steps;

       1)Declare cursor:CURSOR cursor_name IS select_statement

        2)Open cursors for queries:OPEN cursor_name

        3)The result is put in the PL/SQL variable.

                 FETCH cursor_name INTO list_of_variables;

               FETCH cursor_name INTO PL/SQL_record;

        4)Close the cursor.CLOSE cursor_name

  Note: when vernier is declared,select_statementCan not contain the INTO clause. When displaying cursors, the INTO clause is part of the FETCH statement.

  Example: show employee’s name and salary

Copy code ></span></div>
<pre><span style=--Traversing cursors using LOOPDECLARE v_name emp.ename%TYPE; v_sal emp.sal%TYPE; CURSOR cus_emp IS SELECT ename,sal FROM emp; --declare cursorBEGIN OPEN cus_emp; --open LOOP FETCH cus_emp INTO v_name,v_sal; --Extract cursorEXIT WHEN cus_emp%NOTFOUND; dbms_output.put_line('The first'||cus_emp%ROWCOUNT||'User: name:'||v_name||' sal:'||v_sal); END LOOP; CLOSE cus_emp; --Close the cursorEND;
Copy code ></span></div>
</div>
<p>  Displays the cursor’s properties:</p>
<p>  <span style=%FOUND:Only when the DML statement affects one row or more rows, it returns TRUE.

  %NOTFOUND:No row is affected, then TRUE is returned.

  %ROWCOUNT:Returns the number of rows affected by the DML statement, and returns 0 if there is no effect.

  %ISOPEN:Returns whether the cursor is open, and after executing SQL, Oracle automatically closes the SQL cursor, so the% isopen property of the implicit cursor is never false;

 

  Another way:

Copy code ></span></div>
<pre><span style=--Using for to simplify cursor traversalDECLARE CURSOR cus_emp IS SELECT ename,sal FROM emp; BEGIN FOR record_emp IN cus_emp LOOP dbms_output.put_line('The first'||cus_emp%ROWCOUNT||'User: name:'||record_emp.ename||' sal:'||record_emp.sal); END LOOP; END;
Copy code ></span></div>
</div>
<p>  record_empIs a record variable declared by plsql, whose property is declared as the% ROWTYPE type, scoped within the FOR loop, which is inaccessible outside the FOR loop.</p>
<p>  The characteristics of circular cursors are:<br />  (1)All records from the cursor are automatically terminated.<br />  (2)Extract and process every record in the cursor.<br />  (3)If the%NOTFOUND property returns TRUE after the record is extracted, the loop is terminated. If no rows are returned, the loop is not entered.</p>
<p> </p>
<p>Cursor case:</p>
<div class=
Copy code ></span></div>
<pre><span style=--Raise salary for employees, increase salary according to staff entry time, add 1001000 capping per year.DECLARE v_date emp.hiredate%TYPE; v_empno emp.empno%TYPE; v_money NUMBER; CURSOR cur_emp IS SELECT empno,hiredate FROM emp; BEGIN OPEN cur_emp; LOOP FETCH cur_emp INTO v_empno,v_date; EXIT WHEN cur_emp%NOTFOUND; v_money := 100*(1990-to_char(v_date,'yyyy')); IF v_money<1000 THEN UPDATE emp SET sal=sal+v_money WHERE empno=v_empno; ELSE UPDATE emp SET sal=sal+1000 WHERE empno=v_empno; END IF; END LOOP; END;
Copy code ></span></div>
</div>
<p><strong> Cursors with parameters</strong></p>
<p>  <span style=Grammar:

  CURSOR cursor_name[(parameter[,parameter],…)] IS select_statement;

  The syntax for defining parameters is as follows: Parameter_name [IN] data_type[{: =|DEFAULT} value]

  Example: Receive the user's input department number, use for loop and cursor, print out all the information of all employees in this department (using circular cursor)
Copy code ></span></div>
<pre><span style=DECLARE CURSOR C_DEPT(P_DEPTNO NUMBER) IS SELECT * FROM EMP WHERE EMP.DEPTNO = P_DEPTNO; R_EMP EMP%ROWTYPE; BEGIN FOR R_EMP IN C_DEPT(30) LOOP DBMS_OUTPUT.PUT_LINE('Employee number:' || R_EMP.EMPNO || 'Employee name:' || R_EMP.ENAME || 'Wages:' || R_EMP.SAL); END LOOP; END;
Copy code ></span></div>
</div>
<p><strong><span style='font-family: Four. Implicit cursors:

  All implicit cursors are assumed to return only one record.
  When using implicit cursors, users do not need to declare, open and close. PL/SQL implicitly opens, processes, and then turns off the cursor. Implicit cursor SQL for multiple SQL statements always refers to the result of the last SQL statement, mainly used in update and delete statementsUp.

  Four properties of implicit cursors:

 

attribute Explain
 SQL%rowcount  The number of rows in the affected record integer (used to determine whether the insert, update, modification is successful, must be before comit, otherwise the submitted result is 0.)
 SQL%found  It affects the record true ().
 SQL%notfound  No impact on recording true
 SQL%isopen  Whether to open Boolean value is always false

For example:

Copy code ></span></div>
<pre><span style=DECLARE row_emp emp%ROWTYPE; BEGIN SELECT ename,sal INTO row_emp.ename,row_emp.sal FROM emp WHERE emp.empno = 7369; --Deciding whether to find dataif(SQL%ROWCOUNT=1) THEN dbms_output.put_line('Eureka'); END IF; --Another way of judgingIF(SQL%Found) THEN dbms_output.put_line('Eureka'); END IF; dbms_output.put_line('ename:'||row_emp.ename||' sal:'||row_emp.sal); END;
Copy code ></span></div>
</div>
<p> </p>
<p>The cursor is automatically opened and assigned the corresponding value to the corresponding variable and then closed. After execution, the PL/SQL variable rowemp.ename and rowemp.sal already have a value.</p>
<p><strong><span style='font-family: Five: dynamic cursor

  A static cursor is a query statement that is declared to have been determined. If the user needs to dynamically determine the query to be executed by the cursor at run time, he needs to use a dynamic cursor (REF cursor).

  Dynamic cursors can be classified into two categories:Strongly typed cursors andWeak type cursors.

  Dynamic cursor usage steps:

  1、Declare dynamic cursor type;

  2、Open cursor and specify cursor query;

  3、Extract cursors.

  4、Close the cursor.

  Example:

  Strongly typed cursorsA vernier using return declaration is a strongly typed cursor. Binding queries on cursors can only bind the type rowtype returned by cursors.

Copy code ></span></div>
<pre><span style=--Strong type dynamic cursor, querying data in EMP table.DECLARE TYPE ref_cur IS REF CURSOR --Declare cursor typeRETURN emp%ROWTYPE; --Strong type dynamic cursors with return valuesRefcur_emp ref_cur;--Cursor type objectV_emp EMP%ROWTYPE; BEGIN OPEN refcur_emp FOR --Bind the cursor to a query statement, because the declaration is strongly typed, so it can only bind EMP.SELECT * FROM emp; LOOP FETCH refcur_emp INTO v_emp; --Extract cursor contentEXIT WHEN refcur_emp%NOTFOUND; dbms_output.put_line(refcur_emp%Rowcount||'、name:'||v_emp.ename||' sal:'||v_emp.sal); END LOOP; CLOSE refcur_emp; END;
Copy code ></span></div>
</div>
<p>  </p>
<p>  <strong>Weak type cursor: can be used to bind multiple query results.</strong></p>
<p>  Example:</p>
<div class=
Copy code ></span></div>
<pre><span style=--Weak type cursorDECLARE TYPE refcur IS REF CURSOR; --Undefined return type is weak type cursor. rc refcur; v_name emp.ename%TYPE; v_deptname dept.dname%TYPE; BEGIN OPEN rc FOR SELECT ename,dname FROM emp e,dept d WHERE e.deptno = d.deptno; --Binding query LOOP FETCH rc INTO v_name,v_deptname; EXIT WHEN rc%NOTFOUND; dbms_output.put_line('name:'||v_name||' deptname:'||v_deptname); END LOOP; CLOSE rc; END;
Copy code ></span></div>
</div>
<p> </p>
<p>  Example:</p>
<div class=
Copy code ></span></div>
<pre><span style=--Binding cursors based on input contentDECLARE TYPE refcur IS REF CURSOR; rc refcur; v_tablename VARCHAR2(10) := '&tab'; v_id NUMBER; v_name VARCHAR2(20); BEGIN IF(v_tablename = 'e') THEN OPEN rc FOR SELECT e.empno,e.ename INTO v_id,v_name FROM emp e; dbms_output.put_line('=========Employee information = = = = = = = = = = = = ='); Elsif(v_tablename = 'd') THEN OPEN rc FOR SELECT d.deptno,d.dname INTO v_id,v_name FROM dept d; dbms_output.put_line('=========Departmental information = = = = = = = = = = = = ='); ELSE dbms_output.put_line('Input error, please input e or D!'); RETURN; END IF; LOOP FETCH rc INTO v_id,v_name; dbms_output.put_line('#'||rc%Rowcount||' id:'||v_id||' name:'||v_name); EXIT WHEN rc%NOTFOUND; END LOOP; END;
Copy code ></span></div>
</div>
<p> </p>
<p><strong><span style='font-family: Six, the difference between dynamic cursor and static cursor:  

  1、Static cursors are static definitions, and REF cursors are dynamic associations.

  2、Using REF cursors requires REF cursor variables.

  3、REF Cursors can be passed as parameters, while static cursors are impossible.

Leave a Reply

Your email address will not be published. Required fields are marked *