在进一步的调查中,这看起来可能是一个 SQL Developer 错误(当然,假设你再次在做什么......)。我可以得到同样的错误:
VAR TRANSACTIONNR NUMBER;
BEGIN
SELECT 2961725541 INTO :TRANSACTIONNR FROM DUAL;
END;
/
似乎 SQL DeveloperNUMBER
仅限于2^31
,而 Oracle 通常不是这种情况。
一种可能的解决方法是用于BINARY_FLOAT
存储该值,但您最终会遇到精度问题(不确定在哪里,但看起来可以2^53
-ish),并且在使用它时需要将cast()
其恢复NUMBER
。
VAR TRANSACTIONNR BINARY_DOUBLE;
BEGIN
SELECT 2961725541 INTO :TRANSACTIONNR FROM DUAL;
-- dbms_output.put_line(cast(:TRANSACTIONNR as NUMBER)); -- null for some reason
END;
/
...
BEGIN
dbms_output.put_line(cast(:TRANSACTIONNR as NUMBER));
END;
/
出于某种原因,我似乎无法在我设置的匿名块中再次引用绑定变量——它在注释掉的代码中为空——这似乎是另一个 SQL Developer 怪癖,无论var
类型如何;但是当你在你的代码中这样做时,我可能再次假设太多......
后代的原始答案,因为它可能在其他情况下仍然相关......
大概你正在做一些事情来结束当前的交易,例如 a commit
in endtransaction
; 否则你可以my_sequence.currval
在do_something
通话中提及。但是,对于这种大小的number
数字,变量是可以的,它不会对大小的序列产生任何影响,并且它来自序列而不是手动分配不会有任何区别。我认为问题不在于存储或顺序。
错误似乎更有可能来自您正在调用的包过程之一,尽管我无法想象您可能会用它做什么;像这样的事情会导致同样的错误:
create sequence my_sequence start with 2961725541;
create package my_package as
procedure starttransaction(v_num number);
procedure endtransaction;
procedure do_something(v_num number);
end my_package;
/
create package body my_package as
procedure starttransaction(v_num number) is
begin
dbms_output.put_line('starttransaction(): ' || v_num);
for i in 1..v_num loop
null;
end loop;
end starttransaction;
procedure endtransaction is
begin
dbms_output.put_line('endtransaction()');
end endtransaction;
procedure do_something(v_num number) is
begin
dbms_output.put_line('do_something(): ' || v_num);
end do_something;
end my_package;
/
当您的代码针对它运行时,它会引发您的错误:
BEGIN
*
ERROR at line 1:
ORA-01426: numeric overflow
ORA-06512: at "STACKOVERFLOW.MY_PACKAGE", line 6
ORA-06512: at line 5
endtransaction()
do_something():
请注意,该错误是针对包中的第 6 行报告的,这是该for ... loop
行,而不是来自匿名块中的分配。
像这样循环当然是一件奇怪的事情,但可能还有其他方法可以产生该错误。它工作的断点是如果在nextval
上面2^31
。如果我以 2147483647 开始序列,它可以工作,而 2147483648 则错误。
我假设您实际上是ORA-01426
从原始问题中得到的;如果它实际上是 a ORA-1438
,ORA-06502
则通过尝试将值分配给number(9)
列或变量来更容易重现。不过,“数字溢出”非常具体。