2009-12-09 7 views
-1

Quand la fonction sql below peut-elle provoquer une exception autre que NO DATA FOUND? v_ExchangeRate est de type float.Le type de données de la colonne de taux est NUMBER (14, 10) et cette colonne ne peut pas contenir de valeurs NULL.Sélectionner une requête provoquant une exception

BEGIN 
SELECT rate 
INTO v_ExchangeRate 
FROM exchange_rate 
WHERE currency_code = CurrencyCode 
AND status  = 'A'; 

Le type de exchange_rate dans la base de données est le numéro (14,10)

Modifier lignes multiples ne peuvent pas être renvoyés par la clause where comme currency_code est la clé primaire.

+0

quelle exception? quel type de dbms? mysql/sql server/oracle? – shahkalpesh

+1

En supposant que le SGBDR est Oracle. Si vous n'avez pas de contrainte telle que currency_code avec Status = 'A' est unique, vous risquez d'avoir une trop grande exception de lignes. (Le nom exact m'échappe.) –

+0

Autre que l'exception NO DATA FOUND, j'utilise proC avec la base de données oracle –

Répondre

2

exceptions possibles (liste non exhaustive par tout moyen):

1) ORA-00942: table ou vue n'existe pas

declare 
    var integer; 
begin 
    select 1 into var from nosuchtable; 
end; 

2) ORA-06502: PL/SQL: numérique ou d'une erreur de valeur: le caractère d'une erreur de conversion du nombre

declare 
    var integer; 
begin 
    select 'x' into var from dual; 
end; 

3) ORA-06502: PL/SQL: erreur numérique ou de la valeur: tampon de chaîne de caractères trop petit

declare 
    var varchar2(1); 
begin 
    select 'xx' into var from dual; 
end; 

4) ORA-01722: numéro incorrect

SQL> create table t1 (n1 number); 

Table created. 

SQL> insert into t1 values (1); 

1 row created. 

SQL> declare 
    2 var varchar2(1); 
    3 begin 
    4 select 'x' into var 
    5 from t1 where n1 = 'y'; 
    6 end; 
    7/
declare 
* 
ERROR at line 1: 
ORA-01722: invalid number 
ORA-0512: at line 4 

Pouvez-vous pas créer une copie de la fonction, retirez le WHEN OTHERS part, et le tester dans SQL Plus ou un IDE pour voir ce que exception vous obtenez? Faire une trace SQL PEUT montrer l'exception (si elle a soulevé par SQL plutôt que le PL/SQL)

+0

+1 pour de bons détails pour les exceptions –

0

Peut-être que je suis un peu perdu, mais qu'est-ce que CurrencyCode? Je devine exchange_rate et ExchangeRate sont des tables dans votre base de données? Il est déroutant d'avoir une colonne et une table nommée exchange_rate, sauf si cela fait partie du problème.

+0

Pour éviter la confusion, j'ai renommé exchange_rate pour évaluer, Maintenant rate est la colonne et change_rate est le nom de table.Je récupère la colonne de taux dans la variable echangeur à l'aide de la clé primart donc toujours une seule ligne sera retournée –

0

Collez également votre procédure stockée complète, sa table exchange_rate ou code de colonne et de devise vraiment confus. Je pense que la même variable utilisée pour l'ID de colonne et le nom de table donne l'exception

+0

Permet de la vérifier une fois, j'ai ajouté v_ devant le nom de la variable –

2

Quel problème essayez-vous de résoudre ici, ou est-ce juste une question théorique? Si une exception est levée et que vous la supprimez avec une clause WHEN OTHERS, supprimez cette clause - sa présence est une erreur de codage (c'est-à-dire un bogue).

+0

Je ne peux pas modifier le code tel qu'il est utilisé par un système en ligne, je sais juste en passant en revue le code que l'exception causée est autre que NO ROWS FOUND –

+0

Vous avez donc une clause WHEN OTHERS qui supprime une erreur? –

+0

Oui, j'ai une clause WHEN OTHERS –

1

La variante DBMS_TRACE a la capacité d'enregistrer des exceptions même lorsqu'elles sont interceptées par un gestionnaire d'exceptions. Mais vous devrez installer les tables de soutien.

D:\oraclexe\app\oracle\product\10.2.0\server\RDBMS\ADMIN>sqlplus/as sysdba 

SQL*Plus: Release 10.2.0.1.0 - Production on Mon Dec 14 09:24:45 2009 
Copyright (c) 1982, 2005, Oracle. All rights reserved. 
Connected to: 
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production 
SQL> @tracetab.sql 
SQL> CREATE PUBLIC SYNONYM plsql_trace_runs FOR plsql_trace_runs; 
SQL> CREATE PUBLIC SYNONYM plsql_trace_events FOR plsql_trace_events; 
SQL> CREATE PUBLIC SYNONYM plsql_trace_runnumber FOR plsql_trace_runnumber; 
SQL> GRANT SELECT, INSERT, UPDATE, DELETE ON plsql_trace_runs TO PUBLIC; 
SQL> GRANT SELECT, INSERT, UPDATE, DELETE ON plsql_trace_events TO PUBLIC; 
SQL> GRANT SELECT ON plsql_trace_runnumber TO PUBLIC; 

maintenant pour une démonstration:

create or replace 
procedure test_trace is 
    v_test varchar2(3); 
begin 
    select '12' into v_test from dual; 
    select '123' into v_test from dual; 
    select '1234' into v_test from dual; 
    select '12345' into v_test from dual; 
exception 
    when value_error then 
    null; 
end; 
/

Exécutez le test en dégageant la table de tout vieilleries, mettre le drapeau et exécuter la procédure

delete from plsql_trace_events; 
commit; 
exec DBMS_TRACE.set_plsql_trace (DBMS_TRACE.trace_all_exceptions); 
exec test_trace; 

ensuite interroger les résultats .

select event_kind, event_unit, event_line, stack_depth, excp, event_comment, callstack, errorstack 
from plsql_trace_events 
where event_kind not in (38,40,43,44) 
order by event_seq; 

EVENT_KIND EVENT_UNIT      EVENT_LINE STACK_DEPTH  EXCP 
----------- ------------------------------- ----------- ----------- ----------- 
EVENT_COMMENT 
---------------------------------------------------------------------------------- 
CALLSTACK 
---------------------------------------------------------------------------------- 
ERRORSTACK 
---------------------------------------------------------------------------------- 
     52.00 TEST_TRACE        6.00  2.00 6,502.00 
Exception raised 
----- PL/SQL Call Stack ----- 
    object  line object 
    handle number name 
3BF0F6D4   6 procedure GARY.TEST_TRACE 
3BDF1764   1 anonymous block 
ORA-06502: PL/SQL: numeric or value error: character string buffer too small 

     53.00 TEST_TRACE       11.00  2.00 6,502.00 
Exception handled 

On peut voir une exception a été soulevée à la ligne 6 et le fait qu'il a été pris à la ligne 11. Ce dernier est aussi très important. Si vous avez du code complexe, il n'est pas impossible qu'un gestionnaire d'exceptions à un ou deux niveaux de la hiérarchie d'appels puisse 'gérer' une exception pour laquelle il n'a jamais été prévu. Vous pouvez même voir le numéro d'erreur qui est pratique si elle a été attrapée par un autre.

Questions connexes