Что такое CURSOR в PL / SQL?
Курсор — это указатель на эту контекстную область. Oracle создает контекстную область для обработки оператора SQL, который содержит всю информацию об операторе.
PL / SQL позволяет программисту управлять контекстной областью с помощью курсора. Курсор содержит строки, возвращаемые оператором SQL. Набор строк, которые содержит курсор, называется активным набором. Эти курсоры также могут быть названы так, чтобы их можно было ссылаться из другого места кода.
В этом уроке вы узнаете
Курсор бывает двух типов.
- Неявный курсор
- Явный курсор
Неявный курсор
Всякий раз, когда в базе данных происходят какие-либо операции DML, создается неявный курсор, который содержит затронутые строки в этой конкретной операции. Эти курсоры не могут быть названы и, следовательно, они не могут управляться или ссылаться из другого места кода. Мы можем ссылаться только на самый последний курсор через атрибуты курсора.
Явный курсор
Программистам разрешено создавать именованную контекстную область для выполнения своих операций DML, чтобы получить больший контроль над ней. Явный курсор должен быть определен в разделе объявлений блока PL / SQL и создан для оператора SELECT, который необходимо использовать в коде.
Ниже приведены этапы работы с явными курсорами.
- Объявление курсора
Объявление курсора просто означает создание одной именованной области контекста для оператора SELECT, который определен в части объявления. Имя этой области контекста совпадает с именем курсора.
- Открытие курсора
Открытие курсора даст PL / SQL команду выделить память для этого курсора. Это сделает курсор готовым к извлечению записей.
- Извлечение данных из курсора
In this process, the ‘SELECT’ statement is executed and the rows fetched is stored in the allocated memory. These are now called as active sets. Fetching data from the cursor is a record-level activity that means we can access the data in a record-by-record way.
Each fetch statement will fetch one active set and holds the information of that particular record. This statement is same as ‘SELECT’ statement that fetches the record and assigns to the variable in the ‘INTO’ clause, but it will not throw any exceptions.
- Closing the Cursor
Once all the record is fetched now, we need to close the cursor so that the memory allocated to this context area will be released.
Syntax:
DECLARE CURSOR <cursor_name> IS <SELECT statement^> <cursor_variable declaration> BEGIN OPEN <cursor_name>; FETCH <cursor_name> INTO <cursor_variable>; . . CLOSE <cursor_name>; END;
- In the above syntax, the declaration part contains the declaration of the cursor and the cursor variable in which the fetched data will be assigned.
- The cursor is created for the ‘SELECT’ statement that is given in the cursor declaration.
- In execution part, the declared cursor is opened, fetched and closed.
Cursor Attributes
Both Implicit cursor and the explicit cursor has certain attributes that can be accessed. These attributes give more information about the cursor operations. Below are the different cursor attributes and their usage.
Cursor Attribute | Description |
%FOUND | It returns the Boolean result ‘TRUE’ if the most recent fetch operation fetched a record successfully, else it will return FALSE. |
%NOTFOUND | This works oppositely to %FOUND it will return ‘TRUE’ if the most recent fetch operation could not able to fetch any record. |
%ISOPEN | It returns Boolean result ‘TRUE’ if the given cursor is already opened, else it returns ‘FALSE’ |
%ROWCOUNT | It returns the numerical value. It gives the actual count of records that got affected by the DML activity. |
Example 1: In this example, we are going to see how to declare, open, fetch and close the explicit cursor.
We will project all the employee’s name from emp table using a cursor. We will also use cursor attribute to set the loop to fetch all the record from the cursor.
DECLARE CURSOR guru99_det IS SELECT emp_name FROM emp; lv_emp_name emp.emp_name%type; BEGIN OPEN guru99_det; LOOP FETCH guru99_det INTO lv_emp_name; IF guru99_det%NOTFOUND THEN EXIT; END IF; Dbms_output.put_line(‘Employee Fetched:‘||lv_emp_name); END LOOP; Dbms_output.put_line(‘Total rows fetched is‘||guru99_det%R0WCOUNT); CLOSE guru99_det; END: /
Вывод
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY Total rows fetched is 3
Объяснение кода:
- Строка кода 2 : Объявление курсора guru99_det для оператора «SELECT emp_name FROM emp».
- Строка кода 3 : Объявление переменной lv_emp_name.
- Строка кода 5 : открытие курсора guru99_det.
- Строка кода 6: установка оператора цикла Basic для извлечения всех записей в таблице «emp».
- Строка кода 7: извлекает данные guru99_det и присваивает значение lv_emp_name.
- Строка кода 9: Использование атрибута курсора «% NOTFOUND», чтобы определить, выбраны ли все записи в курсоре. В случае выборки он вернет «ИСТИНА» и элемент управления выйдет из цикла, иначе элемент управления продолжит извлекать данные из курсора и печатать данные.
- Строка кода 11: условие EXIT для оператора цикла.
- Строка кода 12: распечатайте выбранное имя сотрудника.
- Строка кода 14: Использование атрибута курсора «% ROWCOUNT», чтобы найти общее количество записей, которые были затронуты / извлечены в курсоре.
- Строка кода 15: после выхода из цикла курсор закрывается и выделяемая память освобождается.
Оператор FOR Loop Cursor
Оператор FOR LOOP может использоваться для работы с курсорами. Мы можем дать имя курсора вместо предела диапазона в операторе цикла FOR, чтобы цикл работал от первой записи курсора до последней записи курсора. Переменная курсора, открытие курсора, выборка и закрытие курсора будут выполняться неявно циклом FOR.
Синтаксис:
DECLARE CURSOR <cursor_name> IS <SELECT statement>; BEGIN FOR I IN <cursor_name> LOOP . . END LOOP; END;
- В приведенном выше синтаксисе часть объявления содержит объявление курсора.
- Курсор создан для оператора SELECT, который указан в объявлении курсора.
- Во время выполнения объявленный курсор устанавливается в цикле FOR, и переменная цикла ‘I’ будет вести себя как переменная курсора в этом случае.
Example 1: In this example, we will project all the employee name from emp table using a cursor-FOR loop.
DECLARE CURSOR guru99_det IS SELECT emp_name FROM emp; BEGIN FOR lv_emp_name IN guru99_det LOOP Dbms_output.put_line(‘Employee Fetched:‘||lv_emp_name.emp_name); END LOOP; END; /
Output
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY
Code Explanation:
- Code line 2: Declaring the cursor guru99_det for statement ‘SELECT emp_name FROM emp’.
- Code line 4: Constructing the ‘FOR’ loop for the cursor with the loop variable lv_emp_name.
- Code line 5: Printing the employee name in each iteration of the loop.
- Code line 8: Exit the loop
Note: In Cursor-FOR loop, cursor attributes cannot be used since opening, fetching and closing of the cursor is done implicitly by FOR loop.