فئة الخطأ DIVIDE_BY_ZERO

SQLSTATE: 22012

قسمة على صفر. استخدم try_divide لتحمل كون عامل القسمة 0 وإرجاع NULL بدلا من ذلك. إذا لزم الأمر، فقم بتعيين <config> إلى "خطأ" لتجاوز هذا الخطأ.

معلمات

  • ansiConfig: اسم التكوين لتغيير السلوك.

تفسير

يثير Azure Databricks هذا الخطأ كلما حاول تقسيم فاصل زمني، أو رقمي على 0. تعزل معلومات السياق المتوفرة مع هذا الخطأ الكائن والتعبير الذي حدث فيه الخطأ. تتضمن الدالات وعوامل التشغيل مثل mod، التي يمكن أن تسبب هذا الخطأ، تلك التي تقوم بإجراء القسمة كجزء من صيغ أكثر تعقيدا.

التخفيف

يعتمد التخفيف من الخطأ على السبب:

  • هل التعبير الذي يسبب الخطأ صحيح؟

    إذا كان التعبير غير صحيح، فقم بإصلاحه بحيث 0 لا يمكن حدوث القيمة، وأعد محاولة الاستعلام.

  • هل البيانات صحيحة؟

    إذا كان يجب أن تكون بيانات الإدخال قادرة على أن تؤدي 0 إلى تمرير القيم، فقد تحتاج إما إلى إصلاح البيانات في المصدر أو تنظيفها قبل تمرير البيانات إلى الدالة كوسيطة.

    يمكن أن يعني تنظيف البيانات استبعاد الصفوف المخالفة، أو تحويل 0 القيم إلى NULL استخدام nullif(expr، 0) أو لتحويل البيانات إلى قيمة مقبولة أخرى باستخدام if(expr = 0، alt، expr).

إذا كان التعبير والبيانات صحيحة، وتريد تحمل القسمة بمقدار صفر، يمكنك استخدام try_divide. كبديل، قم بتغيير الوسيطة إلى nullif(expr, 0). سيؤدي هذا إلى إرجاع NULL التعبير بدلا من خطأ. إذا كنت تفضل أنه يمكنك ue 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