Oracle Curseur PL/SQL : implicite, explicite, boucle For avec exemple

โšก Rรฉsumรฉ intelligent

Curseurs dans Oracle En PL/SQL, les curseurs pointent vers la zone de contexte qui contient les lignes renvoyรฉes par une instruction SQL. Il en existe deux types : les curseurs implicites, crรฉรฉs automatiquement pour les opรฉrations DML, et les curseurs explicites, dรฉclarรฉs et contrรดlรฉs par le programmeur.

  • ๐Ÿ“ Zone de contexte : Un curseur pointe vers la zone de contexte qui stocke une instruction SQL et son ensemble actif renvoyรฉ.
  • โš™๏ธ Curseur implicite : Oracle ouvre automatiquement un curseur implicite pour chaque instruction DML et SELECT INTO sur une seule ligne.
  • โœ‹ Curseur explicite : Un programmeur dรฉclare, ouvre, rรฉcupรจre et ferme un curseur explicite pour obtenir un contrรดle total.
  • ???? Attributs du curseur : %FOUND, %NOTFOUND, %ISOPEN et %ROWCOUNT indiquent l'รฉtat de l'opรฉration la plus rรฉcente.
  • (I.e. Boucle FOR avec curseur : Une boucle FOR ouvre, rรฉcupรจre et ferme un curseur implicitement, sans nรฉcessiter d'intervention manuelle.
  • ๐Ÿค– Assistance IA : Les assistants IA tels que GitHub Copilot bloquent les boucles de curseur et signalent les curseurs non fermรฉs.

Oracle Courant PL/SQL implicite, explicite et boucle FOR

Quโ€™est-ce que CURSEUR en PL/SQL ?

Un curseur est un pointeur vers la zone de contexte. Oracle crรฉe une zone de contexte pour le traitement d'un SQL dรฉclaration, et cette zone contient toutes les informations relatives ร  la dรฉclaration.

PL / SQL Le curseur permet au programmeur de contrรดler la zone de contexte. Il contient les lignes renvoyรฉes par l'instruction SQL, et l'ensemble de ces lignes est appelรฉ ensemble actif. Ces curseurs peuvent รชtre nommรฉs afin de pouvoir y faire rรฉfรฉrence depuis un autre endroit du code.

Le curseur est de deux types :

  • Curseur implicite
  • Curseur explicite

Curseur implicite

Chaque fois que Opรฉration DML Lorsqu'une opรฉration a lieu dans la base de donnรฉes, un curseur implicite est crรฉรฉ, contenant les lignes affectรฉes par cette opรฉration. Ces curseurs ne peuvent pas รชtre nommรฉs et, par consรฉquent, ne peuvent รชtre ni contrรดlรฉs ni rรฉfรฉrencรฉs depuis un autre endroit du code. Seul le curseur le plus rรฉcent peut รชtre consultรฉ via ses attributs.

Curseur explicite

Les programmeurs peuvent crรฉer une zone de contexte nommรฉe pour exรฉcuter leurs opรฉrations DML et en obtenir un meilleur contrรดle. Le curseur explicite doit รชtre dรฉfini dans la section de dรฉclaration du Bloc PL/SQLet elle est crรฉรฉe pour l'instruction SELECT qui doit รชtre utilisรฉe dans le code.

Voici les รฉtapes ร  suivre pour travailler avec des curseurs explicites :

  • Dรฉclaration du curseur : Dรฉclarer le curseur revient simplement ร  crรฉer une zone de contexte nommรฉe pour l'instruction SELECT dรฉfinie dans la partie dรฉclaration. Le nom de cette zone de contexte est identique ร  celui du curseur.
  • Ouverture du curseur : L'ouverture du curseur indique ร  PL/SQL d'allouer la mรฉmoire nรฉcessaire ร  ce curseur, le rendant ainsi prรชt ร  extraire les enregistrements.
  • Rรฉcupรฉration des donnรฉes ร  partir du curseur : Dans ce processus, l'instruction SELECT est exรฉcutรฉe et les lignes extraites sont stockรฉes dans la mรฉmoire allouรฉe. On les appelle alors des ensembles actifs. L'extraction de donnรฉes ร  partir du curseur est une opรฉration au niveau de l'enregistrement, ce qui signifie que nous pouvons accรฉder aux donnรฉes enregistrement par enregistrement. Chaque instruction FITCH extrait un ensemble actif et contient les informations de cet enregistrement particulier. Cette instruction est identique ร  une instruction SELECT qui extrait l'enregistrement et l'affecte ร  la variable de la clause INTO, mais elle ne lรจvera aucune exception. exceptions.
  • Fermeture du curseur : Une fois tous les enregistrements rรฉcupรฉrรฉs, nous devons fermer le curseur afin que la mรฉmoire allouรฉe ร  cette zone de contexte soit libรฉrรฉe.

Syntaxe

DECLARE
CURSOR <cursor_name> IS <SELECT statement>;
<cursor_variable declaration>;
BEGIN
OPEN <cursor_name>;
FETCH <cursor_name> INTO <cursor_variable>;
.
.
CLOSE <cursor_name>;
END;

Dans la syntaxe ci-dessus, la dรฉclaration contient la dรฉfinition du curseur et de la variable de curseur qui recevra les donnรฉes extraites. Le curseur est crรฉรฉ pour l'instruction SELECT spรฉcifiรฉe dans sa dรฉclaration. L'exรฉcution du curseur consiste ร  l'ouvrir, ร  y extraire les donnรฉes, puis ร  le fermer.

Attributs du curseur

Le curseur implicite et le curseur explicite possรจdent tous deux certains attributs accessibles. Ces attributs fournissent des informations supplรฉmentaires sur les opรฉrations du curseur. Vous trouverez ci-dessous les diffรฉrents attributs du curseur et leur utilisation.

Attribut du curseur Description
%A TROUVร‰ Renvoie la valeur boolรฉenne TRUE si la derniรจre opรฉration de rรฉcupรฉration a permis de rรฉcupรฉrer un enregistrement avec succรจs ; sinon, elle renvoie FALSE.
%PAS TROUVร‰ Fonctionne ร  l'inverse de %FOUND. Renvoie TRUE si la derniรจre opรฉration de rรฉcupรฉration n'a permis de rรฉcupรฉrer aucun enregistrement.
%EST OUVERT Renvoie la valeur boolรฉenne TRUE si le curseur donnรฉ est dรฉjร  ouvert ; sinon, elle renvoie FALSE.
% ROWCOUNT Renvoie une valeur numรฉrique indiquant le nombre rรฉel d'enregistrements affectรฉs ou rรฉcupรฉrรฉs par l'opรฉration.

Exemple de curseur explicite : Dans cet exemple, nous verrons comment dรฉclarer, ouvrir, rรฉcupรฉrer et fermer un curseur explicite. Nous projetterons tous les noms des employรฉs de la table ยซ emp ยป ร  l'aide d'un curseur. Nous utiliserons รฉgalement un attribut de curseur pour dรฉfinir la boucle permettant de rรฉcupรฉrer tous les enregistrements.

La capture d'รฉcran ci-dessous montre cet exemple de curseur explicite et sa sortie. Oracle.

Exemple de curseur explicite rรฉcupรฉrant les noms des employรฉs de la table emp dans Oracle PL / SQL

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;
/

Sortie

Employee Fetched:BBB
Employee Fetched:XXX
Employee Fetched:YYY
Total rows fetched is 3

Code Explication

  • Code ligne 2: Dรฉclaration du curseur guru99_det pour l'instruction 'SELECT emp_name FROM emp'.
  • Code ligne 3: Dรฉclarer la variable lv_emp_name avec le %type ancrรฉ ร  emp.emp_name.
  • Code ligne 5: Ouverture du curseur guru99_det.
  • Code ligne 6: Dรฉfinition de l'instruction de boucle de base pour rรฉcupรฉrer tous les enregistrements de la table emp.
  • Code ligne 7: Rรฉcupรจre les donnรฉes guru99_det et attribue la valeur ร  lv_emp_name.
  • Code ligne 8: L'attribut %NOTFOUND du curseur permet de vรฉrifier si tous les enregistrements ont รฉtรฉ rรฉcupรฉrรฉs. Si c'est le cas, la fonction renvoie TRUE et l'exรฉcution s'arrรชte ; sinon, elle continue ร  rรฉcupรฉrer les donnรฉes et les affiche.
  • Code ligne 10: Condition EXIT pour l'instruction de boucle.
  • Code ligne 12: Imprimez le nom de l'employรฉ rรฉcupรฉrรฉ.
  • Code ligne 14: Utilisez l'attribut de curseur %ROWCOUNT pour trouver le nombre total d'enregistrements rรฉcupรฉrรฉs par le curseur.
  • Code ligne 15: Une fois la boucle terminรฉe, le curseur est fermรฉ et la mรฉmoire allouรฉe est libรฉrรฉe.

Instruction de curseur de boucle FOR

Un curseur Boucle POUR On peut utiliser la boucle FOR pour manipuler les curseurs. Au lieu de spรฉcifier une plage de valeurs, on peut indiquer le nom du curseur afin que la boucle parcoure les enregistrements du premier au dernier. La variable curseur, son ouverture, sa lecture et sa fermeture sont gรฉrรฉes implicitement par la boucle FOR.

Syntaxe

DECLARE
CURSOR <cursor_name> IS <SELECT statement>;
BEGIN
FOR I IN <cursor_name>
LOOP
.
.
END LOOP;
END;

Dans la syntaxe ci-dessus, la dรฉclaration contient la dรฉclaration du curseur. Ce curseur est crรฉรฉ pour l'instruction SELECT spรฉcifiรฉe dans sa dรฉclaration. Dans la partie exรฉcution, le curseur dรฉclarรฉ est initialisรฉ dans la boucle FOR, et la variable de boucle ยซ I ยป joue alors le rรดle de la variable de curseur.

Oracle Exemple de boucle avec curseur : Dans cet exemple, nous allons extraire tous les noms des employรฉs de la table emp ร  l'aide d'une boucle curseur-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;
/

Sortie

Employee Fetched:BBB
Employee Fetched:XXX
Employee Fetched:YYY

Code Explication

  • Code ligne 2: Dรฉclaration du curseur guru99_det pour l'instruction 'SELECT emp_name FROM emp'.
  • Code ligne 4: Construction de la boucle FOR pour le curseur avec la variable de boucle lv_emp_name.
  • Code ligne 6: Impression du nom de l'employรฉ ร  chaque itรฉration de la boucle.
  • Code ligne 7: Sortir de la boucle (FIN DE BOUCLE).

ร€ noter: Dans une boucle FOR avec curseur, les attributs du curseur ne peuvent pas รชtre utilisรฉs, car l'ouverture, la rรฉcupรฉration et la fermeture du curseur sont effectuรฉes implicitement par la boucle FOR.

FAQ

Un curseur de rรฉfรฉrence (REF CURSOR) est un pointeur vers un ensemble de rรฉsultats de requรชte. Contrairement ร  un curseur statique, il peut ouvrir diffรฉrentes requรชtes lors de l'exรฉcution et transmettre des rรฉsultats entre des blocs PL/SQL ou ร  des programmes clients.

Un curseur normal rรฉcupรจre une ligne par FETCH, ce qui entraรฎne de nombreux changements de contexte. COLLECTE EN VRAC charge de nombreuses lignes dans une collection en une seule requรชte, rรฉduisant considรฉrablement la surcharge sur les grands ensembles de rรฉsultats.

Oui. Dรฉclarez un curseur paramรฉtrรฉ, par exemple CURSOR c(dept NUMBER) IS SELECT โ€ฆ, puis transmettez les valeurs ร  OPEN c(10). Les paramรจtres vous permettent de rรฉutiliser une mรชme dรฉfinition de curseur avec diffรฉrentes valeurs de filtre.

La clause FOR UPDATE verrouille les lignes sรฉlectionnรฉes par le curseur afin d'empรชcher toute modification ultรฉrieure. La clause WHERE CURRENT OF met ensuite ร  jour ou supprime la ligne exacte qui vient d'รชtre extraite, sans rรฉpรฉter la condition WHERE.

Les curseurs ouverts conservent de la mรฉmoire rรฉservรฉe et sont comptabilisรฉs dans la limite OPEN_CURSORS. Laisser un grand nombre de curseurs ouverts finit par gรฉnรฉrer l'erreur ORA-01000 : nombre maximal de curseurs ouverts dรฉpassรฉ. Il est donc impรฉratif de fermer explicitement un curseur aprรจs utilisation.

Chaque requรชte FETCH alterne entre les moteurs PL/SQL et SQL. Des milliers de ces changements de contexte s'accumulent, si bien qu'une seule instruction SQL ensembliste ou BULK COLLECT traite gรฉnรฉralement les mรชmes lignes beaucoup plus rapidement.

Oui. Copilote GitHub ร‰bauche des boucles OPEN, FETCH et CLOSE explicites ou des boucles FOR avec curseur ร  partir d'un commentaire, ajoute des vรฉrifications de sortie %NOTFOUND et suggรจre des noms d'attributs, bien que vous deviez d'abord examiner la logique.

Les assistants IA signalent les boucles de curseur ligne par ligne susceptibles de se transformer en requรชtes SQL ensemblistes ou en opรฉrations BULK COLLECT, repรจrent les curseurs non fermรฉs et expliquent le comportement de l'attribut %attribute. Cette analyse par apprentissage automatique amรฉliore les performances avant la mise en production du code.

Rรฉsumez cet article avec :