ARITHMETIC_OVERFLOW 错误类

SQLSTATE: 22003

<message><alternative> 如有必要,请将 <config> 设置为“false”以绕过此错误。

参数

  • message:导致溢出的表达式的说明。
  • alternative:避免该错误的建议方法。
  • config:用于更改 ANSI 模式的配置设置。

说明

当 Azure Databricks 执行的数学运算超过所执行操作的数据类型的最大范围时,就会发生算术溢出。

在许多情况下,数学是用运算符操作数的最不常见类型或函数参数的最不常见类型来执行的。

添加两个类型为 TINYINT 的数字可以快速超出类型范围,即从 -128+127 的范围。 其他类型(如 TIMESTAMPINTERVAL)也具有较大但有限的范围。

有关类型域的定义,请参阅数据类型的定义

缓解

此错误的缓解方法取决于具体原因:

  • 数学或输入参数是否不正确?

    根据需要更正所使用的函数或输入数据。

    还可考虑重新排序操作,以将中间结果保持在所需的范围内。

  • 数据类型不是最宽的类型吗?

    通过将其中一个参数强制转换为足以完成操作的类型来扩大类型。

    使用适当的 s 选择 DOUBLEDECIMAL(38, s) 会提供很大的范围,但以舍入为代价。

  • 是否可以容忍溢出条件并将其替换为 NULL

    更改表达式以使用 alternative 中建议的函数。 例如,使用 try_sum 而不是 sum

  • 不能更改表达式,而宁愿得到包装的结果也不愿返回一个错误?

    最为最后的手段,可通过将 ansiConfig 设置为 false 来禁用 ANSI 模式。

示例

-- An overflow of a small numeric
> SELECT 100Y * 100Y;
 [ARITHMETIC_OVERFLOW] 100S * 100S caused overflow.
 If necessary set ansi_mode to "false" (except for ANSI interval type) to bypass this error.

-- Use a wider numeric to perform the operation by casting one of the operands
> SELECT 100Y * cast(100Y AS INTEGER);
 10000

-- An overflow of a complex expression which can be rewritten
> SELECT 100Y * 10Y / 5;
 [ARITHMETIC_OVERFLOW] 100S * 10S caused overflow.
 If necessary set spark.sql.ansi.enabled to "false" (except for ANSI interval type) to bypass this error.

-- Rewrite the expression
> SELECT 100Y / 5 * 10Y;
 200.0

-- An occasional overfklow that should be tolerated
> SELECT arg1 * arg2 FROM VALUES(100Y, 100Y), (20Y, 5Y) AS t(arg1, arg2);
 [ARITHMETIC_OVERFLOW] 100S * 100S caused overflow.
 If necessary set ansi_mode to "false" (except for ANSI interval type) to bypass this error.

-- Allowing overflows to be treated as NULL
> SELECT try_multiply(arg1, arg2) FROM VALUES(100Y, 100Y), (20Y, 5Y) AS t(arg1, arg2);
  NULL
  100

-- In Databricks SQL temporarily disable ANSI mode to tolerate incorrect overflow.
> SET ANSI_MODE = false;
> SELECT arg1 * arg2 FROM VALUES(100Y, 100Y), (20Y, 5Y) AS t(arg1, arg2);
  16
  100
> SET ANSI_MODE = true;

-- In Databricks Runtime temporarily disable ANSI mode to tolerate incorrect overflow.
> SET spark.sql.ansi.enabled = false;
> SELECT arg1 * arg2 FROM VALUES(100Y, 100Y), (20Y, 5Y) AS t(arg1, arg2);
  16
  100
> SET spark.sql.ansi.enabled = true;