Partilhar via


DIVIDE_BY_ZERO classe de erros

SQLSTATE: 22012

Divisão por zero. Utilize try_divide para tolerar que o divisor seja 0 e, em vez disso, devolva NULL. Se necessário, defina <config> como "falso" para ignorar este erro.

Parâmetros

  • ansiConfig: o nome da configuração para alterar o comportamento.

Explicação

O Azure Databricks gera este erro sempre que tenta dividir um INTERVALO ou numérico por 0. As informações de contexto fornecidas com este erro isolam o objeto e a expressão na qual ocorreu o erro. Funções e operadores, como mod, que podem causar este erro incluem aqueles que estão a executar a divisão como parte de fórmulas mais complexas.

Mitigação

A mitigação do erro depende da causa:

  • A expressão está a causar o erro correto?

    Se a expressão estiver incorreta, corrija-a para que o 0 valor não possa ocorrer e repita a consulta.

  • Os dados estão corretos?

    Se os dados de entrada conseguirem fazer com que os 0 valores sejam transmitidos, poderá ter de corrigir os dados na origem ou limpá-lo antes de transmitir os dados para a função como um argumento.

    A limpeza de dados pode significar excluir as linhas ofensivas, converter os 0 valores em NULL utilizar nullif(expr, 0)ou converter os dados noutro valor aceitável com if(expr = 0, alt, expr).

Se a expressão e os dados estiverem corretos e quiser tolerar a divisão por zero, pode utilizar try_divide. Como alternativa, altere o argumento para nullif(expr, 0). Isto fará com que a expressão regresse NULL em vez de um erro. Se preferir, pode ue nvl(try_divide(expr1, expr2), alt) para transformar o resultado NULL num valor alternativo, como elementos neutros para adição 0 ou multiplicação 1.

Como solução de último recurso, quando não é possível alterar a expressão ou o fluxo de dados, pode desativar este comportamento ANSI ao definir o fornecido ansiconfig como false. Tenha em atenção que esta definição é consequente para além da condição de erro imediata.

Exemplos

-- 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