2015-01-02 28 views
-2

我有一個函數,在那裏我收到一個「由零錯誤發生分區」消息。這裏是我的功能:除以零發生錯誤發生SQL Server

ALTER FUNCTION dbo.Commission 
    (
    @startdate DateTime, 
    @enddate Datetime, 
    @storenumber int, 
    @tier1 int, 
    @tier2 int, 
    @tier1amount int, 
    @tier2amount int 

    ) 
RETURNS Table 
AS 

    RETURN 


SELECT  A.Name, A.Total_Customers1, A.Amount, CASE WHEN B.Service1_Only_Customers1 IS NULL THEN '0' ELSE B.Service1_Only_Customers1 END AS Service1_Only_Customers1, 
         CASE WHEN B.Service1_Only_Amount IS NULL THEN '0' ELSE CAST(CAST(B.Service1_Only_Amount AS Float) AS decimal(10, 2)) END AS Service1_Only_Amount, 
         A.Total_Customers1 - ISNULL(B.Service1_Only_Customers1, 0) AS Payable_Customers1, A.Amount - ISNULL(B.Service1_Only_Amount, 0) - ISNULL(C.Service2_Sales, 0) 
         AS Payable_Amount, CAST((A.Amount - ISNULL(B.Service1_Only_Amount, 0) - ISNULL(C.Service2_Sales, 0))/(A.Total_Customers1 - ISNULL(B.Service1_Only_Customers1, 0)) 
         AS Decimal(10, 2)) AS Payable_Average, CASE WHEN (CAST(A.Amount AS float) - ISNULL(B.Service1_Only_Amount, 0) - ISNULL(C.Service2_Sales, 0)) 
        /(A.Total_Customers1 - ISNULL(B.Service1_Only_Customers1, 0)) BETWEEN @Tier1 AND @Tier2 THEN '1' WHEN (CAST(A.Amount AS float) - ISNULL(B.Service1_Only_Amount, 0) 
         - ISNULL(C.Service2_Sales, 0))/(A.Total_Customers1 - ISNULL(B.Service1_Only_Customers1, 0)) < @Tier1 THEN '0' WHEN (CAST(A.Amount AS float) 
         - ISNULL(B.Service1_Only_Amount, 0) - ISNULL(C.Service2_Sales, 0))/(A.Total_Customers1 - ISNULL(B.Service1_Only_Customers1, 0)) >= @Tier2 THEN '2' END AS PayoutTier, 
         CASE WHEN (CAST(A.Amount AS float) - ISNULL(B.Service1_Only_Amount, 0))/(A.Total_Customers1 - ISNULL(B.Service1_Only_Customers1, 0)) BETWEEN @Tier1 AND 
         @Tier2 THEN ((CAST(A.Amount AS float) - ISNULL(B.Service1_Only_Amount, 0) - ISNULL(C.Service2_Sales, 0)) * @Tier1Amount)/100 WHEN (CAST(A.Amount AS float) 
         - ISNULL(B.Service1_Only_Amount, 0) - ISNULL(C.Service2_Sales, 0))/(A.Total_Customers1 - ISNULL(B.Service1_Only_Customers1, 0)) 
         < @Tier1 THEN '0' WHEN (CAST(A.Amount AS float) - ISNULL(B.Service1_Only_Amount, 0) - ISNULL(C.Service2_Sales, 0)) 
        /(A.Total_Customers1 - ISNULL(B.Service1_Only_Customers1, 0)) >= @Tier2 THEN ((CAST(A.Amount AS float) - ISNULL(B.Service1_Only_Amount, 0) - ISNULL(C.Service2_Sales, 0)) 
         * @Tier2Amount)/100 END AS PayoutAmount, ISNULL(C.Service2_Sales, 0) AS Service2_Sales 
FROM   (SELECT  COUNT(Invoice_Tb.Invoice_Number) AS Total_Customers1, SUM(Invoice_Tb.Net_Sales) AS Amount, 
               Employee_Tb.First_Name + ' ' + Employee_Tb.Last_Name AS Name 
         FROM   User_Tb RIGHT OUTER JOIN 
               Invoice_Tb LEFT OUTER JOIN 
               Invoice_User_Role_Tb ON Invoice_Tb.Store_Number = Invoice_User_Role_Tb.Store_Number AND 
               Invoice_Tb.Invoice_Number = Invoice_User_Role_Tb.Invoice_Number AND Invoice_Tb.Invoice_Date = Invoice_User_Role_Tb.Invoice_Date ON 
               User_Tb.User_Name = Invoice_User_Role_Tb.User_Name LEFT OUTER JOIN 
               Employee_Tb ON User_Tb.User_Id = Employee_Tb.User_Id 
         WHERE  (Invoice_User_Role_Tb.User_Role = 'Advisor') AND (Invoice_Tb.Invoice_Date >= @startdate) AND (Invoice_Tb.Store_Number = @storenumber) AND 
               (Invoice_Tb.Invoice_Date <= @enddate) 
         GROUP BY Employee_Tb.First_Name, Employee_Tb.Last_Name) AS A LEFT OUTER JOIN 
          (SELECT  SUM(Invoice_Detail_Tb_1.Extended_Price) AS Service2_Sales, Employee_Tb_2.First_Name + ' ' + Employee_Tb_2.Last_Name AS Name 
          FROM   Invoice_Detail_Tb AS Invoice_Detail_Tb_1 LEFT OUTER JOIN 
                Employee_Tb AS Employee_Tb_2 INNER JOIN 
                User_Tb AS User_Tb_2 ON Employee_Tb_2.User_Id = User_Tb_2.User_Id INNER JOIN 
                Invoice_User_Role_Tb AS Invoice_User_Role_Tb_2 ON User_Tb_2.User_Name = Invoice_User_Role_Tb_2.User_Name ON 
                Invoice_Detail_Tb_1.Invoice_Number = Invoice_User_Role_Tb_2.Invoice_Number 
          WHERE  (Invoice_Detail_Tb_1.Store_Number = @storenumber) AND (Invoice_Detail_Tb_1.Invoice_Date BETWEEN @startdate AND @enddate) AND 
                (Invoice_User_Role_Tb_2.User_Role = 'Advisor') AND (Invoice_Detail_Tb_1.Category_Code LIKE 'BRK') OR 
                (Invoice_Detail_Tb_1.Store_Number = @storenumber) AND (Invoice_Detail_Tb_1.Invoice_Date BETWEEN @startdate AND @enddate) AND 
                (Invoice_User_Role_Tb_2.User_Role = 'Advisor') AND (Invoice_Detail_Tb_1.Category_Code LIKE 'BRR') OR 
                (Invoice_Detail_Tb_1.Store_Number = @storenumber) AND (Invoice_Detail_Tb_1.Invoice_Date BETWEEN @startdate AND @enddate) AND 
                (Invoice_User_Role_Tb_2.User_Role = 'Advisor') AND (Invoice_Detail_Tb_1.Category_Code LIKE 'BRA') OR 
                (Invoice_Detail_Tb_1.Store_Number = @storenumber) AND (Invoice_Detail_Tb_1.Invoice_Date BETWEEN @startdate AND @enddate) AND 
                (Invoice_User_Role_Tb_2.User_Role = 'Advisor') AND (Invoice_Detail_Tb_1.Category_Code LIKE 'BRD') OR 
                (Invoice_Detail_Tb_1.Store_Number = @storenumber) AND (Invoice_Detail_Tb_1.Invoice_Date BETWEEN @startdate AND @enddate) AND 
                (Invoice_User_Role_Tb_2.User_Role = 'Advisor') AND (Invoice_Detail_Tb_1.Category_Code LIKE 'BRRI') OR 
                (Invoice_Detail_Tb_1.Store_Number = @storenumber) AND (Invoice_Detail_Tb_1.Invoice_Date BETWEEN @startdate AND @enddate) AND 
                (Invoice_User_Role_Tb_2.User_Role = 'Advisor') AND (Invoice_Detail_Tb_1.Category_Code LIKE 'BRP') OR 
                (Invoice_Detail_Tb_1.Store_Number = @storenumber) AND (Invoice_Detail_Tb_1.Invoice_Date BETWEEN @startdate AND @enddate) AND 
                (Invoice_User_Role_Tb_2.User_Role = 'Advisor') AND (Invoice_Detail_Tb_1.Category_Code LIKE 'BRS') OR 
                (Invoice_Detail_Tb_1.Store_Number = @storenumber) AND (Invoice_Detail_Tb_1.Invoice_Date BETWEEN @startdate AND @enddate) AND 
                (Invoice_User_Role_Tb_2.User_Role = 'Advisor') AND (Invoice_Detail_Tb_1.Category_Code LIKE 'LER') 
          GROUP BY Invoice_User_Role_Tb_2.User_Name, Employee_Tb_2.First_Name, Employee_Tb_2.Last_Name) AS C ON A.Name = C.Name LEFT OUTER JOIN 
          (SELECT  Employee_Tb_1.First_Name + ' ' + Employee_Tb_1.Last_Name AS Name, COUNT(DISTINCT Invoice_Detail_Tb.Invoice_Number) 
                AS Service1_Only_Customers1, SUM(Invoice_Tb_1.Invoice_Net_Sales) AS Service1_Only_Amount 
          FROM   User_Tb AS User_Tb_1 INNER JOIN 
                Employee_Tb AS Employee_Tb_1 ON User_Tb_1.User_Id = Employee_Tb_1.User_Id INNER JOIN 
                Invoice_Detail_Tb INNER JOIN 
                Invoice_Tb AS Invoice_Tb_1 ON Invoice_Detail_Tb.Store_Number = Invoice_Tb_1.Store_Number AND 
                Invoice_Detail_Tb.Invoice_Number = Invoice_Tb_1.Invoice_Number AND Invoice_Detail_Tb.Invoice_Date = Invoice_Tb_1.Invoice_Date INNER JOIN 
                Invoice_User_Role_Tb AS Invoice_User_Role_Tb_1 ON Invoice_Tb_1.Store_Number = Invoice_User_Role_Tb_1.Store_Number AND 
                Invoice_Tb_1.Invoice_Number = Invoice_User_Role_Tb_1.Invoice_Number AND Invoice_Tb_1.Invoice_Date = Invoice_User_Role_Tb_1.Invoice_Date ON 
                User_Tb_1.User_Name = Invoice_User_Role_Tb_1.User_Name 
          WHERE  (Invoice_Detail_Tb.Invoice_Detail_Code = 'serv0') AND (Invoice_User_Role_Tb_1.User_Role = 'Advisor') AND 
                (Invoice_Detail_Tb.Invoice_Date >= @startdate) AND (Invoice_Tb_1.Invoice_Net_Sales <= 21) AND (Invoice_Detail_Tb.Invoice_Date <= @enddate) AND 
                (Invoice_Detail_Tb.Store_Number = @storenumber) OR 
                (Invoice_Detail_Tb.Invoice_Detail_Code = 'serv1') AND (Invoice_User_Role_Tb_1.User_Role = 'Advisor') AND 
                (Invoice_Detail_Tb.Invoice_Date >= @startdate) AND (Invoice_Tb_1.Invoice_Net_Sales <= 10) AND (Invoice_Detail_Tb.Invoice_Date <= @enddate) AND 
                (Invoice_Detail_Tb.Store_Number = @storenumber) OR 
                (Invoice_Detail_Tb.Invoice_Detail_Code = 'serv2') AND (Invoice_User_Role_Tb_1.User_Role = 'Advisor') AND 
                (Invoice_Detail_Tb.Invoice_Date >= @startdate) AND (Invoice_Tb_1.Invoice_Net_Sales <= 15) AND (Invoice_Detail_Tb.Invoice_Date <= @enddate) AND 
                (Invoice_Detail_Tb.Store_Number = @storenumber) OR 
                (Invoice_Detail_Tb.Invoice_Detail_Code = 'serv3') AND (Invoice_User_Role_Tb_1.User_Role = 'Advisor') AND 
                (Invoice_Detail_Tb.Invoice_Date >= @startdate) AND (Invoice_Tb_1.Invoice_Net_Sales <= 26) AND (Invoice_Detail_Tb.Invoice_Date <= @enddate) AND 
                (Invoice_Detail_Tb.Store_Number = @storenumber) OR 
                (Invoice_Detail_Tb.Invoice_Detail_Code = 'serv4') AND (Invoice_User_Role_Tb_1.User_Role = 'Advisor') AND 
                (Invoice_Detail_Tb.Invoice_Date >= @startdate) AND (Invoice_Tb_1.Invoice_Net_Sales <= 6) AND (Invoice_Detail_Tb.Invoice_Date <= @enddate) AND 
                (Invoice_Detail_Tb.Store_Number = @storenumber) OR 
                (Invoice_Detail_Tb.Invoice_Detail_Code = 'serv5') AND (Invoice_User_Role_Tb_1.User_Role = 'Advisor') AND 
                (Invoice_Detail_Tb.Invoice_Date >= @startdate) AND (Invoice_Tb_1.Invoice_Net_Sales <= 11) AND (Invoice_Detail_Tb.Invoice_Date <= @enddate) AND 
                (Invoice_Detail_Tb.Store_Number = @storenumber) 
          GROUP BY Employee_Tb_1.First_Name, Employee_Tb_1.Last_Name) AS B ON A.Name = B.Name 

我認爲這是一個錯誤,我開始分裂找到幾個不同的列。大多數選擇語句與情況最終的例外情況相同。所以我在這方面我猜是哪裏我遇到的問題:

CASE WHEN (CAST(A.Amount AS float) - ISNULL(B.Service1_Only_Amount, 0) - ISNULL(C.Service2_Sales, 0)) 
         /(A.Total_Customers1 - ISNULL(B.Service1_Only_Customers1, 0)) BETWEEN @Tier1 AND @Tier2 THEN '1' 

我試過的代碼調整到:

CASE WHEN Coalesce((CAST(A.Amount AS float) - ISNULL(B.Service1_Only_Amount, 0) - ISNULL(C.Service2_Sales, 0)) 
         /(A.Total_Customers1 - ISNULL(B.Service1_Only_Customers1, 0)) ,0)BETWEEN @Tier1 AND @Tier2 THEN '1' 

而且我也試過:

CASE WHEN (CAST(A.Amount AS float) - ISNULL(B.Service1_Only_Amount, 0) - ISNULL(C.Service2_Sales, 0)) 
         /(A.Total_Customers1 - NULLIF(B.Service1_Only_Customers1, 0)) BETWEEN @Tier1 AND @Tier2 THEN '1' 

我最後的嘗試是:

CASE WHEN Coalesce((CAST(A.Amount AS float) - ISNULL(B.Service1_Only_Amount, 0) - ISNULL(C.Service2_Sales, 0)) 
         /(A.Total_Customers1 - ISNULL(B.Service1_Only_Customers1, 0)),0) BETWEEN @Tier1 AND @Tier2 THEN '1' 

ç任何人都能提供一些見解。我不知道什麼是'0'或Null在這一點拋出異常。

回答

2

Division by Zero error將發生在查詢發生這種情況時發生。

select 1/0 

使用NULLIF()功能,避免divide by zero exeption

改變所有的報表與division到這樣的事情。

CASE WHEN (CAST(A.Amount AS float) - ISNULL(B.Service1_Only_Amount, 0) - ISNULL(C.Service2_Sales, 0)) 
         /Nullif((A.Total_Customers1 - ISNULL(B.Service1_Only_Customers1, 0)) BETWEEN @Tier1 AND @Tier2 THEN '1',0) 

這裏Nullif將使denominatornull當它是zero

+0

這工作完美。我沒有想到在整個分母中使用NULLIF。謝謝! – Shmewnix