合并未正确检查

时间:2013-06-18 15:35:28

标签: tsql stored-procedures

我有这个存储过程按预期工作,除了一个缺陷。在总结查询的计费部分时,我需要考虑NULL值。如果不存在值,则数据库默认为NULL,这导致我的最终计算为NULL。为了解决这个问题,我想使用COALESCE函数强制任何列返回0,如果它们被发现是NULL,那么我的计算工作正常。

目前我只在BillAdjustmentCTE CTE的AdjustFeeAmountTotal列上进行测试,因为只需在所需列上使用COALESCE函数就行了。我在下面的当前实现仍然为AdjustFeeAmountTotal列返回NULL。

任何人都知道为什么?

 ALTER PROCEDURE [dbo].[GetRollCallData] 
    @Ids        VARCHAR(255),
    @LexiconId  INT,
    @UUID       UNIQUEIDENTIFIER,
    @ReadOnly   INT
 AS

 DECLARE @TableCode INT
 SET @TableCode = 58;

 IF @Ids <> ''
    BEGIN
        EXEC InsertInSelectionCache @Ids, @UUID, @TableCode, 0
        IF @ReadOnly = 1
            With DOACTE AS(
                SELECT ROW_NUMBER() OVER(PARTITION BY [File].Id ORDER BY CustomRecordsetId DESC) AS RowNumber, [File].*, FileType2Lexicon.Label as FileTypeLabel, [People].DefaultPhone, [People].InvertedName as ClientInvertedName, CustomField.Name as FieldLabel, CustomFieldValue.Value as FieldValue
                    FROM FileType2Lexicon, SelectionCache, [People], [File]
                    INNER JOIN [CustomRecordSet]
                    ON [CustomRecordset].RecordId = [File].Id
                    INNER JOIN CustomFieldValue
                    ON  [CustomRecordset].Id = CustomFieldValue.CustomRecordsetId
                    INNER JOIN [CustomField2Lexicon]
                    ON CustomField2Lexicon.CustomFieldId = CustomFieldValue.CustomFieldId
                    INNER JOIN [CustomField]
                    ON CustomField.Id = CustomField2Lexicon.CustomFieldId
                    WHERE   [File].Id = SelectionCache.RecordId
                    AND SelectionCache.UUID = @UUID
                    AND SelectionCache.TableCode = @TableCode -- this is the code for File table  
                    AND     [File].Id <> 0 
                    AND     [File].FileTypeId = FileType2Lexicon.FileTypeId 
                    AND     FileType2Lexicon.LexiconId = @LexiconId
                    AND     [File].ClientIdString = [People].ClientIdString
                    AND     CustomFieldValue.Value <> ''),

            SolicitorCTE AS(
                SELECT [People].Name AS SolicitorName, [People].InvertedName as InvertedSolicitorName, [File].Id
                FROM SelectionCache, [File]
                INNER JOIN [People2File]
                ON [People2File].FileId = [File].Id
                INNER JOIN [Role2Lexicon]
                ON [Role2Lexicon].RoleId = [People2File].RoleId
                INNER JOIN [People]
                ON [People].Id = [People2File].PeopleId
                WHERE 
                [File].Id = SelectionCache.RecordId
                AND SelectionCache.UUID = @UUID
                AND SelectionCache.TableCode = @TableCode -- this is the code for File table  
                AND [File].Id <> 0
                AND [Role2Lexicon].Label = 'Solicitor'),        

            ArrestingOfficerCTE AS(
                SELECT COALESCE(ROW_NUMBER() OVER(PARTITION BY [File].Id ORDER BY [People].InvertedName ASC), NULL) AS RowNumber, COALESCE([People].Name, NULL) AS ArrestingOfficerName, COALESCE([People].CompanyName, NULL)  AS ArrestingOfficerCompany, [File].Id
                FROM SelectionCache, [File]
                INNER JOIN [People2File]
                ON [People2File].FileId = [File].Id
                INNER JOIN [Role2Lexicon]
                ON [Role2Lexicon].RoleId = [People2File].RoleId
                INNER JOIN [People]
                ON [People].Id = [People2File].PeopleId
                WHERE 
                [File].Id = SelectionCache.RecordId
                AND SelectionCache.UUID = @UUID
                AND SelectionCache.TableCode = @TableCode -- this is the code for File table  
                AND [File].Id <> 0
                AND [Role2Lexicon].Label = 'Arresting Officer'),

                BillCTE As(
                    SELECT [File].Id, SUM(Bill.BilledFee) as BilledFeeTotal, SUM(Bill.BilledExpense) as BilledExpenseTotal, SUM(Bill.BilledTax1) as BilledTax1Total, SUM(Bill.BilledTax2) as BilledTax2Total, SUM(Bill.BilledInterest) as BilledInterestTotal
                        FROM SelectionCache, [File]
                        INNER JOIN [Bill]
                        ON [File].Id = Bill.FileId
                        WHERE
                        [File].Id = SelectionCache.RecordId
                        AND SelectionCache.UUID = @UUID
                        AND SelectionCache.TableCode = @TableCode -- this is the code for File table  
                        AND [File].Id <> 0
                        GROUP BY [File].Id),

                BillPaymentCTE As(
                    SELECT [File].Id, SUM(BillPayment.FeeAmount) as PaidFeeAmountTotal, SUM(BillPayment.ExpenseAmount) as PaidExpenseAmountTotal, SUM(BillPayment.Tax1) as PaidTax1Total, SUM(BillPayment.Tax2) as PaidTax2Total, SUM(BillPayment.InterestAmount) as PaidInterestAmountTotal
                        FROM SelectionCache, [File]
                        INNER JOIN [Bill]
                        ON [File].Id = Bill.FileId
                        INNER JOIN [BillPayment]
                        ON [Bill].Id = BillPayment.BillId
                        WHERE
                        [File].Id = SelectionCache.RecordId
                        AND SelectionCache.UUID = @UUID
                        AND SelectionCache.TableCode = @TableCode -- this is the code for File table  
                        AND [File].Id <> 0
                        GROUP BY [File].Id),

                BillAdjustmentCTE AS(
                     SELECT [File].Id, COALESCE((SUM(BillAdjustment.FeeAmount)), 0) as AdjustFeeAmountTotal, SUM(COALESCE(BillAdjustment.ExpenseAmount, 0)) as AdjustExpenseAmountTotal
                        FROM SelectionCache, [File]
                        INNER JOIN [Bill]
                        ON [File].Id = Bill.FileId
                        INNER JOIN [BillAdjustment]
                        ON [Bill].Id = BillAdjustment.BillId
                        WHERE
                        [File].Id = SelectionCache.RecordId
                        AND SelectionCache.UUID = @UUID
                        AND SelectionCache.TableCode = @TableCode -- this is the code for File table  
                        AND [File].Id <> 0
                        GROUP BY [File].Id),

            PivotCTE AS(
                SELECT *
                FROM
                (Select Id, FieldLabel, FieldValue FROM DOACTE) AS Source
                PIVOT(
                MAX(FieldValue) FOR FieldLabel IN ([Date_Arrest], [Graphic_Client], [Ticket_1], [Ticket_2], [Ticket_3], [Ticket_4], [Ticket_5], [Charge_1], [Charge_2], [Charge_3], [Charge_4], [Charge_5])) as Pvt
                )

            SELECT DOACTE.*, 
                    COALESCE(ArrestingOfficerCTE.ArrestingOfficerCompany, NULL)AS ArrestingOfficerCompany, COALESCE(ArrestingOfficerCTE.ArrestingOfficerName, NULL) AS ArrestingOfficerName, 
                    COALESCE(SolicitorCTE.SolicitorName, NULL) as SolicitorName, COALESCE(SolicitorCTE.InvertedSolicitorName, NULL) as InvertedSolicitorName, 
                    PivotCTE.[Date_Arrest], dbo.GetImagebyId(PivotCTE.[Graphic_Client]) as Photo, PivotCTE.[Ticket_1], PivotCTE.[Ticket_2], PivotCTE.[Ticket_3], PivotCTE.[Ticket_4], PivotCTE.[Ticket_5], PivotCTE.[Charge_1], PivotCTE.[Charge_2], PivotCTE.[Charge_3], PivotCTE.[Charge_4], PivotCTE.[Charge_5], 
                    BillCTE.BilledFeeTotal, BillCTE.BilledExpenseTotal, BillCTE.BilledTax1Total, BillCTE.BilledTax2Total, BillCTE.BilledInterestTotal, (BillCTE.BilledFeeTotal + BillCTE.BilledExpenseTotal + BillCTE.BilledTax1Total + BillCTE.BilledTax2Total + BillCTE.BilledInterestTotal) AS BillTotal,
                    BillPaymentCTE.PaidFeeAmountTotal, BillPaymentCTE.PaidExpenseAmountTotal, BillPaymentCTE.PaidTax1Total, BillPaymentCTE.PaidTax2Total, BillPaymentCTE.PaidInterestAmountTotal, (BillPaymentCTE.PaidFeeAmountTotal + BillPaymentCTE.PaidExpenseAmountTotal + BillPaymentCTE.PaidTax1Total + BillPaymentCTE.PaidTax2Total + BillPaymentCTE.PaidInterestAmountTotal) AS BillPaymentTotal,
                    BillAdjustmentCTE.AdjustFeeAmountTotal, BillAdjustmentCTE.AdjustExpenseAmountTotal, (BillAdjustmentCTE.AdjustFeeAmountTotal + BillAdjustmentCTE.AdjustExpenseAmountTotal) AS BillAdjustmentTotal,
                    ((BillCTE.BilledFeeTotal + BillCTE.BilledExpenseTotal + BillCTE.BilledTax1Total + BillCTE.BilledTax2Total + BillCTE.BilledInterestTotal) + (BillAdjustmentCTE.AdjustFeeAmountTotal + BillAdjustmentCTE.AdjustExpenseAmountTotal) - (BillPaymentCTE.PaidFeeAmountTotal + BillPaymentCTE.PaidExpenseAmountTotal + BillPaymentCTE.PaidTax1Total + BillPaymentCTE.PaidTax2Total + BillPaymentCTE.PaidInterestAmountTotal)) AS AccountsReceivable
                FROM DOACTE
                INNER JOIN 
                PivotCTE
                ON DOACTE.Id = PivotCTE.Id
                LEFT JOIN
                SolicitorCTE
                ON DOACTE.Id = SolicitorCTE.Id
                LEFT JOIN
                ArrestingOfficerCTE
                ON DOACTE.Id = ArrestingOfficerCTE.Id
                LEFT JOIN
                BillCTE
                ON DOACTE.Id = BillCTE.Id 
                LEFT JOIN
                BillAdjustmentCTE
                ON DOACTE.Id = BillAdjustmentCTE.Id
                LEFT JOIN
                BillPaymentCTE
                ON DOACTE.Id = BillPaymentCTE.Id
                WHERE DOACTE.RowNumber = 1
                AND (ArrestingOfficerCTE.RowNumber < 2
                OR ArrestingOfficerName IS NULL)




        ELSE

        DELETE SelectionCache 
            WHERE UUID = @UUID
            AND   TableCode = @TableCode
    END

 RETURN

1 个答案:

答案 0 :(得分:1)

它是因为你在CTE级别进行COALESCEing(因此CTE将为NULL值返回0),但是你正在对CTE进行LEFT JOIN。如果没有为CTE返回任何行,则LEFT JOIN将返回NULL。您需要在SELECT语句级别进行COALESCE以补偿这一点。