3

我正在使用名为 Appworx 的进程调度软件。其中,每个进程和子进程可以有任意数量的“条件”,如果为真,则采取一些条件动作。

可能的条件操作之一是 goto 语句,其中一个普通整数是标签(每个条件从 1 开始编号)。我想使用此功能在循环中评估和运行一些任务,但您只能转到更高编号的条件(不要问我为什么......这似乎破坏了大部分实用程序)。

我有理由相信所有这些都是由 Oracle 在后端评估的。在查看 Appworx 的架构后,goto标签似乎都是 NUMBER(12,0)。我怀疑检查标签是否低于当前条件的逻辑类似于:

where label > current_condition

所以,如果我要提供一个足够高的值的 goto,我认为它会欺骗检查并允许我执行简单的循环。至少如果 Oracle 使用普通整数。是否有可能使它们溢出,我将使用什么值将值溢出回 1?

我想Oracle版本很重要,如果是的话,那就是11g。

PS 另外,如果有人愿意为我重新标记此内容,请添加“appworx”

4

2 回答 2

3

Oracle 数字实际上是具有 40 个十进制数字有效位的浮点数。
所以,它们不能溢出。

(10^40-1) 是可以加1的最大整数。
证明

NUMBER(12,0) 是 NUMBER 类型的子类型。
也就是说,它由 NUMBER 类型和一个限制检查器组成。

于 2013-03-18T19:07:44.413 回答
2

好吧,这取决于您对“溢出”的定义。如果您将“溢出”定义为“找到一个值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 上发现了这个,对吧?那么有多难呢?是吗?:-)

分享和享受。

于 2013-03-20T18:26:47.573 回答