1

我有一个执行计算的 Oracle 函数,但没有返回结果的小数。

CREATE OR REPLACE Function MY_TESTE
   RETURN DECIMAL
   IS
BEGIN

  RETURN 1/3;

END;

如果我执行了这个功能

SELECT MY_TESTE 
  FROM DUAL

它返回带有任何小数位的值 0。但它期望返回 0.3333 有什么想法吗?

4

4 回答 4

5

DECIMAL 在 SYS.STANDARD 包中被声明为 NUMBER 的子类型(Oracle 中的大多数数字类型也是如此),特别是 NUMBER(38, 0),这意味着 DECIMAL 值不能在小数点右侧有数字观点。为了使 DECIMAL 值具有小数点右侧的数字,它们必须这样声明,类似于

dValue  DECIMAL(38, 4)

但是,如果您想从函数返回这样的值,这将无济于事,因为您不能在函数返回类型上使用精度说明符。

为了从函数返回小数点右侧的数字的 DECIMAL 值,您需要声明 DECIMAL 的子类型,该子类型指定正确的小数位数并将该子类型用作函数的返回类型。这是一个例子:

DECLARE 
  SUBTYPE DEC_10_3 IS DECIMAL(10, 3);

  FUNCTION TEST1 RETURN DECIMAL
  IS
    d  DECIMAL := 1/3;
  BEGIN
    RETURN d;
  END TEST1;

  FUNCTION TEST2 RETURN DECIMAL
  IS
    d  DECIMAL(10, 3) := 1/3;
  BEGIN
    RETURN d;
  END TEST2;

  FUNCTION TEST3 RETURN DEC_10_3 IS
    d DEC_10_3 := 1/3;
  BEGIN
    RETURN d;
  END TEST3;
BEGIN
  -- Test statements here
  DBMS_OUTPUT.PUT_LINE('TEST1=' || TEST1);
  DBMS_OUTPUT.PUT_LINE('TEST2=' || TEST2);
  DBMS_OUTPUT.PUT_LINE('TEST3=' || TEST3);
END;

运行上述将产生

TEST1=0
TEST2=0
TEST3=.333

分享和享受。

于 2013-07-17T13:05:23.540 回答
3

将返回类型更改为NUMBER

在这里,您已经解释了 Oracle 中 DECIMAL 和 NUMBER 数据类型之间的区别:decimal(s,p) 还是 number(s,p)?

于 2013-07-17T12:49:19.000 回答
0

Bob Jarvis 解释了使用DECIMAL. 您可以使用TRUNC(或ROUND,取决于您希望它的行为方式)并返回NUMBER仍然限制为所需小数位数的 a:

create or replace function my_test return number is
begin
  return trunc(1/3, 4);
end;
/

select my_test from dual;

   MY_TEST
----------
    0.3333

TRUNC和之间的区别ROUND可以用不同的分数更好地证明:

create or replace function my_test return number is
begin
  return trunc(2/3, 4);
end;
/

select my_test from dual;

   MY_TEST
----------
    0.6666 

create or replace function my_test return number is
begin
  return round(2/3, 4);
end;
/

select my_test from dual;

FUNCTION MY_TEST compiled
   MY_TEST
----------
    0.6667 

请注意,最后一个版本在此版本中将最后一位数字向上取整。

于 2013-07-17T14:54:17.030 回答
0

在 Oracle DECIMAL 中,默认情况下存储除法结果类似于整数,例如,您需要 decimal(10, 3)

declare
    l_res1 decimal(10, 3);
    l_res2 decimal;
begin

    l_res1 := 1 / 3;
    dbms_output.put_line(l_res1);

    l_res2 := 1 / 3;
    dbms_output.put_line(l_res2);
end;

但是您不能在函数中使用 decimal(10, 3) 作为返回类型,因此将十进制更改为数字

祝你好运

于 2013-07-17T12:57:55.057 回答