Bagikan melalui


kondisi kesalahan DIVIDE_BY_ZERO

SQLSTATE: 22012

Pembagian dengan nol. Gunakan try_divide untuk mengabaikan ketika pembagi bernilai 0 dan mengembalikan NULL sebagai gantinya. Jika perlu atur <config> ke "false" untuk melewati kesalahan ini.

Parameter

  • ansiConfig: Nama konfigurasi untuk mengubah perilaku.

Penjelasan

Azure Databricks menimbulkan kesalahan ini setiap kali mencoba membagi INTERVAL, atau numerik dengan 0. Informasi konteks yang diberikan dengan kesalahan ini mengisolasi objek dan ekspresi tempat kesalahan terjadi. Fungsi dan operator seperti mod, yang dapat menyebabkan kesalahan ini termasuk yang melakukan pembagian sebagai bagian dari rumus yang lebih kompleks.

Mitigasi

Mitigasi kesalahan tergantung pada penyebabnya:

  • Apakah ekspresi yang menyebabkan kesalahan ini sudah sesuai?

    Jika ekspresi salah memperbaikinya sehingga nilai 0 tidak dapat terjadi, dan coba lagi kueri.

  • Apakah data benar?

    Jika data input harus dapat membuat nilai 0 dapat diteruskan, Anda mungkin perlu memperbaiki data di sumber atau membersihkannya terlebih dahulu sebelum meneruskan data ke fungsi sebagai argumen.

    Pembersihan data dapat berarti mengecualikan baris yang menyinggung, untuk mengonversi nilai 0 menjadi NULL menggunakan nullif(expr, 0), atau untuk mengonversi data ke nilai lain yang dapat diterima menggunakan jika(expr = 0, alt, expr).

Jika ekspresi dan data sudah benar, dan Anda ingin mentolerir pembagian dengan nol, Anda dapat menggunakan try_divide. Sebagai alternatif, ubah argumen menjadi nullif(expr, 0). Ini akan menyebabkan ekspresi mengembalikan NULL sebagai pengganti kesalahan. Jika Anda lebih suka Anda dapat melakukan nvl(try_divide(expr1, expr2), alt) untuk mengubah NULL yang dihasilkan menjadi nilai alternatif seperti elemen netral untuk penambahan 0 atau perkalian 1.

Sebagai solusi dari upaya terakhir, ketika ekspresi atau aliran data tidak dapat diubah, Anda dapat menonaktifkan perilaku ANSI ini dengan mengatur ansiconfig yang disediakan ke false. Perhatikan bahwa pengaturan ini berdampak melebihi kondisi kesalahan langsung.

Contoh

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