除以零错误发生 SQL 服务器

Division by Zero error Occurred SQL Server

我有一个函数,我正在其中接收 "Division by Zero Error Occurred" 消息。这是我的功能:

    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

我假设这是一个错误,我开始划分以找到几个不同的列。大多数 select 语句都是相同的,除了 case 最终是什么。所以我猜这方面是我遇到问题的地方:

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。

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会使denominatorzero时变成null