[Oracle] Oracle Series Thirteen - Cursor

Review of past issues

Preface

1. Definition of cursor

Oracle cursor is a data structure used to process result sets in PL/SQL code, such as temporarily storing the result set returned by a SELECT statement. Cursors allow programmers to process a result set row by row and retrieve or modify data when needed. When the amount of data in the table is large, it is not suitable to use cursors.

5 steps to use cursors:

  • Declare a variable to save the value returned by the SELECT statement.
  • Declare the cursor and specify the SELECT statement.
  • Use the OPEN statement to open a cursor.
  • Get records from the cursor through the FETCH statement.
  • Close the cursor through the CLOSE statement.

e.g

DECLARE
MYRECORD employees%ROWTYPE;  /*声明变量*/
CURSOR MYCUR IS
SELECT * FROM employees;  /*声明游标*/
BEGIN
OPEN MYCUR;                    /*打开游标*/
LOOP
FETCH MYCUR INTO MYRECORD;  /*从游标中获取记录*/
DBMS_OUTPUT.PUT_LINE (MYRECORD.NAME||','||MYRECORD.BIRTH);
EXIT WHEN MYCUR%NOTFOUND;
END LOOP;
CLOSE MYCUR;                   /*关闭游标*/
END;

2. Type of cursor

Oracle supports two types of cursors: explicit cursors and implicit cursors. Explicit cursors are cursors that are explicitly declared and defined by the programmer, while implicit cursors are automatically created and used by Oracle.

(1) Explicit cursor

Explicit cursors are explicitly declared and defined by the programmer, giving greater control over the cursor's behavior. They can be used in PL/SQL code, allowing the programmer to retrieve the result set, process the data row by row, and modify the data if needed.

e.g

DECLARE
  CURSOR c1 IS SELECT * FROM employees WHERE department_id = 10;
  v_emp employees%ROWTYPE;
BEGIN
  OPEN c1;
  LOOP
    FETCH c1 INTO v_emp;
    EXIT WHEN c1%NOTFOUND;
    -- 处理v_emp这一行数据
  END LOOP;
  CLOSE c1;
END;

In the above example, cursor c1 selects all records with department ID 10 in the table named employees. The FETCH statement stores each row of data in the v_emp variable one by one for line-by-line processing. If there are no more rows, the EXIT statement exits the loop and closes the cursor.

(2) Implicit cursor

Implicit cursors are cursors automatically created and maintained by Oracle. They are used to process result sets in SQL statements without explicit declaration and definition.

e.g

BEGIN
  FOR v_emp IN (SELECT * FROM employees WHERE department_id = 10) LOOP
    -- 处理v_emp这一行数据
  END LOOP;
END;

In the above example, the FOR loop uses the SELECT statement to select all records with department ID 10 in the table named employees. During the loop, each row is stored in the v_emp variable for row-by-row processing.

Although implicit cursors do not require explicit declaration and definition, they can more easily cause errors, such as possibly affecting other concurrently executing operations or causing memory leaks and other problems. Therefore, when writing PL/SQL code with complex business logic, you should give priority to using explicit cursors.

3. Application of cursor

(1) Basic usage

The most basic use of a cursor is to traverse the query result set. The cursor can also take parameters. The parameters only declare the type, not the precision.

e.g

DECLARE
T_NAME employees%TYPE;
CURSOR CUR_PARA(MCC VARCHAR2) IS
SELECT MC FROM employees WHERE AREA=MCC;
BEGIN
OPEN CUR_PARA('北京市');
LOOP
FETCH CUR_PARA INTO T_NAME;
EXIT WHEN CUR_PARA%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(T_NAME);
END LOOP;
CLOSE CUR_PARA;
END;

(2) Data processing

Cursors can implement complex data processing business logic through loops.

e.g

DECLARE
CURSOR c_emp IS SELECT * FROM emp;
v_sum NUMBER := 0;
v_sal emp.sal%TYPE;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO v_emp;
EXIT WHEN c_emp%NOTFOUND;
v_sal := v_emp.sal;
v_sum := v_sum + v_sal;
END LOOP;
CLOSE c_emp;
DBMS_OUTPUT.put_line('The total salary is ' || v_sum);
END;

The above code queries all records in the emp table by defining the cursor c_emp, and loops through each record to accumulate and sum employee salaries, and finally outputs the result.

(3) Update data

In addition to querying and reading, cursors can also update and delete query results.

e.g

DECLARE
CURSOR c_emp IS SELECT * FROM emp WHERE job = 'MANAGER' AND deptno = 10 FOR UPDATE;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO v_emp;
EXIT WHEN c_emp%NOTFOUND;
UPDATE emp SET sal = sal * 1.1 WHERE CURRENT OF c_emp;
END LOOP;
CLOSE c_emp;
END;

The above code queries the emp table for employee records with department number 10 and position manager by defining the cursor c_emp, and uses the FOR UPDATE statement to lock these records to prevent other users from modifying them. Then, loop through each record and update the salary of each record with a 10% increase. Finally, close the cursor via the CLOSE statement.

(4) Precautions

Please pay attention to the following issues when using cursors:

Cursor performance issues: Because the cursor needs to read the data in the query result set one by one, it may cause performance issues when processing large amounts of data. In order to optimize the performance of the cursor, you can reduce the query result set by increasing the WHERE clause, using indexes, and reducing JOIN.
Cursor memory usage: Cursors need to occupy a certain amount of memory space, so you need to pay special attention to the memory usage when processing large amounts of data. To avoid memory overflow, you can limit the size of the query result set by setting the cursor cache size, using the LIMIT keyword, and adding a WHERE clause.
Cursor concurrency control: Since the cursor needs to lock the records in the query result set when processing data, special attention needs to be paid to the concurrency control of the cursor in a concurrent environment. In order to avoid deadlock and other problems, the concurrency stability of the cursor can be ensured through reasonable lock mechanism and transaction management.

Guess you like

Origin blog.csdn.net/u011397981/article/details/133442823