PLSQL 中的 REAL 数据类型
Posted
技术标签:
【中文标题】PLSQL 中的 REAL 数据类型【英文标题】:REAL datatype in PLSQL 【发布时间】:2016-04-08 05:33:39 【问题描述】:SET SERVEROUTPUT ON;
DECLARE
A REAL := 123456789123456789123456789123456789123456789123456789123456789123456789;
BEGIN
DBMS_OUTPUT.PUT_LINE('A Value is : ' || A);
END;
上面的程序运行并给了我如下的输出。
anonymous block completed
A Value is : 123456789123456789123456789123456789123500000000000000000000000000000000
谁能解释一下为什么它在第 40 位后显示 0 而不是实际值。还有第 40 位数字是 5 而不是 4。
【问题讨论】:
你猜到了吗? 先看文档:docs.oracle.com/cd/B19306_01/server.102/b14237/… 你读过the SQL Reference manual吗? "5 而不是 4。" --> 四舍五入可能有帮助:mathsisfun.com/rounding-numbers.html Oracle guarantees the portability of numbers with precision of up to 20 base-100 digits, which is equivalent to 39 or 40 decimal digits depending on the position of the decimal point。它显示了 40 个最重要的数字;最后一个是四舍五入的,剩下的数字为零,因为你已经超出了可用的精度。 【参考方案1】:SQL language reference 表示“REAL 数据类型是二进制精度为 63 或十进制 18 的浮点数”,它显示为 FLOAT(63)。 FLOAT [(p)] 是:
精度为 p 的 NUMBER 数据类型的子类型。 FLOAT 值在内部表示为 NUMBER。精度 p 的范围可以从 1 到 126 个二进制数字。 FLOAT 值需要 1 到 22 个字节。
如果您创建具有 REAL 列的表,其行为类似于 FLOAT(63):
create table t42 (a real, b float(126), c float(63), d number);
insert into t42 (a, b, c, d)
values (123456789123456789123456789123456789123456789123456,
123456789123456789123456789123456789123456789123456,
123456789123456789123456789123456789123456789123456,
123456789123456789123456789123456789123456789123456);
select a, b, c, d from t42;
A
----------------------------------------------------------------
B
----------------------------------------------------------------
C
----------------------------------------------------------------
D
----------------------------------------------------------------
123456789123456789100000000000000000000000000000000
123456789123456789123456789123456789120000000000000
123456789123456789100000000000000000000000000000000
123456789123456789123456789123456789123000000000000
我使用了一个较小的值,因此它可以在 numformat 的 49 位 SQL*Plus/SQL Developer 限制内显示。请注意,FLOAT(126) 和 NUMBER 值与该值并不完全相同。
PL/SQL 略有不同。在标准包中可以看到:
type NUMBER is NUMBER_BASE;
subtype FLOAT is NUMBER; -- NUMBER(126)
subtype REAL is FLOAT; -- FLOAT(63)
在 PL/SQL 块中,您的 REAL
变量可以采用不受限制的 NUMBER
可以采用的任何值,并且具有相同的比例/精度效果;在这种情况下,只保留最重要的(38-40) 数字,并将其余数字四舍五入为前 40 位数字中的最小数字。您的值的整体“大小”(作为 72 位数字)被保留,但您失去的精度超出了 Oracle 内部格式可以存储的精度。如果您具有与表示例相同的变量类型并将原始值放入:
DECLARE
A REAL := 123456789123456789123456789123456789123456789123456789123456789123456789;
B FLOAT(126) := 123456789123456789123456789123456789123456789123456789123456789123456789;
c FLOAT(63) := 123456789123456789123456789123456789123456789123456789123456789123456789;
D NUMBER := 123456789123456789123456789123456789123456789123456789123456789123456789;
BEGIN
DBMS_OUTPUT.PUT_LINE('A Value is : ' || A);
DBMS_OUTPUT.PUT_LINE('B Value is : ' || B);
DBMS_OUTPUT.PUT_LINE('C Value is : ' || C);
DBMS_OUTPUT.PUT_LINE('D Value is : ' || D);
END;
/
A Value is : 123456789123456789123456789123456789123500000000000000000000000000000000
B Value is : 123456789123456789123456789123456789120000000000000000000000000000000000
C Value is : 123456789123456789100000000000000000000000000000000000000000000000000000
D Value is : 123456789123456789123456789123456789123500000000000000000000000000000000
注意这次不受限制的 FLOAT 和 NUMBER 显示相同的值,而受限制的 FLOAT 具有您期望的精度。
所以它在第 40 位之后显示零,并且第 40 位是 5 而不是 4,因为您已经超出了精度并且该值被四舍五入到最高有效位。 SQL REAL 数据类型的精度为 63 位二进制或 18 位十进制数字;但除非指定 PL/SQL REAL 匹配 NUMBER。
【讨论】:
以上是关于PLSQL 中的 REAL 数据类型的主要内容,如果未能解决你的问题,请参考以下文章
关于c语言的数据类型real_T,int_T和real,int的区别
PLSQL 在变量中存储具有未知数据类型的游标(使用 FETCH INTO)