Oracle PL/SQL курсор: имплицитно, явно, For Loop с пример
⚡ Умно обобщение
Курсори в Oracle PL/SQL са указатели към контекстната област, която съдържа редовете, върнати от SQL оператор. Съществуват два вида: имплицитни курсори, създадени автоматично за DML, и експлицитни курсори, декларирани и контролирани от програмиста.

Какво е CURSOR в PL/SQL?
Курсорът е указател към контекстната област. Oracle създава контекстна област за обработка на SQL изявление и тази област съдържа цялата информация за изявлението.
PL / SQL позволява на програмиста да контролира контекстната област чрез курсора. Курсорът съдържа редовете, върнати от SQL оператора, а наборът от редове, които курсорът съдържа, се нарича активен набор. Тези курсори могат също да бъдат именувани така, че да могат да бъдат препращани към тях от друго място в кода.
Курсорът е от два вида:
- Неявен курсор
- Явен курсор
Неявен курсор
Винаги, когато някой DML операция в базата данни се създава имплицитен курсор, който съдържа редовете, засегнати от тази конкретна операция. Тези курсори не могат да бъдат именувани и следователно не могат да бъдат контролирани или препращани към тях от друго място в кода. Можем да препращаме само към най-скорошния курсор чрез атрибутите на курсора.
Явен курсор
Програмистите имат право да създават именувана контекстна област, за да изпълняват своите DML операции и да получат по-голям контрол върху нея. Изричният курсор трябва да бъде дефиниран в секцията за декларация на PL/SQL блоки е създаден за оператора SELECT, който трябва да се използва в кода.
По-долу са стъпките, необходими за работа с явни курсори:
- Деклариране на курсора: Декларирането на курсора означава просто създаване на една именувана контекстна област за оператора SELECT, която е дефинирана в декларационната част. Името на тази контекстна област е същото като името на курсора.
- Отваряне на курсора: Отварянето на курсора инструктира PL/SQL да разпредели памет за този курсор. Това подготвя курсора за извличане на записите.
- Извличане на данни от курсора: В този процес се изпълнява командата SELECT и извлечените редове се съхраняват в разпределената памет. Те вече се наричат активни набори. Извличането на данни от курсора е дейност на ниво запис, което означава, че можем да осъществяваме достъп до данните запис по запис. Всяка команда fetch извлича един активен набор и съхранява информацията за този конкретен запис. Тази команда е същата като команда SELECT, която извлича записа и го присвоява на променливата в клаузата INTO, но няма да генерира никакви грешки. изключения.
- Затваряне на курсора: След като всички записи бъдат извлечени, трябва да затворим курсора, така че паметта, разпределена за тази контекстна област, да бъде освободена.
Синтаксис
DECLARE CURSOR <cursor_name> IS <SELECT statement>; <cursor_variable declaration>; BEGIN OPEN <cursor_name>; FETCH <cursor_name> INTO <cursor_variable>; . . CLOSE <cursor_name>; END;
В горния синтаксис, декларационната част съдържа декларацията на курсора и променливата на курсора, в която ще бъдат присвоени извлечените данни. Курсорът се създава за оператора SELECT, който е даден в декларацията на курсора. В частта за изпълнение, декларираният курсор се отваря, извлича и затваря.
Атрибути на курсора
Както имплицитният, така и експлицитният курсор имат определени атрибути, до които може да се осъществи достъп. Тези атрибути дават повече информация за операциите с курсора. По-долу са описани различните атрибути на курсора и тяхното използване.
| Атрибут на курсора | Descriptйон |
|---|---|
| % НАМЕРЕНО | Връща булевия резултат TRUE, ако последната операция по извличане е извлякла запис успешно; в противен случай връща FALSE. |
| %НЕНАМЕРЕНО | Работи обратно на %FOUND. Връща TRUE, ако последната операция за извличане не е успяла да извлече никакъв запис. |
| %ISOPEN | Връща булевия резултат TRUE, ако даденият курсор вече е отворен; в противен случай връща FALSE. |
| %ROWCOUNT | Връща числова стойност, показваща действителния брой записи, засегнати или извлечени от операцията. |
Пример за изричен курсор: В този пример ще видим как да декларираме, отворим, извлечем и затворим експлицитен курсор. Ще проектираме всички имена на служители от emp таблицата, използвайки курсор. Ще използваме и атрибут cursor, за да настроим цикъла да извлича всички записи от курсора.
Снимката на екрана по-долу показва този пример за експлицитен курсор и неговия изход в Oracle.
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%ROWCOUNT); CLOSE guru99_det; END; /
Продукция
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY Total rows fetched is 3
Code Обяснение
- Code ред 2: Деклариране на курсора guru99_det за оператора 'SELECT emp_name FROM emp'.
- Code ред 3: Деклариране на променливата lv_emp_name с %тип закотвен към emp.emp_name.
- Code ред 5: Отваряне на курсора guru99_det.
- Code ред 6: Задаване на основния цикъл за извличане на всички записи в emp таблицата.
- Code ред 7: Извлича данните от guru99_det и присвоява стойността на lv_emp_name.
- Code ред 8: Използване на атрибута на курсора %NOTFOUND за проверка дали всички записи в курсора са извлечени. Ако са извлечени, връща TRUE и управлението излиза от цикъла; в противен случай управлението продължава да извлича данните от курсора и ги отпечатва.
- Code ред 10: Условие EXIT за командата за цикъл.
- Code ред 12: Отпечатайте извлеченото име на служител.
- Code ред 14: Използване на атрибута на курсора %ROWCOUNT за намиране на общия брой записи, извлечени от курсора.
- Code ред 15: След излизане от цикъла, курсорът се затваря и разпределената памет се освобождава.
FOR Loop Cursor инструкция
Курсор FOR цикъл може да се използва за работа с курсори. Можем да зададем име на курсора вместо ограничение на диапазона в оператора на цикъла FOR, така че цикълът да работи от първия запис на курсора до последния запис на курсора. Променливата на курсора, отварянето на курсора, извличането и затварянето на курсора се извършват имплицитно от цикъла FOR.
Синтаксис
DECLARE CURSOR <cursor_name> IS <SELECT statement>; BEGIN FOR I IN <cursor_name> LOOP . . END LOOP; END;
В горния синтаксис, декларационната част съдържа декларацията на курсора. Курсорът се създава за оператора SELECT, който е даден в декларацията на курсора. В изпълнителната част, декларираният курсор се задава в цикъла FOR, а променливата на цикъла 'I' се държи като променлива на курсора в този случай.
Oracle Пример за курсор за цикъл: В този пример ще проектираме имената на всички служители от таблицата emp, използвайки цикъл cursor-FOR.
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; /
Продукция
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY
Code Обяснение
- Code ред 2: Деклариране на курсора guru99_det за оператора 'SELECT emp_name FROM emp'.
- Code ред 4: Конструиране на цикъла FOR за курсора с променливата на цикъла lv_emp_name.
- Code ред 6: Отпечатване на името на служителя във всяка итерация на цикъла.
- Code ред 7: Изход от цикъла (END LOOP).
Забележка: В цикъл cursor-FOR, атрибутите на курсора не могат да се използват, тъй като отварянето, извличането и затварянето на курсора се извършва имплицитно от цикъла FOR.

