Поделиться через


класс ошибок DIVIDE_BY_ZERO

SQLSTATE: 22012

Деление на ноль. Используйте try_divide для того, чтобы вместо этого допускать 0 делителей и возвращать значение NULL. Если необходимо, установите <config> в "false", чтобы обойти эту ошибку.

Параметры

  • ansiConfig: имя конфигурации для изменения поведения.

Объяснение

Azure Databricks вызывает эту ошибку всякий раз, когда он пытается разделить интервал или число на 0. Сведения о контексте, предоставленные этой ошибкой, изолируют объект и выражение, в котором произошла ошибка. Функции и операторы, такие как мод, которые могут вызвать эту ошибку, включают те, которые выполняют деление в составе более сложных формул.

Смягчение

Устранение ошибки зависит от причины:

  • Действительно ли выражение, вызывающее ошибку, корректно?

    Если выражение некорректно, исправьте его, чтобы значение 0 не могло возникнуть, и повторите запрос.

  • Правильно ли данные?

    Если входные данные должны привести к передаче значений 0, может потребоваться либо исправить данные в источнике, либо очистить их перед передачей данных функции в качестве аргумента.

    Очистка данных может означать, чтобы исключить строки с ошибками, преобразовать значения данных 0 в NULL с помощью nullif(expr, 0)или изменить данные в иной допустимый формат с помощью if(expr = 0, alt, expr).

Если выражение и данные корректны, и вы хотите допустить деление на ноль, используйте try_divide. В качестве альтернативы измените аргумент на nullif(expr, 0). Это приведет к тому, что выражение возвращает NULL вместо ошибки. Если вы предпочитаете, вы можете использовать nvl(try_divide(expr1, expr2), alt), чтобы заменить результирующее NULL на альтернативные значения, такие как нейтральные элементы для сложения 0 или умножения 1.

В крайнем случае, если выражение или поток данных нельзя изменить, можно отключить это поведение ANSI, присвоив предоставленному ansiconfig значение false. Обратите внимание, что этот параметр имеет важные последствия, выходящие за рамки немедленной ошибки.

Примеры

-- A DIVIDE_BY_ZERO in a embedded in view. The context information isolates the faiing function.
> CREATE OR REPLACE TEMPORARY VIEW v(c1) AS SELECT 1/val FROM VALUES(1), (0) AS T(val);
> SELECT c1 FROM v;
  [DIVIDE_BY_ZERO] Division by zero. To return NULL instead, use `try_divide`. If necessary set "spark.sql.ansi.enabled" to false (except for ANSI interval type) to bypass this error.
  == SQL of VIEW v(line 1, position 7) ==
  SELECT 1/val FROM VALUES(1), (0) AS T(val)
         ^^^^^

-- Tolerating division by zero by turning the result to NULL using try_divide.
> CREATE OR REPLACE TEMPORARY VIEW v(c1) AS SELECT try_divide(1, val) FROM VALUES(1), (0) AS T(val);
> SELECT c1 FROM v;
  1
  NULL

-- Tolerating division by zero by turning the result to NULL using nullif
> CREATE OR REPLACE TEMPORARY VIEW v(c1) AS SELECT 1 / nullif(val, 0) FROM VALUES(1), (0) AS T(val);
> SELECT c1 FROM v;
  1
  NULL

-- Filtering out offensive rows
> CREATE OR REPLACE TEMPORARY VIEW v(c1) AS SELECT 1/val FROM VALUES(1), (0) AS T(val) WHERE val != 0;
> SELECT c1 FROM v;
  1

-- Turning division by zero into division by a small number.
> CREATE OR REPLACE TEMPORARY VIEW v(c1) AS SELECT 1 / if(val = 0, 1e-10, val) FROM VALUES(1), (0) AS T(val);
> SELECT c1 FROM v;
  1
  10000000000

-- Turning division by zero into a neutral element for addition.
> CREATE OR REPLACE TEMPORARY VIEW v(c1) AS SELECT nvl(try_divide(1, val), 0) FROM VALUES(1), (0) AS T(val);
> SELECT c1 FROM v;
  1
  0

-- Disabling ANSI mode in Databricks SQL for the view definition only.
> SET ANSI_MODE = false;
> CREATE OR REPLACE TEMPORARY VIEW v(c1) AS SELECT 1/val FROM VALUES(1), (0) AS T(val);
> SET ANSI_MODE = true;

> SELECT c1 FROM v;
  1
  NULL

-- Disabling ANSI mode in Databricks Runtime for the view definition only.
> SET spark.sql.ansi.enabled = false;
> CREATE OR REPLACE TEMPORARY VIEW v(c1) AS SELECT 1/val FROM VALUES(1), (0) AS T(val);
> SET spark.sql.ansi.enabled = true;

> SELECT c1 FROM v;
  1
  NULL