问题描述
尝试以下测试用例:
宣布
x编号:= 1 ;
开始
x := 1024 * 1024 * 1024 * 5 ;
结束;
/
-> ORA-01426 :数值溢出
宣布
x编号:= 1 ;
开始
x := x * 1024 ;
x := x * 1024 ;
x := x * 1024 ;
x := x 5 ;
结束;
/
->这样就可以了
示例可以在各种变体中完成,例如
宣布
*编号:= 1024 * 1024 * 1024 * 5 ;
开始
无效;
结束;
/
似乎如果构造了超过3个运算符,并且值超过了小整型,就会发生溢出。以后,你可以做任何事。
和: (我觉得很有趣) :
宣布
*编号;
开始
选择1024 * 1024 * 1024 * 1024 * 5进入x从双通道;
结束;
/
这个也行。
有什么想法吗?
敬重
最大
宣布
x编号:= 1 ;
开始
x := 1024 * 1024 * 1024 * 5 ;
结束;
/
-> ORA-01426 :数值溢出
宣布
x编号:= 1 ;
开始
x := x * 1024 ;
x := x * 1024 ;
x := x * 1024 ;
x := x 5 ;
结束;
/
->这样就可以了
示例可以在各种变体中完成,例如
宣布
*编号:= 1024 * 1024 * 1024 * 5 ;
开始
无效;
结束;
/
似乎如果构造了超过3个运算符,并且值超过了小整型,就会发生溢出。以后,你可以做任何事。
和: (我觉得很有趣) :
宣布
*编号;
开始
选择1024 * 1024 * 1024 * 1024 * 5进入x从双通道;
结束;
/
这个也行。
有什么想法吗?
敬重
最大
专家解答
当您在PL/SQL中乘以整数时,它实际上使用的是pls_integers。这些算法使用硬件算法。这比数字运算快。他们用图书馆的算术。
但有一个陷阱。上限为2,147,483,647。你的1024 * 1024 * 1024 * 1024 * 5的计算超过了这个!您将达到1024 * 1024 * 1024 * 2的限制:
但为什么会失败呢?
从文档中:
A calculation with two PLS_INTEGER values that overflows the PLS_INTEGER range raises an overflow exception, even if you assign the result to a NUMBER data type
https://docs.oracle.com/cloud/latest/db112/LNPLS/datatypes.htm#LNPLS99938
那么如何避免这种情况呢?
将表达式中的某个值设为数字!然后, Oracle将隐式地将整个计算转换为数字算术。
以下是您可以使用的几种方法:
Cast one of the literals
Add a decimal to one of the literals, making it a number
Include a variable that's a number in the calculation
这就是为什么你的第二个例子会起作用。所有的乘法都使用数算术。所以不要有2 147 483 647的限制。
SQL语句可以工作,因为它是在SQL引擎中处理的。PLS_integer不存在。所以它使用了数算。
但有一个陷阱。上限为2,147,483,647。你的1024 * 1024 * 1024 * 1024 * 5的计算超过了这个!您将达到1024 * 1024 * 1024 * 2的限制:
SQL> declare 2 l number := 1024 * 1024 * 1024 * 2; 3 begin 4 null; 5 end; 6 / declare * ERROR at line 1: ORA-01426: numeric overflow ORA-06512: at line 2
但为什么会失败呢?
从文档中:
A calculation with two PLS_INTEGER values that overflows the PLS_INTEGER range raises an overflow exception, even if you assign the result to a NUMBER data type
https://docs.oracle.com/cloud/latest/db112/LNPLS/datatypes.htm#LNPLS99938
那么如何避免这种情况呢?
将表达式中的某个值设为数字!然后, Oracle将隐式地将整个计算转换为数字算术。
以下是您可以使用的几种方法:
Cast one of the literals
SQL> declare 2 l number := cast(1024 as number) * 1024 * 1024 * 2; 3 begin 4 null; 5 end; 6 / PL/SQL procedure successfully completed.
Add a decimal to one of the literals, making it a number
SQL> declare 2 l number := 1024 * 1024 * 1024 * 2.0; 3 begin 4 null; 5 end; 6 /
Include a variable that's a number in the calculation
SQL> declare 2 n number := 1; 3 l number := n * 1024 * 1024 * 1024 * 2; 4 begin 5 null; 6 end; 7 /
这就是为什么你的第二个例子会起作用。所有的乘法都使用数算术。所以不要有2 147 483 647的限制。
SQL语句可以工作,因为它是在SQL引擎中处理的。PLS_integer不存在。所以它使用了数算。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




