SQL 服务器 - 存储过程出现意外结果

SQL Server - Stored Proc Unexpected Result

CREATE PROC [dbo].[SP_GetListOfGoodsReceiptNote] (@MinDate AS DATETIME, @MaxDate AS DATETIME, @CompanyID AS INT, @ProductID AS INT = NULL, @TradePartnerID AS INT = NULL, @PurchaseOrderID AS INT = NULL)
AS
BEGIN
    SELECT 
        CVH.ID, CVH.VoucherTypeID, CVH.VoucherDate, CVH.VoucherNumber, CVH.CompanyID, CVH.ReferenceVoucherID, CVH.VoucherAmount, CVH.VoucherStatus, CCP.TradePartnerID, CPMR.PartnerName
    FROM
        CruxVoucherHeader CVH
        LEFT OUTER JOIN CruxCorePurchase CCP ON CCP.VoucherHeaderID = CVH.ID
        LEFT OUTER JOIN CruxPartnerMaster CPMR ON CCP.TradePartnerID = CPMR.ID
        LEFT OUTER JOIN CruxVoucherBody CVB ON CVB.VoucherHeaderID = CVH.ID
    WHERE 
        CVH.VoucherDate >= @MinDate 
        AND CVH.VoucherDate <= @MaxDate
        AND CVH.CompanyID = @CompanyID
        AND CVH.VoucherTypeID = 3
        AND @ProductID IS NULL OR CVB.ProductID = @ProductID        
        AND @TradePartnerID IS NULL OR CCP.TradePartnerID = @TradePartnerID
        AND @PurchaseOrderID IS NULL OR CVH.ReferenceVoucherID = @PurchaseOrderID
END

我在从上述存储过程中获取预期结果时遇到了一些问题。如果您看到,我已经使用 CVH.VoucherTypeID = 3 过滤了数据,但仍然由于某些未知原因我得到了附加的结果。我在编写存储过程时是否犯了任何概念性错误。 ?

这就是我执行存储过程的方式。

EXEC SP_GetListOfGoodsReceiptNote '2020/01/01','2021/02/02', 2, NULL, 74, NULL

由于 And 运算符优先于 Or 运算符, 所以,如果有一个表达式 A = B and C is null or C = D and 运算符将在 or 运算符部分

之前被评估

所以如果你需要先评估or部分需要放在括号里 成为 A = B and (C is null or C = D)

所以 WHERE 子句看起来需要括号如下:

WHERE CVH.VoucherDate >= @MinDate AND
      CVH.VoucherDate <= @MaxDate AND
      CVH.CompanyID = @CompanyID AND
      CVH.VoucherTypeID = 3 AND
      (@ProductID IS NULL OR CVB.ProductID = @ProductID) AND        
      (@TradePartnerID IS NULL OR CCP.TradePartnerID = @TradePartnerID) AND
      (@PurchaseOrderID IS NULL OR CVH.ReferenceVoucherID = @PurchaseOrderID)

有关运算符优先级的更多信息,请遵循此 link