好吧,这取决于您对“溢出”的定义。如果您将“溢出”定义为“找到一个值n,其中n + 1 < n ”,那么不,没有这样的值。如果您将“溢出”定义为“引发异常”,那么是的,很有可能在引发异常的 NUMBER(12,0) 上执行操作。
运行以下命令:
DECLARE
n NUMBER(12, 0);
BEGIN
n := 999999999999; -- Twelve 9's
DBMS_OUTPUT.PUT_LINE('1 : n=' || n);
n := n + 1;
DBMS_OUTPUT.PUT_LINE('2 : n=' || n);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Exception: ' || SQLCODE || ' ' || SQLERRM);
END;
如您所见,尝试执行“n := n + 1”时会引发以下异常:
ORA-06502: PL/SQL: numeric or value error: number precision too large
所以很有可能溢出 NUMBER 的子类型。但是,鉴于您希望找到 n + 1 < n 的值n ,我认为您不走运。
如果你真的想使用基本的 NUMBER 类型来引发这种行为,只需执行
n := POWER(10, 126);
当然,对于 NUMBER 中真正令人讨厌的行为,您需要让它产生一个 NaN(不是数字):
n := 9999999999999999999999999999999999999999 * POWER(10, 125);
DBMS_OUTPUT.PUT_LINE('n=' || n);
生产
n=~
怎么回事?!?'~'?“~”到底是什么鬼?好吧,这似乎是 Oracle 打印 NaN 的方式。真正有趣的部分是什么?一旦你在一个变量中得到一个 NaN,你对该变量执行的任何操作都会产生另一个 NaN。悄悄。默默。没有警告。没有追索权。尝试:
DBMS_OUTPUT.PUT_LINE('n * 1234=' || n * 1234); -- produces n * 1234=~
DBMS_OUTPUT.PUT_LINE('n / 5678=' || n / 5678); -- produces n / 5678=~
嘿 - 玩得开心!:-)
在实际实践中,你不太可能遇到这种行为,但这是你真正需要注意的事情——不仅因为遇到它真的会毁了你的一个月,而且因为(你可以指望这个)下周浴室旁边那个无知的家伙会问这个问题——你现在就会知道这一切了。(而且你现在可以放心了,知道这个人真的很无能,因此应该被停在地狱的立方体中。我的意思是,你在 StackOverflow 上发现了这个,对吧?那么有多难呢?是吗?:-)
分享和享受。