调用立即执行时出现错误数字溢出 oracle
Error numeric overflow oracle when call execute immediate
我定义了一个程序来将公式(类型值字符串)解析为数值数字:
公式中的某些案例值可以执行或引发错误数字溢出。
代码:
DECLARE
formula VARCHAR2(1000) := '1111111111 * 2';
val NUMBER;
BEGIN
EXECUTE IMMEDIATE 'BEGIN :res := '||formula||'; END;' USING OUT val;
DBMS_OUTPUT.PUT_LINE ( 'formula = ' || formula );
DBMS_OUTPUT.PUT_LINE ( 'val = ' || val );
END;
在这种情况下,则引发错误数字溢出。当我将值操作数 more/less 增加到 10 个字符 1 时,它就可以正常工作了。
我尝试检查一些值,如果公式中的值包含数字 1,就会发现大部分错误。
是这个原因吗?
谢谢大家!
当你在 PL/SQL 中乘以整数时,它实际上使用 pls_integers
。
pls_integer
2,147,483,647 有一个上限,您的示例中使用的乘法 2,222,222,222 超过了这个上限,因此导致数值溢出。
来自官方文档和 ask Tom 站点:
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.
为了摆脱这种情况,我们可以将表达式中的一个值设为数字。
案例 1:与 CAST
DECLARE
formula VARCHAR2(1000) := 'cast(1111111111 as number) * 2';
val NUMBER;
BEGIN
EXECUTE IMMEDIATE
'BEGIN '||
' :res := '||formula||';'||
'END;' USING OUT val;
DBMS_OUTPUT.PUT_LINE ( 'formula = ' || formula );
DBMS_OUTPUT.PUT_LINE ( 'val = ' || val );
END;
/
Case2:通过将其中一个表达式转换为十进制,Oracle 会将其隐式转换为数字
DECLARE
formula VARCHAR2(1000) := '1111111111 * 2.0';
val NUMBER;
BEGIN
EXECUTE IMMEDIATE
'BEGIN '||
' :res := '||formula||';'||
'END;' USING OUT val;
DBMS_OUTPUT.PUT_LINE ( 'formula = ' || formula );
DBMS_OUTPUT.PUT_LINE ( 'val = ' || val );
END;
/
我定义了一个程序来将公式(类型值字符串)解析为数值数字: 公式中的某些案例值可以执行或引发错误数字溢出。 代码:
DECLARE
formula VARCHAR2(1000) := '1111111111 * 2';
val NUMBER;
BEGIN
EXECUTE IMMEDIATE 'BEGIN :res := '||formula||'; END;' USING OUT val;
DBMS_OUTPUT.PUT_LINE ( 'formula = ' || formula );
DBMS_OUTPUT.PUT_LINE ( 'val = ' || val );
END;
在这种情况下,则引发错误数字溢出。当我将值操作数 more/less 增加到 10 个字符 1 时,它就可以正常工作了。
我尝试检查一些值,如果公式中的值包含数字 1,就会发现大部分错误。 是这个原因吗?
谢谢大家!
当你在 PL/SQL 中乘以整数时,它实际上使用 pls_integers
。
pls_integer
2,147,483,647 有一个上限,您的示例中使用的乘法 2,222,222,222 超过了这个上限,因此导致数值溢出。
来自官方文档和 ask Tom 站点:
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.
为了摆脱这种情况,我们可以将表达式中的一个值设为数字。
案例 1:与 CAST
DECLARE
formula VARCHAR2(1000) := 'cast(1111111111 as number) * 2';
val NUMBER;
BEGIN
EXECUTE IMMEDIATE
'BEGIN '||
' :res := '||formula||';'||
'END;' USING OUT val;
DBMS_OUTPUT.PUT_LINE ( 'formula = ' || formula );
DBMS_OUTPUT.PUT_LINE ( 'val = ' || val );
END;
/
Case2:通过将其中一个表达式转换为十进制,Oracle 会将其隐式转换为数字
DECLARE
formula VARCHAR2(1000) := '1111111111 * 2.0';
val NUMBER;
BEGIN
EXECUTE IMMEDIATE
'BEGIN '||
' :res := '||formula||';'||
'END;' USING OUT val;
DBMS_OUTPUT.PUT_LINE ( 'formula = ' || formula );
DBMS_OUTPUT.PUT_LINE ( 'val = ' || val );
END;
/