Quelle est la différence entre les curseurs explicites et implicites dans Oracle?
Question
Je suis un peu rouillé sur mon jargon de curseur en PL / SQL. Quelqu'un le sait?
La solution
Un curseur implicite est un curseur "automatiquement". pour vous par Oracle lorsque vous exécutez une requête. Il est plus simple de coder, mais souffre de
- inefficacité (la norme ANSI spécifie qu’il faut extraire deux fois pour vérifier s’il existe plusieurs enregistrements)
- vulnérabilité aux erreurs de données (si vous obtenez deux lignes, une exception TOO_MANY_ROWS est générée)
Exemple
SELECT col INTO var FROM table WHERE something;
Un curseur explicite est celui que vous créez vous-même. Cela prend plus de code, mais donne plus de contrôle - par exemple, vous pouvez simplement ouvrir-récupérer-fermer si vous ne voulez que le premier enregistrement et ne vous souciez pas de l'existence d'autres.
Exemple
DECLARE
CURSOR cur IS SELECT col FROM table WHERE something;
BEGIN
OPEN cur;
FETCH cur INTO var;
CLOSE cur;
END;
Autres conseils
Un curseur explicite est défini comme tel dans un bloc de déclaration:
DECLARE
CURSOR cur IS
SELECT columns FROM table WHERE condition;
BEGIN
...
un curseur implicite est implémenté directement dans un bloc de code:
...
BEGIN
SELECT columns INTO variables FROM table where condition;
END;
...
1.CURSOR: Lorsque PLSQL envoie des instructions SQL, il crée un espace de travail privé. analyser & amp; exécuter l'instruction SQL s'appelle le curseur.
2.IMPLICIT: Lorsqu'un bloc PL / SQLexecutable émet une instruction SQL. PL / SQL crée un curseur implicite et gère automatiquement les moyens implcit ouvert & amp; la fermeture a lieu. Il a utilisé quand SQL retour instruction une seule ligne.Il possède 4 attributs SQL% ROWCOUNT, SQL% FOUND, SQL% NOTFOUND, SQL% ISOPEN.
3.EXPLICIT: il est créé & amp; géré par le programmeur. Il a besoin de tous time explicit open, fetch & amp; Fermer. Il est utilisé lors de l'instruction sql renvoie plus d'une ligne. Il a aussi 4 attributs CUR_NAME% ROWCOUNT, CUR_NAME% FOUND, CUR_NAME% NOTFOUND, CUR_NAME% ISOPEN. Il traite plusieurs lignes en utilisant une boucle. Le programmeur peut également passer le paramètre au curseur explicite.
- Exemple: curseur explicite
& nbsp;
declare
cursor emp_cursor
is
select id,name,salary,dept_id
from employees;
v_id employees.id%type;
v_name employees.name%type;
v_salary employees.salary%type;
v_dept_id employees.dept_id%type;
begin
open emp_cursor;
loop
fetch emp_cursor into v_id,v_name,v_salary,v_dept_id;
exit when emp_cursor%notfound;
dbms_output.put_line(v_id||', '||v_name||', '||v_salary||','||v_dept_id);
end loop;
close emp_cursor;
end;
Un curseur explicite est celui que vous déclarez, par exemple:
CURSOR my_cursor IS
SELECT table_name FROM USER_TABLES
Un curseur implicite est un curseur créé pour prendre en charge tout SQL en ligne que vous écrivez (statique ou dynamique).
Ces jours, les curseurs implicites sont plus efficaces que les curseurs explicites.
http://www.oracle.com/technology /oramag/oracle/04-sep/o54plsql.html
http: // asktom.oracle.com/pls/asktom/f?p=100:11:::::::11:QPTION_ID:1205168148688
En réponse à la première question. Directement depuis l’Oracle documentation . / p>
Un curseur est un pointeur sur un SQL privé. zone qui stocke des informations sur traiter un SELECT ou un DML spécifique déclaration.
Les curseurs implicites nécessitent une mémoire tampon anonyme.
Les curseurs explicites peuvent être exécutés encore et encore en utilisant leur nom. Ils sont stockés dans un espace mémoire défini par l'utilisateur plutôt que dans une mémoire tampon anonyme et sont donc facilement accessibles par la suite.
Avec les curseurs explicites, vous avez un contrôle complet sur la manière d’accéder aux informations de la base de données. Vous décidez quand OUVRIR le curseur, quand FETCH enregistre à partir du curseur (et donc de la ou des tables dans l'instruction SELECT du curseur), combien d'enregistrements à extraire et quand FERMER le curseur. Des informations sur l'état actuel de votre curseur sont disponibles en examinant les attributs du curseur.
Voir http://www.unix.com.ua/ orelly / oracle / prog2 / ch06_03.htm pour plus de détails.
Google est votre ami: http://docstore.mik.ua/ orelly / oracle / prog2 / ch06_03.htm
PL / SQL émet un curseur implicite chaque fois que vous exécutez une instruction SQL directement dans votre code, tant que cela le code n'emploie pas explicitement le curseur. C'est ce qu'on appelle un "implicite" curseur parce que vous, le développeur, faites pas explicitement déclarer un curseur pour l'instruction SQL.
Un curseur explicite est un SELECT déclaration explicitement définie dans la section déclaration de votre code et, dans le processus, assigné un prénom. Il n’existe pas de curseur explicite pour UPDATE, DELETE, et INSERT déclarations.
Un curseur est une fenêtre SÉLECTIONNÉE sur une table Oracle. Il s’agit d’un groupe d’enregistrements présents dans une table Oracle et satisfaisant à certaines conditions. Un curseur peut aussi SÉLECTIONNER tout le contenu d'une table. Avec un curseur, vous pouvez manipuler les colonnes Oracle, en les aliasant dans le résultat. Voici un exemple de curseur implicite:
BEGIN
DECLARE
CURSOR C1
IS
SELECT DROPPED_CALLS FROM ALARM_UMTS;
C1_REC C1%ROWTYPE;
BEGIN
FOR C1_REC IN C1
LOOP
DBMS_OUTPUT.PUT_LINE ('DROPPED CALLS: ' || C1_REC.DROPPED_CALLS);
END LOOP;
END;
END;
/
Avec FOR ... LOOP ... END LOOP, vous ouvrez et fermez automatiquement le curseur lorsque tous les enregistrements du curseur ont été analysés.
Voici un exemple de curseur explicite:
BEGIN
DECLARE
CURSOR C1
IS
SELECT DROPPED_CALLS FROM ALARM_UMTS;
C1_REC C1%ROWTYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO c1_rec;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE ('DROPPED CALLS: ' || C1_REC.DROPPED_CALLS);
END LOOP;
CLOSE c1;
END;
END;
/
Dans le curseur explicite, vous ouvrez et fermez le curseur de manière explicite, en vérifiant la présence d'enregistrements et en indiquant une condition de sortie.
Le curseur implicite ne renvoie qu'un seul enregistrement et est appelé automatiquement. Cependant, les curseurs explicites sont appelés manuellement et peuvent renvoyer plusieurs enregistrements.
Je sais que c'est une vieille question, mais je pense qu'il serait bon d'ajouter un exemple concret pour montrer la différence entre les deux du point de vue des performances.
Du point de vue des performances, les curseurs implicites sont plus rapides.
Voyons la différence de performance entre les deux:
SQL> SET SERVEROUTPUT ON
SQL> DECLARE
2 l_loops NUMBER := 100000;
3 l_dummy dual.dummy%TYPE;
4 l_start NUMBER;
5
6 CURSOR c_dual IS
7 SELECT dummy
8 FROM dual;
9 BEGIN
10 l_start := DBMS_UTILITY.get_time;
11
12 FOR i IN 1 .. l_loops LOOP
13 OPEN c_dual;
14 FETCH c_dual
15 INTO l_dummy;
16 CLOSE c_dual;
17 END LOOP;
18
19 DBMS_OUTPUT.put_line('Explicit: ' ||
20 (DBMS_UTILITY.get_time - l_start) || ' hsecs');
21
22 l_start := DBMS_UTILITY.get_time;
23
24 FOR i IN 1 .. l_loops LOOP
25 SELECT dummy
26 INTO l_dummy
27 FROM dual;
28 END LOOP;
29
30 DBMS_OUTPUT.put_line('Implicit: ' ||
31 (DBMS_UTILITY.get_time - l_start) || ' hsecs');
32 END;
33 /
Explicit: 332 hsecs
Implicit: 176 hsecs
PL/SQL procedure successfully completed.
Ainsi, une différence significative est clairement visible.
Autres exemples ici .
En PL / SQL, un curseur est un pointeur sur cette zone de contexte. Il contient toutes les informations nécessaires au traitement de la déclaration.
Curseurs implicites: Les curseurs implicites sont automatiquement créés par Oracle chaque fois qu'une instruction SQL est exécutée, lorsqu'il n'existe aucun curseur explicite pour cette instruction. Les programmeurs ne peuvent pas contrôler les curseurs implicites et les informations qu’ils contiennent.
Curseurs explicites: Les curseurs explicites sont des curseurs définis par le programmeur permettant de mieux contrôler la zone de contexte. Un curseur explicite doit être défini dans la section déclaration du bloc PL / SQL. Il est créé sur une instruction SELECT qui renvoie plusieurs lignes.
La syntaxe pour créer un curseur explicite est:
CURSOR cursor_name IS select_statement;
Chaque instruction SQL exécutée par la base de données Oracle est associée à un curseur, qui est une zone de travail privée pour stocker les informations de traitement. Des curseurs implicites sont créés implicitement par le serveur Oracle pour toutes les instructions DML et SELECT.
Vous pouvez déclarer et utiliser des curseurs Explicit pour nommer la zone de travail privée et accéder à ses informations stockées dans votre bloc de programme.
Comme indiqué dans d'autres réponses, les curseurs implicites sont plus faciles à utiliser et moins sujets aux erreurs.
Et Curseurs implicite / explicite dans Oracle PL / SQL montre que les curseurs implicites sont jusqu'à deux fois plus rapides que les curseurs explicites également.
Il est étrange que personne n'ait encore mentionné Implicitement pour LO LOOP Curseur :
begin
for cur in (
select t.id from parent_trx pt inner join trx t on pt.nested_id = t.id
where t.started_at > sysdate - 31 and t.finished_at is null and t.extended_code is null
)
loop
update trx set finished_at=sysdate, extended_code = -1 where id = cur.id;
update parent_trx set result_code = -1 where nested_id = cur.id;
end loop cur;
end;
Un autre exemple sur SO: PL / SQL POUR LE CURSEUR IMPLICITE DE BOUCLE .
C'est beaucoup plus court que la forme explicite.
Ceci fournit également une solution de contournement intéressante pour mettre à jour plusieurs tables à partir de CTE .
Explicite ...
le curseur foo est select * from blah; commencer ouvrir chercher sortir quand fermer le curseur yada yada yada
ne les utilisez pas, utilisez implicite
le curseur foo est choisi * parmi blah;
pour n in foo loop x = n.some_column boucle de fin
Je pense que vous pouvez même le faire
pour n dans la boucle (select * from blah) ...
Tenez-vous en à l’implicite, ils se ferment, ils sont plus lisibles, ils facilitent la vie.