web-dev-qa-db-fra.com

Pourquoi no_data_found ORA-01403 est-il une exception dans Oracle?

Si l'instruction SELECT INTO ne renvoie pas au moins une ligne, ORA-01403 est levée.

Pour tous les autres SGBD, je sais que c'est normal sur un SELECT. Seul Oracle traite un SELECT INTO comme ceci.

CREATE OR REPLACE PROCEDURE no_data_proc IS
   dummy dual.dummy%TYPE;
BEGIN
  BEGIN 
     SELECT dummy  
       INTO dummy
       FROM dual
      WHERE dummy = 'Y';   
  EXCEPTION 
     WHEN no_data_found THEN
        dbms_output.put_line('Why is this needed?');
  END;
END no_data_proc;

Pourquoi?

À mon avis, vous n'avez pas vraiment besoin de cette exception. C'est trop de frais généraux. Parfois, c'est pratique mais vous devez écrire un bloc BEGIN, EXCEPTION, WHEN, END complet.

Y a-t-il des raisons essentielles que je ne vois pas?

18
Stephan Schielke

Le bloc d'exception n'est pas nécessaire , vous pouvez l'utiliser ou non, selon le contexte.

Ici, vous ignorez activement l'exception (la procédure retournera avec succès) mais la plupart du temps si vous effectuez un SELECT INTO, vous voulez qu'il --- échec s'il ne retourne pas de ligne, pensez à:

PROCEDURE update_employee_salary (p_empno) IS
   l_salary NUMBER;
BEGIN
   SELECT sal INTO l_salary FROM emp WHERE empno = p_empno FOR UPDATE;
   /* do something with emp data */
END;

Ici, je veux que ma fonction échoue si elle est appelée avec un empno qui n'existe pas dans la table EMP. Je peux intercepter l'exception pour déclencher un message d'erreur significatif (avec raise_application_error) mais la plupart du temps je suis content de l'ORA-01403.

En général, les seules exceptions que vous devez intercepter sont les exceptions attendues (c'est-à-dire que cela ne devrait pas être la norme pour intercepter toutes les ORA-01403, ou toutes les exceptions d'ailleurs).

19
Vincent Malgrat

Mais nous devons encore répondre à la question "pourquoi une exception est-elle levée dans le cas où un SELECT n'a pas de données à récupérer".

Je crois que cela se fait parce que c'est une situation courante qui pourrait autrement être négligée. Écrire du code comme s'il s'attendait toujours à trouver des données est une chose courante à faire, et si nous étions censés effectuer des vérifications d'erreurs telles que

SELECT <something...>
IF SQLCODE = 100 THEN -- No data found
  <no-data handler>
END IF

il est probable à mon humble avis que la vérification de SQLCODE = 100 soit sautée fréquemment. Une exception ayant soulevé des béliers, vous avez directement remarqué que A) une condition importante (aucune donnée trouvée) s'est produite, et B) AUCUNE INDEMNITÉ N'A ÉTÉ FAITE POUR CELA. IMO ayant le moteur PL/SQL lever une exception est mieux que d'avoir le programme continuer joyeusement sur son chemin en supposant que les données ont été récupérées alors qu'en fait ce n'était pas le cas, ce qui peut conduire à toutes sortes de problèmes autres que joyeux.

Partagez et profitez.

12
Bob Jarvis

Vous pouvez essayer d'utiliser MIN pour éviter d'utiliser la clause EXCEPTION.

 SELECT MIN(dummy)  
   INTO dummy
   FROM dual
  WHERE dummy = 'Y'; 

alors la variable fictive sera NULL

7
Michael Pakhantsov

Parce que vous faites SELECT INTO qui nécessite exactement une ligne (plus de lignes seraient également une erreur).

Si vous pouvez avoir une ou aucune ligne, vous pouvez utiliser un curseur.

Ce n'est pas le travail de la base de données de décider pour vous qu'une ligne manquante n'est pas une erreur, et définissez simplement la valeur sur null.

3
Thilo

Vous pouvez également utiliser les fonctions sql MAX ou MIN . Si aucune ligne n'est renvoyée, ces fonctions renverront un NULL .

Par exemple: Sélectionnez MAX (column1) Dans la variable From Table Where Column1 = 'Value';

La fonction MAX renverra la valeur maximale ou si aucune ligne n'est renvoyée, elle renverra NULL.

2
Immortal Code

Parce que ce que le moteur PL/SQL doit faire n'est pas clair - doit-il quitter le bloc? Doit-il continuer avec NULL dans la variable? Que se passe-t-il si dans le bloc suivant vous essayez d'insérer cela dans une colonne NOT NULL, comment doit-il signaler l'emplacement de l'erreur? En faire une exception vous oblige à être explicite à ce sujet.

1
Gaius

La fonction MAX fonctionne, elle ne génère pas d'erreur ORA-014 fonctionne lorsque NULL est renvoyé en sélectionnant INTO

1
Gaurav londhe