在例外之后打印消息" ZERO NOT DIVISBLE"

时间:2018-02-12 17:34:50

标签: oracle function oracle11g

使用Oracle 11g,在SQL Developer的SQL Developer出口和输出脚本中,我希望在创建以下函数后看到一些结果。

CREATE OR REPLACE
FUNCTION FN_DIVISION(NUMBER1 NUMBER, NUMBER2 NUMBER)
    RETURN NUMBER
IS
    RESULTS NUMBER;
    V_RESULT NUMBER;
    ERR_NUM NUMBER;
    ERR_MSG VARCHAR2(255);
BEGIN
    SELECT NUMBER1 / NUMBER2 INTO V_RESULT FROM DUAL;
    RETURN(V_RESULT);
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        RETURN 0;
    WHEN ZERO_DIVIDE THEN
        ERR_NUM:=SQLCODE;
        ERR_MSG:=SQLERRM;
        DBMS_OUTPUT.PUT_LINE('ERROR:' || TO_CHAR(ERR_NUM));
        DBMS_OUTPUT.PUT_LINE(ERR_MSG);
        DBMS_OUTPUT.PUT_LINE('ZERO NOT DIVISIBLE');
        RETURN(ERR_NUM);
END FN_DIVISION;

执行以下查询后

SELECT FN_DIVISION(8, 0) FROM DUAL;

我只进入OUTPUT脚本,出现以下错误:

FN_DIVISION
-1476

有时候,在DBMS输出中我什么也得不到,但是如果我多次尝试并再次创建功能后我可以得到正确的输出,那就是:

ERROR:-1476
ORA-01476: divisor is equal to zero
ZERO NOT DIVISIBLE

另一方面,当我试图看到" 0"以换取EXCEPTION ......

EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN 0;

...执行查询SELECT FN_DIVISION() FROM DUAL;后,我只收到以下错误:

ORA-06553: PLS-306: wrong number or types of arguments in call to
'FN_DIVISION'
06553. 00000 -  "PLS-%s: %s"
*Cause:    
*Action: Error en la línea: 129, columna: 8

提前致谢,任何帮助

2 个答案:

答案 0 :(得分:0)

除非为函数定义默认变量,否则会有以下值:

FN_DIVISION(NUMBER1 NUMBER default 0, NUMBER2 NUMBER default 1)...

当您调用此wrong number时,您会收到SELECT FN_DIVISION() FROM DUAL;错误的错误消息。 (此处默认值0或1仅为示例。如果您未提供任何这些值,则会提到错误。i.e. you have to put a value for an argument without value)。

答案 1 :(得分:0)

你可以节省一些空间和通过缩短功能代码来实现能量。您不需要所有这些变量,尤其不是SELECT ... FROM DUAL,而异常处理程序确实处理 nothing ,但可能非常误导。

参数的默认值来自Barbaros的消息。

当前功能代码:

SQL> CREATE OR REPLACE
  2  FUNCTION FN_DIVISION(NUMBER1 NUMBER, NUMBER2 NUMBER)
  3      RETURN NUMBER
  4  IS
  5      RESULTS NUMBER;
  6      V_RESULT NUMBER;
  7      ERR_NUM NUMBER;
  8      ERR_MSG VARCHAR2(255);
  9  BEGIN
 10      SELECT NUMBER1 / NUMBER2 INTO V_RESULT FROM DUAL;
 11      RETURN(V_RESULT);
 12  EXCEPTION
 13      WHEN NO_DATA_FOUND THEN
 14          RETURN 0;
 15      WHEN ZERO_DIVIDE THEN
 16          ERR_NUM:=SQLCODE;
 17          ERR_MSG:=SQLERRM;
 18          DBMS_OUTPUT.PUT_LINE('ERROR:' || TO_CHAR(ERR_NUM));
 19          DBMS_OUTPUT.PUT_LINE(ERR_MSG);
 20          DBMS_OUTPUT.PUT_LINE('ZERO NOT DIVISIBLE');
 21          RETURN(ERR_NUM);
 22  END FN_DIVISION;
 23  /

Function created.

SQL> select 1476 / fn_division(1, 0) result from dual;

    RESULT
----------
        -1

ERROR:-1476
ORA-01476: divisor is equal to zero
ZERO NOT DIVISIBLE
SQL>

那么,这是真的吗?结果是-1,还是什么?看起来似乎是这样 - 至少,这是你指示Oracle做的事情。

很少从SQL * Plus调用函数,即操作符实际看到DBMS_OUTPUT结果的交互模式。想象一下,我在Oracle Forms应用程序中使用了我的SELECT语句。我当然不会看到任何消息,并且结果很好并且“有效”-1。这接近危险

在缩短代码时,请转到:

SQL> CREATE OR REPLACE
  2  FUNCTION FN_DIVISION(NUMBER1 in NUMBER default 0, NUMBER2 in NUMBER default 1)
  3      RETURN NUMBER
  4  IS
  5  BEGIN
  6      RETURN (number1 / number2);
  7  EXCEPTION
  8      WHEN ZERO_DIVIDE THEN
  9         RAISE_APPLICATION_ERROR(-20000, sqlerrm);
 10  END FN_DIVISION;
 11  /

Function created.

SQL> select 1476 / fn_division(1, 0) result from dual;
select 1476 / fn_division(1, 0) result from dual
              *
ERROR at line 1:
ORA-20000: ORA-01476: divisor is equal to zero
ORA-06512: at "HR.FN_DIVISION", line 8
ORA-06512: at line 1

在行ORA-20000: ORA-01476: divisor is equal to zero中,-20000是我自己的错误代码,与SQLERRM连接。但是嘿,我需要做什么呢?这是愚蠢的 - 如果我让Oracle引发错误,那么无论如何都会这样做:

SQL> CREATE OR REPLACE
  2  FUNCTION FN_DIVISION(NUMBER1 in NUMBER default 0, NUMBER2 in NUMBER default 1)
  3      RETURN NUMBER
  4  IS
  5  BEGIN
  6      RETURN (number1 / number2);
  7  END FN_DIVISION;
  8  /

Function created.

SQL> select 1476 / fn_division(1, 0) result from dual;
select 1476 / fn_division(1, 0) result from dual
              *
ERROR at line 1:
ORA-01476: divisor is equal to zero
ORA-06512: at "HR.FN_DIVISION", line 5
ORA-06512: at line 1


SQL>

啊哈。好的,但是 - 功能代码现在缩短为一行。如果我可以简单地

,为什么我会使用一个函数呢?
SQL> select 1476 / (1 / 0) result from dual;
select 1476 / (1 / 0) result from dual
                 *
ERROR at line 1:
ORA-01476: divisor is equal to zero

基本上,这个功能或多或少都没用。摆脱它。