web-dev-qa-db-fra.com

Quelle est la différence entre les curseurs explicites et implicites dans Oracle?

Je suis un peu rouillé sur mon curseur de jargon en PL/SQL. Quelqu'un sait ça?

25
Brian G

Un curseur implicite est un curseur "automatiquement" créé pour vous par Oracle lorsque vous exécutez une requête. Il est plus simple de coder, mais souffre de 

  • inefficacité (le standard ANSI spécifie qu'il doit aller chercher deux fois pour vérifier s'il y a plus d'un enregistrement)
  • 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 voulez seulement 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;
39
Sten Vesterli

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;
...
16
stjohnroe

1.CURSOR: Lorsque PLSQL émet des instructions SQL, il crée un espace de travail privé analyser et exécuter l’instruction SQL s’appelle curseur.

2.IMPLICIT: Quand un bloc PL/SQLexecutable émet une instruction SQL . PL/SQL crée un curseur implicite et gère automatiquement les moyens implcit ouvrir & fermer a lieu. Il était utilisé lorsque l'instruction SQL retournait une seule ligne.Il possède 4 attributs SQL% ROWCOUNT, SQL% FOUND, SQL% NOTFOUND, SQL% ISOPEN.

3.EXPLICIT: Il est créé et géré par le programmeur. Il a besoin de tout temps explicite ouvrir, chercher et 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 aussi passer le paramètre au curseur explicite.

  • Exemple: curseur explicite

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;
4
Ganesh Pathare

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 ultérieurement.

3
prince
3
pablo

Un curseur explicite est celui que vous déclarez, comme:

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).

3
Dave Costa

En réponse à la première question. Directement d'Oracle documentation

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.

3
Ian Carpenter

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 à récupérer 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.

2
Kristian

Un curseur est une fenêtre SÉLECTIONNÉE sur une table Oracle. Cela signifie un groupe d'enregistrements présents dans une table Oracle et satisfaisant à certaines conditions. Un curseur peut également SÉLECTIONNER tout le contenu d'une table. Avec un curseur, vous pouvez manipuler les colonnes Oracle, en les aliasant dans le résultat. Un exemple de curseur implicite est le suivant:

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 le curseur automatiquement, une fois que tous les enregistrements du curseur ont été analysés.

Un exemple de curseur explicite est le suivant:

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.

1
UltraCommit

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 un .__ explicite. 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 qui est 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 INSÉRER des déclarations.

1
Derek Swingley

Le curseur implicite ne renvoie qu'un seul enregistrement et est appelé automatiquement. Toutefois, les curseurs explicites sont appelés manuellement et peuvent renvoyer plusieurs enregistrements.

1
shaiksyedbasha

Je sais que la question est ancienne, 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.

Plus d'exemples ici .

1
Lalit Kumar B

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.

0
ropable

Comme indiqué dans d'autres réponses, les curseurs implicites sont plus faciles à utiliser et moins sujets aux erreurs. 

Et Curseurs implicites ou explicites dans Oracle PL/SQL montre que les curseurs implicites sont jusqu'à deux fois plus rapides que les explicites.

C'est étrange que personne n'ait encore mentionné implicite pour le curseur LO LOOP :

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 FOR CURSEUR IMPLICITE LOOP .

C'est beaucoup plus court que la forme explicite.

Cela fournit également une solution de contournement de Nice pour mettre à jour plusieurs tables à partir de CTE .

0
Vadzim