Sql server 有没有办法确定哪一行代码有被零除的错误?

Sql server 有没有办法确定哪一行代码有被零除的错误?,sql-server,Sql Server,我遇到了一个被零除的错误,从SELECT语句的起始位置开始,但不确定错误的确切位置。我在有除法命令的地方放置了NULLIF,0,但仍然返回被零除的错误。有没有一种方法可以精确定位错误的触发位置 drop table #tempMAINA SELECT a.COUNTRY_IBS --,a.[List_Price_Code] AS "LPC" ,a.[Item_Number] --,

我遇到了一个被零除的错误,从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 

我发现可以产生被零除的线:

在ASP处的利润率为ASP的%

THEN或ELSE可能导致0

标价百分比变动比例

WHEN和ELSE都可能导致0


旁注-我是否只是为您搜索了每个/并找到了所有不带nullif的?

我只看到了两个可能的位置:

如果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   
还有这个表达式,如果TLPC。[Standard_List]+TLPC。[PY_Standard_List]为零,则WHEN和ELSE部分的底部都可以为零,如果我读取的操作顺序错误,则可能为-1:

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

选项2:将结果集限制在前10名、前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\U Qty]。

当你得到一个被零除的错误时,它不会告诉你行。我建议从没有NULLIF{divisior},0的除法开始,因为有几个除法。另外,为什么你的别名一直在最右边,没有人可以看到它们而不滚动?请查看页边空白处的页边空白处的页边空白处的页边空白处的页边空白处的页边空白处的页边空白处的页边空白处的页边空白处的页边空白处的页边空白处的页边空白处的页边空白处的页边空白处的页边空白处。分母的CASE语句可能会产生这样的错误。哇,你真的希望有人能通过这个怪物式的表达吗把它分成更小、更易消化的部分怎么样?附加说明:。例如,事实、数量、依赖、列表、价格、所有国家都没有一个b,那么为什么它的别名是b呢?而且,这是一个很长的对象名。
  ,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]