我有一个执行计算的 Oracle 函数,但没有返回结果的小数。
CREATE OR REPLACE Function MY_TESTE
RETURN DECIMAL
IS
BEGIN
RETURN 1/3;
END;
如果我执行了这个功能
SELECT MY_TESTE
FROM DUAL
它返回带有任何小数位的值 0。但它期望返回 0.3333 有什么想法吗?
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
分享和享受。
将返回类型更改为NUMBER
在这里,您已经解释了 Oracle 中 DECIMAL 和 NUMBER 数据类型之间的区别:decimal(s,p) 还是 number(s,p)?
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
请注意,最后一个版本在此版本中将最后一位数字向上取整。
在 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) 作为返回类型,因此将十进制更改为数字
祝你好运