Данные об ошибках и деление на 0

Нужна помощь, чтобы устранить ошибку: Msg 8114, уровень 16, состояние 5, строка 2 Ошибка преобразования типа данных varchar в числовой.

    CASE WHEN (proj.UserText1 IS NULL OR proj.UserText1 = '') 
         THEN 0.00 
         ELSE
         CASE 
            WHEN sopHdr.SOPTYPE = 4 
            THEN (((sopHdr.DOCAMNT - inv.TaxTotal) - inv.CostTotal) * - 1) * (proj.UserText1 / 100.0) 
                ELSE ((sopHdr.DOCAMNT - inv.TaxTotal) - inv.CostTotal) * (proj.UserText1 / 100.0) 
            END 
    END AS [Accrued Commission],

    CASE WHEN (sopHdr.DOCAMNT < 0) OR (sopHdr.SOPTYPE = 4 AND sopHdr.DOCAMNT > 0) THEN 100.00 
         ELSE 
             CASE WHEN (Paid.Paid IS NULL OR Paid.Paid = 0) OR (sopHdr.DOCAMNT = 0 OR sopHdr.DOCAMNT IS NULL) THEN 0.00 
                  ELSE (Paid.Paid / sopHdr.DOCAMNT) * 100 
    END END AS [Paid %],

    CASE WHEN sopHdr.DOCAMNT < 0 THEN (sopHdr.DOCAMNT) 
         WHEN (sopHdr.SOPTYPE = 4 AND sopHdr.DOCAMNT > 0) THEN (sopHdr.DOCAMNT * - 1) 
    ELSE CASE WHEN Paid.Paid IS NULL THEN 0.00 
              ELSE Paid.Paid 
    END END AS [Amount Received],

    CASE WHEN sopHdr.SOPTYPE = 4 
         THEN (inv.TaxTotal * - 1) 
         ELSE inv.TaxTotal 
    END AS [Tax Amount],

    CASE WHEN sopHdr.SOPTYPE = 4 THEN CAST(CAST(((sopHdr.SUBTOTAL - inv.TaxTotal - inv.CostTotal) * - 1) AS DECIMAL(13,6)) as float)
         ELSE CAST(CAST((sopHdr.SUBTOTAL - inv.TaxTotal - inv.CostTotal)AS DECIMAL(13,6)) as float)
    END AS [Gross Profit],

    CASE WHEN sopHdr.SOPTYPE = 4 THEN (inv.CostTotal * - 1) 
         ELSE inv.CostTotal 
    END AS [Ext Cost],

    CASE WHEN (proj.UserText1 IS NULL OR proj.UserText1 = '') THEN CAST('0.00' as varchar) 
         ELSE CAST(proj.UserText1 as varchar)
    END AS [Commission %],


    CASE WHEN sopHdr.SOPTYPE = 4 THEN CAST(CAST(((sopHdr.DOCAMNT - inv.TaxTotal) * - 1) AS DECIMAL(13,6)) as float)
         ELSE CAST(CAST((sopHdr.DOCAMNT - inv.TaxTotal) AS DECIMAL(13,6)) as float)
    END AS [Net Sales],

И ошибка:

Сообщение 8134, уровень 16, состояние 1, строка 16
Произошла ошибка деления на ноль.

Case#9
        CASE WHEN (sopHdr.SUBTOTAL IS NULL OR sopHdr.SUBTOTAL = 0) THEN 0.00 
                ELSE 
                    CASE WHEN sopHdr.SOPTYPE = 4 THEN ((sopHdr.SUBTOTAL - inv.TaxTotal - inv.CostTotal) /(sopHdr.SUBTOTAL) - (inv.TaxTotal)) * - 100
                    ELSE (((sopHdr.SUBTOTAL - inv.TaxTotal - inv.CostTotal) / (sopHdr.SUBTOTAL) - (inv.TaxTotal)) * 100)
                    END 
        END AS [Sale Gross Profit %],

Пожалуйста, порекомендуйте. Спасибо


person DemiB    schedule 15.05.2018    source источник
comment
Попробуйте изменить (Paid.Paid IS NULL OR Paid.Paid = 0) OR (sopHdr.DOCAMNT = 0 OR sopHdr.DOCAMNT IS NULL) на ((Paid.Paid IS NULL) OR (Paid.Paid = 0)) OR ((sopHdr.DOCAMNT = 0) OR (sopHdr.DOCAMNT IS NULL)). У меня может возникнуть вопрос приоритета. Кроме того, какую СУБД вы используете, Oracle?   -  person FDavidov    schedule 15.05.2018
comment
Спасибо. я использую SQL   -  person DemiB    schedule 15.05.2018
comment
Я получаю все то же сообщение, но я думаю, что каждый случай должен быть преобразован.   -  person DemiB    schedule 15.05.2018
comment
Похоже, проблема заключается в этом конкретном случае: CASE WHEN (proj.UserText1 IS NULL OR proj.UserText1 = '') THEN 0.00 ELSE CASE WHEN sopHdr.SOPTYPE = 4 THEN (((sopHdr.DOCAMNT - inv.TaxTotal) - inv. CostTotal) * - 1) * (proj.UserText1 / 100.0) ELSE ((sopHdr.DOCAMNT - inv.TaxTotal) - inv.CostTotal) * (proj.UserText1 / 100.0) END END AS [Начисленная комиссия],   -  person DemiB    schedule 15.05.2018


Ответы (1)


Вы не можете получить ошибку Divide by zero при делении на константы, только поля таблицы или выражения, содержащие единицы.
Поскольку sql является декларативным языком, даже если вы напишете что-то вроде этого:

select a/b
from table
where b <> 0

ваш механизм базы данных может решить, что проще вычислить это для каждой записи и отфильтровать позже, что, очевидно, даст вам эту ошибку. Предполагая, что вы используете сервер sql, я писал так:

select a/NULLIF(b, 0)
from table
where b <> 0

NULLIF() преобразует нули в нули и вместо ошибок вы получите null, (конечно, в приведенном выше примере не будет строк с нулями)

person avb    schedule 15.05.2018
comment
Да, это работает. СЛУЧАЙ, КОГДА (sopHdr.SUBTOTAL IS NULL OR sopHdr.SUBTOTAL = 0) THEN 0.00 ELSE CASE WHEN sopHdr.SOPTYPE = 4 THEN ((sopHdr.SUBTOTAL - inv.TaxTotal - inv.CostTotal) / NULLIF((NULLIF(sopHdr.SUBTOTAL, 0) - NULLIF(inv.TaxTotal,0)),0)) * - 100 ELSE (((sopHdr.SUBTOTAL - inv.TaxTotal - inv.CostTotal) / NULLIF((NULLIF(sopHdr.SUBTOTAL,0) - NULLIF( inv.TaxTotal,0)),0)) * 100) END END AS [Валовая прибыль от продажи %], - person DemiB; 15.05.2018