DIVIDE_BY_ZERO-Fehlerklasse

SQLSTATE: 22012

Division durch Null. Verwenden Sie try_divide, um zu tolerieren, dass der Divisor 0 ist, und stattdessen NULL zurückzugeben. Legen Sie <config> bei Bedarf auf „false“ fest, um diesen Fehler zu umgehen.

Parameter

  • ansiConfig: Der Name der Konfiguration zum Ändern des Verhaltens.

Erklärung

Azure Databricks löst diesen Fehler aus, wenn versucht wird, ein INTERVALL oder einen numerischen Wert durch 0 zu teilen. Die mit diesem Fehler bereitgestellten Kontextinformationen isolieren das Objekt und den Ausdruck, in dem der Fehler aufgetreten ist. Der Fehler kann durch Funktionen und Operatoren wie mod verursacht werden. Zu diesen Funktionen und Operatoren gehören u. a. auch solche, die Divisionen als Teil komplexerer Formeln ausführen.

Lösung

Die Minderung des Fehlers hängt von der Ursache ab:

  • Ist der Ausdruck, der den Fehler verursacht, korrekt?

    Wenn der Ausdruck falsch ist, korrigieren Sie ihn, damit 0-Werte nicht möglich sind, und wiederholen Sie die Abfrage.

  • Sind die Daten korrekt?

    Wenn die Eingabedaten zulassen, dass 0-Werte übergeben werden, müssen Sie die Daten möglicherweise entweder an der Quelle korrigieren oder vor dem Übergeben der Daten an die Funktion als Argument bereinigen.

    Die Datenbereinigung kann bedeuten, dass die problematischen Zeilen ausgeschlossen werden, die 0-Werte mithilfe von nullif(expr, 0) in NULL konvertiert werden oder die Daten mithilfe von if(expr = 0, alt, expr) in einen anderen akzeptablen Wert konvertiert werden.

Wenn der Ausdruck und die Daten korrekt sind und Sie die Division durch Null tolerieren möchten, können Sie try_divide verwenden. Ändern Sie alternativ das Argument in nullif(expr, 0). Dadurch gibt der Ausdruck NULL anstelle eines Fehlers zurück. Sie können auch nvl(try_divide(expr1, expr2), alt) verwenden, um den resultierenden NULL-Wert in alternative Werte umzuwandeln, z. b. neutrale Elemente zum Addieren 0 oder Multiplizieren 1.

Wenn der Ausdruck oder der Datenfluss nicht geändert werden kann, können Sie als letzte Option dieses ANSI-Verhalten deaktivieren, indem Sie die bereitgestellte ansiconfig als false festlegen. Beachten Sie, dass diese Einstellung mit Folgen verbunden ist, die über die unmittelbare Fehlerbedingung hinausgehen.

Beispiele

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