我正在使用名为Appworx的流程调度软件。在其中,每个进程和子进程可以具有任意数量的“条件”,如果为真,则采取一些条件操作。
可能的条件操作之一是goto语句,其中普通整数是标签(每个条件从1开始编号)。我想使用此功能在循环中评估和运行一些任务,但你只能转到更高编号的条件(不要问我为什么......这似乎毁了大多数实用工具)。
我有理由相信所有这些都是由Oracle在后端评估的。看了Appworx的架构,似乎 goto 标签都是NUMBER(12,0)。我怀疑检查标签是否低于当前条件的逻辑类似于:
where label > current_condition
所以,如果我要提供一个足够高的goto,我认为它会欺骗检查并允许我做简单的循环。至少如果Oracle使用普通整数。是否有可能溢出它们,我将使用什么值将值溢出回1?
我认为Oracle版本很重要,如果是的话,它是11g。
PS此外,如果有人愿意为我重新标记这个,请添加“appworx”
答案 0 :(得分:3)
Oracle数字实际上是具有40位十进制数字有效数的浮点数 所以,他们不能溢出来。
(10 ^ 40-1)是可以增加1的最大整数 proof
NUMBER(12,0)是NUMBER类型的子类型 也就是说,它由NUMBER类型和限制检查器组成。
答案 1 :(得分:2)
那么,这取决于你对'溢出'的定义。如果您将'溢出'定义为'找到值 n ,其中 n + 1< n ',然后不,没有这样的价值。如果你将'overflow'定义为'引发异常',那么是的,很可能对引发异常的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 ,其中 n + 1< n ,我认为你运气不好。
如果您真的想使用基本NUMBER类型激发此行为,请执行
n := POWER(10, 126);
当然,对于NUMBER中真正的 令人讨厌的 行为,您需要让它生成NaN(非数字):
n := 9999999999999999999999999999999999999999 * POWER(10, 125);
DBMS_OUTPUT.PUT_LINE('n=' || n);
产生
n=~
WTF?!? '〜'?到底是什么'〜'?好吧,这似乎是甲骨文打印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=~
嘿 - 玩得很开心! : - )
在实际操作中,你不太可能遇到这种行为,但这是你真正需要注意的事情 - 不仅因为遇到它可能真的毁了你的月份,而是因为(你可以指望这个)下周卫生间立方体中一个无能为力的家伙会问这个问题 - 你现在会知道这一切。 (而且你现在能够轻松,舒适地知道这个家伙真的 无能为力,因此应该停在The Cube From Hell。我的意思是,你在StackOverflow上接受了这个,对吧?那有多难?: - )
分享并享受。