选择导致异常的查询

时间:2009-12-09 06:52:07

标签: sql oracle exception function

以下sql函数何时可以导致除NO DATA FOUND以外的异常? v_ExchangeRate的类型为float。rate列的数据类型为NUMBER(14,10),此列不能包含NULL值。

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

数据库中exchange_rate的数据类型为NUMBER(14,10)

修改 由于currency_code是主键,因此where子句不能返回多行。

5 个答案:

答案 0 :(得分:2)

你想在这里解决什么问题,还是这只是一个理论问题?如果引发异常并且您使用WHEN OTHERS子句对其进行抑制,则删除该子句 - 它的存在是编码错误(即错误)。

答案 1 :(得分:2)

可能的例外情况(无论如何都不是详尽的清单):

1)ORA-00942:表或视图不存在

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

2)ORA-06502:PL / SQL:数字或值错误:字符到数字转换错误

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

3)ORA-06502:PL / SQL:数字或值错误:字符串缓冲区太小

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

4)ORA-01722:无效数字

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

您是否可以创建该函数的副本,删除WHEN OTHERS部分,并在SQL Plus或IDE中测试它以查看您获得的异常?

答案 2 :(得分:1)

执行SQL跟踪可能会显示异常(如果它是由SQL而不是PL / SQL引发的)。

或者,DBMS_TRACE能够记录异常,即使它们被异常处理程序捕获也是如此。但是你必须安装支持表。

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;

现在进行演示:

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

通过清除任何旧垃圾的表来运行测试,设置标志并执行过程

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

然后查询结果。

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

我们可以看到在第6行引发了一个异常,并且它在第11行被捕获。后者也非常重要。如果你有一些复杂的代码,那么调用层次结构中的几个级别的异常处理程序可能“处理”它从未打算过的异常。您甚至可以看到错误编号,如果被其他人抓住,则会很方便。

答案 3 :(得分:0)

也许我有点失落,但什么是CurrencyCode?我猜exchange_rate和ExchangeRate是数据库中的表?有一个名为exchange_rate的列和表是令人困惑的,除非这是问题的一部分。

答案 4 :(得分:0)

粘贴您的完整存储过程,其真正令人困惑的exchange_rate表或列和货币代码。我觉得用于列id和表名的相同变量给出了异常