有没有一种方法可以查明哪一行代码有零除错误?

时间:2020-05-13 15:16:14

标签: sql-server

我在SELECT语句的起始位置遇到了除以零的错误,但不确定错误的确切位置。我将NULLIF(,0)放在有除法命令的位置,但是仍然返回除零错误。有没有一种方法可以准确指出错误的触发位置?

drop table #tempMAINA
SELECT a.COUNTRY_IBS 
      --,a.[List_Price_Code]                                        AS "LPC"
      ,a.[Item_Number]
      --,b.COUNTRY_IBS
      --,b.[Price_list]
      --,b.[Item_Number]
      ,Item.Item_Desc_English                                   AS "Item_Description"
      ,ITEM.Product_Manager_Name                                AS "Product_Manager"
      --,PMCD.Category_Director
      ,ITEM.Manufacturer
      ,ITEM.Manufacturer_Desc
      ,ITEM.Brand
      ,ITEM.Brand_Desc
      ,CMT.NAME_PRDUCT_CLASS_LEVEL_2                            AS "CMT_LEVEL_2"
      ,ITEM.PPG_Code
      ,ITEM.PPG_Desc
      ,TLPC.[PY_Standard_List]                                  AS "2019_Standard_List_LC"
      ,TLPC.Standard_List                                       AS "2020_Standard_List_LC"
      ,TLPC.Standard_List*FX.Exchange_Rate                      AS "2020_Standard_List_USD"                                                                             
      ,sc2020.Standard_Cost                                     AS "2020_Standard_Cost_LC"
      ,sc2020.Standard_Cost*FX.Exchange_Rate                        AS "2020_Standard_Cost_USD"
      ,(TLPC.[Standard_List]-sc2020.[Standard_Cost])            AS "2020_Margin_per_Unit_LC"
      ,1-sc2020.[Standard_Cost]/NULLIF(TLPC.[Standard_List],0)          AS "Margin_as_%_of_Stan_List_LC"
      --,c.[Conversion_factor]                                  AS "Conv"
      ,CASE WHEN    TQC.[LTM_Qty] IS NULL OR TQC.[LTM_Qty]=0
            THEN    TLPC.Standard_List*FX.Exchange_Rate*(1-CPPG.[Discount Percentage])
            ELSE    (TSC.[LTM_Sales_USD])/NULLIF(tqc.[LTM_Qty],0)   END                         AS "ASP_USD"
      ,CASE WHEN    TQC.[LTM_Qty] IS NULL OR TQC.[LTM_Qty]=0
            THEN    sc2020.[Standard_Cost]*FX.Exchange_Rate
            ELSE    (TSC.[LTM_Cost_USD])/NULLIF(tqc.[LTM_Qty],0)    END                         AS "ASCost_USD"

      ,CASE WHEN    TQC.[LTM_Qty] IS NULL OR TQC.[LTM_Qty]=0
            THEN    TLPC.Standard_List *FX.Exchange_Rate*(1-CPPG.[Discount Percentage])
            ELSE    (TSC.[LTM_Sales_USD])/NULLIF(tqc.[LTM_Qty],0)   END 
            - 
        CASE    WHEN    TQC.[LTM_Qty] IS NULL OR TQC.[LTM_Qty]=0
            THEN    sc2020.[Standard_Cost]*FX.Exchange_Rate
            ELSE    (TSC.[LTM_Cost_USD])/NULLIF(tqc.[LTM_Qty],0)    END                         AS Margin_per_Unit

     ,1- CASE   WHEN    TQC.[LTM_Qty] IS NULL OR TQC.[LTM_Qty]=0
            THEN    sc2020.[Standard_Cost]*FX.Exchange_Rate
            ELSE    (TSC.[LTM_Cost_USD])/NULLIF(tqc.[LTM_Qty],0)    END 
            /CASE   WHEN    TQC.[LTM_Qty] IS NULL OR TQC.[LTM_Qty]=0
            THEN    TLPC.Standard_List*FX.Exchange_Rate*(1-CPPG.[Discount Percentage])
            ELSE    (TSC.[LTM_Sales_USD])/NULLIF(tqc.[LTM_Qty],0)   END                         AS "Margin_at_ASP_as_%_of_ASP"

      ,(1-(CASE WHEN    TQC.[LTM_Qty] IS NULL OR TQC.[LTM_Qty]=0
                THEN    TLPC.Standard_List*FX.Exchange_Rate*(1-CPPG.[Discount Percentage])
                ELSE    (TSC.[LTM_Sales_USD])/NULLIF(tqc.[LTM_Qty],0) END)
                /NULLIF(TLPC.Standard_List*FX.Exchange_Rate,0))                                 AS "ASP_Discount_%"


      ,CASE WHEN TSC.[LTM_Sales_USD] > 0 
            THEN 'Y' ELSE 'N' END                                                       AS "Selling_History_Y/N"
      --,c.[Conversion_factor]                                                          AS "QDP_Quantity_Limit"

      ,CASE WHEN    [Number_of_Orders] IS NULL
            THEN    0
            ELSE    [Avg_Num_Units_per_Order]   END                                     AS "Avg. # Units per Order"     

      --,CASE WHEN [Avg_Num_Units_per_Order] IS NULL                    THEN c.[Conversion_factor]
            --WHEN [Avg_Num_Units_per_Order] > c.[Conversion_factor]    THEN CEILING([Avg_Num_Units_per_Order]/c.[Conversion_factor])
            --*c.[Conversion_factor]
            --ELSE c.[Conversion_factor] END                                                AS "Adjusted_QDP_Quantity_Limit"

      ,-((CASE WHEN [Number_of_Orders] IS NULL
            THEN    0
            ELSE    [Avg_Num_Units_per_Order]   END)
        --  /
        --CASE WHEN [Avg_Num_Units_per_Order] IS NULL                   THEN c.[Conversion_factor]
        --  WHEN [Avg_Num_Units_per_Order] > c.[Conversion_factor]  THEN CEILING([Avg_Num_Units_per_Order]/c.[Conversion_factor])
        --  *c.[Conversion_factor]
        --  ELSE c.[Conversion_factor] END)
        +
        (CASE WHEN (LTM_Qty-PTM_Qty)/NULLIF(LTM_Qty+PTM_Qty,0) IS NULL
              THEN 0
              ELSE (LTM_Qty-PTM_Qty)/NULLIF(LTM_Qty+PTM_Qty,0) END +1)/2)/2 + 1                 AS "GrowthNearQtyBreak"

      ,CASE WHEN TSC.[LTM_Sales_USD] IS NULL
            THEN 0
            ELSE TSC.[LTM_Sales_USD] END                                                AS "LTM_Sales_USD"
      ,CASE WHEN TSC.[LTM_Cost_USD] IS NULL
            THEN 0
            ELSE TSC.[LTM_Cost_USD] END                                                 AS "LTM_Cost_USD"
      ,CASE WHEN TSC.[PTM_Sales_USD] IS NULL
            THEN 0
            ELSE TSC.[PTM_Sales_USD] END                                                AS "PTM_Sales_USD"
      ,CASE WHEN Sales_Change IS NULL
            THEN 0
            ELSE Sales_Change END                                                       AS "Sales_Change"
      ,(CASE WHEN -(TSC.[LTM_Sales_USD]-[PTM_Sales_USD])/NULLIF(TSC.[LTM_Sales_USD]+[PTM_Sales_USD],0) IS NULL
            THEN 0
            ELSE -(TSC.[LTM_Sales_USD]-[PTM_Sales_USD])/NULLIF(TSC.[LTM_Sales_USD]+[PTM_Sales_USD],0) END
            +1)/2                                                                       AS "Sales Growth % (scaled)"      
      ,CASE WHEN LP_Change IS NULL
            THEN 0
            ELSE LP_Change END                                                          AS "LP_Change"
      ,CASE WHEN ((TLPC.[Standard_List]-TLPC.[PY_Standard_List])
                    /
                 (TLPC.[Standard_List]+TLPC.[PY_Standard_List]) + 1)/2 IS NULL
            THEN 0.5
            ELSE ((TLPC.[Standard_List]-TLPC.[PY_Standard_List])
                    /
                 (TLPC.[Standard_List]+TLPC.[PY_Standard_List]) + 1)/2  END             AS "List Price % Change (scaled)"
      ,CASE WHEN    [LTM_Qty] IS NULL
            THEN 0
            ELSE    [LTM_Qty] END                                                       AS "LTM_Qty"
      ,CASE WHEN    [PTM_Qty] IS NULL
            THEN 0
            ELSE    [PTM_Qty] END                                                       AS "PTM_Qty"
      ,CASE WHEN Qty_Change IS NULL
            THEN 0
            ELSE Qty_Change END                                                         AS "Qty_Change"
INTO #tempMAINA
FROM #templistandMSLP           a
--LEFT JOIN #ListPrice                                                  FLP
--  ON FLP.Item_Number=a.Item_Number
--  AND FLP.Country_IBS=a.COUNTRY_IBS
--  AND FLP.RowID='1'

LEFT JOIN [DATA_IBS].[dbo].[dim_Item_ALL_COUNTRIES]     ITEM with (nolock)  
    ON ITEM.Item_Number=a.Item_Number
    AND a.COUNTRY_IBS=ITEM.Country_IBS

--LEFT JOIN [PROJECTS_EU_List_Price_Roll].[dbo].[Product_Manager_Category_Director] PMCD
--  ON PMCD.Product_Manager=ITEM.Product_Manager_Name

LEFT JOIN Projects_Price_Volume_EU.[dbo].[GWFS_DI_CMT_TAXONOMY_HIER_TB] cmt
    ON   cast(ITEM.Leaf_node as varchar) = cast(cmt.[ID_TAXONOMY_NODE] as varchar) 

LEFT JOIN #tempPP2019   c               /* Joining the Purchase Price table to limit Supplier to =10 and date's current with today */
    ON a.item_number = c.Item_Number
    AND a.country_ibs = c.country_ibs


LEFT JOIN [DATA_IBS].[dbo].[fact_Quantity_Dependent_List_Prices_all_all_countries] b    /* Joining the QDP List Price table to exclude those items that already have QDP Pricing */
    ON a.Item_Number = b.Item_Number
    AND a.country_ibs = b.country_ibs
    --AND a.List_Price_Code = b.Price_list

LEFT JOIN #tempQtyChange                                                TQC
    ON a.Item_Number = TQC.Sku
    AND a.COUNTRY_IBS = TQC.country_IBS

LEFT JOIN #tempSalesChange                                              TSC
    ON a.Item_Number = TSC.Sku
    AND a.COUNTRY_IBS = TSC.country_IBS

LEFT JOIN #tempLPChange                                                 TLPC
    ON a.Item_Number = TLPC.Item_Number
    AND a.COUNTRY_IBS = TLPC.country_IBS

LEFT JOIN PROJECTS_QDP.dbo.QDP_Candidates_Avg_Sales_by_PPG_Code_202005          CPPG            /* Joining QDP Candidate table with PPG Code Avg. Sales for ASP for those candidates with no selling history */
    ON ITEM.PPG_Code=CPPG.PPG_Code
    AND ITEM.PPG_Desc=CPPG.PPG_Desc

--LEFT JOIN PROJECTS_Price_Volume_EU.dbo.Price_Volume_Cube_Master_EUROPE_TB_2018_OldSalesOrg    PV
--  ON a.COUNTRY_IBS=PV.country_IBS
--  AND a.Item_Number=PV.sku

LEFT JOIN DATA_IBS.dbo.dim_Country_Defaults_ALL_COUNTRIES               CD
    ON a.COUNTRY_IBS=CD.Country_Code

LEFT JOIN DATA_IBS.dbo.fact_Exchange_Rates_ALL_ALL_COUNTRIES        FX
    ON CD.Default_Currency=FX.Currency_Code_From
    AND FX.Currency_Code_To='USD'
    and FX.period=202004
left join #StandardCost2020 sc2020
    on a.country_ibs=sc2020.country_ibs
    and a.item_number=sc2020.item_number
--left join #QDPItems as Qdp
--  on a.country_ibs=Qdp.country_ibs
--  and a.item_number=Qdp.sku

WHERE --a.List_Price_Code = '01'
    --AND c.Conversion_Factor <> 1    -- will find all records with conversion factor <> 1, some of which have a QDP price, some do not
     --b.Item_Number IS NULL        -- will find all records without current QDP List  Price
    --and Qdp.sku is null               -- will exclude current qdp items with sales
     Item.PPG_Desc <> 'Third Party Products          '
    AND TLPC.Standard_List*FX.Exchange_Rate >= CASE WHEN    TQC.[LTM_Qty] IS NULL OR TQC.[LTM_Qty]=0
                                                    THEN    TLPC.Standard_List*FX.Exchange_Rate*(1-CPPG.[Discount Percentage])
                                                    ELSE    (TSC.[LTM_Sales_USD])/NULLIF(tqc.[LTM_Qty],0)   END 
    AND CASE    WHEN    TQC.[LTM_Qty] IS NULL OR TQC.[LTM_Qty]=0
                THEN    TLPC.Standard_List*FX.Exchange_Rate*(1-CPPG.[Discount Percentage])
                ELSE    (TSC.[LTM_Sales_USD])/NULLIF(tqc.[LTM_Qty],0)   END
        >
        CASE    WHEN    TQC.[LTM_Qty] IS NULL OR TQC.[LTM_Qty]=0
                THEN    sc2020.[Standard_Cost]*FX.Exchange_Rate
                ELSE    (TSC.[LTM_Cost_USD])/NULLIF(tqc.[LTM_Qty],0)    END 

3 个答案:

答案 0 :(得分:1)

我只看到两个可能的地方:

如果TSC.[LTM_Sales_USD]为零而tqc.[LTM_Qty]不为零,则该除法表达式的底部可能为零:

1- CASE   WHEN    TQC.[LTM_Qty] IS NULL OR TQC.[LTM_Qty]=0
        THEN    sc2020.[Standard_Cost]*FX.Exchange_Rate
        ELSE    (TSC.[LTM_Cost_USD])/NULLIF(tqc.[LTM_Qty],0)    END 
        /CASE   WHEN    TQC.[LTM_Qty] IS NULL OR TQC.[LTM_Qty]=0
        THEN    TLPC.Standard_List*FX.Exchange_Rate*(1-CPPG.[Discount Percentage])
        ELSE    (TSC.[LTM_Sales_USD])/NULLIF(tqc.[LTM_Qty],0)   END   

同样,如果WHEN为零(或者如果我正在读取的顺序为-1,则ELSETLPC.[Standard_List]+TLPC.[PY_Standard_List]的底部都可以为零。操作错误):

  ,CASE WHEN ( (TLPC.[Standard_List]-TLPC.[PY_Standard_List])
                /
              (TLPC.[Standard_List]+TLPC.[PY_Standard_List]) + 1
            )/2 IS NULL
        THEN 0.5
        ELSE ((TLPC.[Standard_List]-TLPC.[PY_Standard_List])
                /
             (TLPC.[Standard_List]+TLPC.[PY_Standard_List]) + 1)/2  END   

答案 1 :(得分:0)

我发现可能会被零除的行:

"Margin_at_ASP_as_%_of_ASP"

.../CASE   WHEN    TQC.[LTM_Qty] IS NULL OR TQC.[LTM_Qty]=0
            THEN    TLPC.Standard_List*FX.Exchange_Rate*(1-CPPG.[Discount Percentage])
            ELSE    (TSC.[LTM_Sales_USD])/NULLIF(tqc.[LTM_Qty],0)   END

THEN或ELSE都可能为0。

"List Price % Change (scaled)"

CASE WHEN ((TLPC.[Standard_List]-TLPC.[PY_Standard_List])
                    /
                 (TLPC.[Standard_List]+TLPC.[PY_Standard_List]) + 1)/2 IS NULL
           THEN 0.5
            ELSE ((TLPC.[Standard_List]-TLPC.[PY_Standard_List])
                    /
                 (TLPC.[Standard_List]+TLPC.[PY_Standard_List]) + 1)/2  END

WHEN和ELSE都可能为0。

旁注–我是否只是为您搜索每个/并找到所有没有nullif的注释?

答案 2 :(得分:0)

两个简单但手动的技巧:

选项1:注释掉所有输出字段,然后逐个取消注释它们并运行查询直到出现错误。您应该能够找出导致错误的字段或表达式,但它可能不是唯一的。

选项2:将结果集限制为TOP 10,TOP 1000等,直到触发错误为止。然后减少记录数,直到错误消失。最好包括所有联接表的ID,以便您可以查明所涉及的记录。并按ID排序。如果错误是在ID 999之后发生的,那么您可能知道问题的下一个ID(1000或类似的数字)。

我将从选项#1开始。确定表达式有问题后,请分别输出各个字段/值。一切都应该变得清楚。

例如,如果您注意到此表达式崩溃了:

  ,CASE WHEN    TQC.[LTM_Qty] IS NULL OR TQC.[LTM_Qty]=0
        THEN    TLPC.Standard_List*FX.Exchange_Rate*(1-CPPG.[Discount Percentage])
        ELSE    (TSC.[LTM_Sales_USD])/NULLIF(tqc.[LTM_Qty],0)   END                         AS "ASP_USD"

然后输出这些列:

TQC.[LTM_Qty],
TLPC.Standard_List,
FX.Exchange_Rate,
CPPG.[Discount Percentage],
TSC.[LTM_Sales_USD]

然后查看这些值,尤其是tqc.[LTM_Qty]