DIVIDE_BY_ZERO foutklasse

SQLSTATE: 22012

Delen door nul. Gebruik try_divide om te tolereren dat deler 0 is en in plaats daarvan NULL retourneert. Stel indien nodig in <config> op 'false' om deze fout te omzeilen.

Parameters

  • ansiConfig: de naam van de configuratie om het gedrag te wijzigen.

Uitleg

Azure Databricks genereert deze fout wanneer wordt geprobeerd een INTERVAL of numeriek te delen door 0. De contextinformatie die bij deze fout wordt geleverd, isoleert het object en de expressie waarin de fout is opgetreden. Functies en operatoren zoals mod, die deze fout kunnen veroorzaken, zijn functies die deling uitvoeren als onderdeel van complexere formules.

Mitigatie

De beperking van de fout is afhankelijk van de oorzaak:

  • Is de expressie die de fout veroorzaakt juist?

    Als de expressie onjuist is, herstelt u deze zodat de 0 waarde niet kan worden uitgevoerd en voert u de query opnieuw uit.

  • Zijn de gegevens correct?

    Als de invoergegevens ertoe moeten kunnen leiden dat de 0 waarden worden doorgegeven, moet u mogelijk de gegevens bij de bron herstellen of opschonen voordat u de gegevens als argument aan de functie doorgeeft.

    Het opschonen van gegevens kan betekenen dat de beledigende rijen worden uitgesloten, dat de 0 waarden worden geconverteerd naar NULLnullif(expr, 0) of dat de gegevens worden geconverteerd naar een andere acceptabele waarde met if(expr = 0, alt, expr).

Als de expressie en de gegevens juist zijn en u de deling door nul wilt tolereren, kunt u try_divide gebruiken. Wijzig als alternatief het argument in nullif(expr, 0). Hierdoor wordt de expressie geretourneerd NULL in plaats van een fout. Als u wilt, kunt ue nvl(try_divide(expr1, expr2), alt) om de resulterende NULL in alternatieve waarden te veranderen, zoals neutrale elementen voor optellen 0 of vermenigvuldigen 1.

Als laatste oplossing kunt u, wanneer de expressie of gegevensstroom niet kan worden gewijzigd, dit ANSI-gedrag uitschakelen door de in ansiconfig te stellen op false. Houd er rekening mee dat deze instelling een gevolg is dat verder gaat dan de onmiddellijke foutvoorwaarde.

Voorbeelden

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