繁体   English   中英

SQL嵌套的IF-ELSE语句

[英]SQL Nested IF-ELSE Statements

好吧,我正式亏本。 我正在尝试创建一个贯穿每个后续检查并执行相应查询的过程。

但是,当我使用一个/两个/所有参数执行该过程时,它总是被捕获在最终的ELSE中并吐出“全部覆盖”结果集。 为什么???

我怀疑它可能是:-If / Else语法 - 使用括号-Begin / End keywords -Too很多IF条件?

非常感谢任何帮助!

加分点:我可以使用WHERE子句中的搜索CASE对其进行优化吗? 我知道我可以真正削减这些代码 - 但我真的好奇为什么这不起作用。

CREATE PROC spBalanceRange
    @VendorVar varchar(50) = NULL,
    @BalanceMax money = NULL,
    @BalanceMin money = NULL

AS
    IF
    (
        @VendorVar != NULL
        AND @BalanceMin != NULL             
        AND @BalanceMax != NULL
    )

    BEGIN
        SELECT VendorName, InvoiceNumber, InvoiceTotal - (PaymentTotal + CreditTotal) AS BalanceDue
        FROM Invoices JOIN Vendors
            ON Invoices.VendorID = Vendors.VendorID
        WHERE
            VendorName = @VendorVar
            AND InvoiceTotal - (PaymentTotal + CreditTotal) >= @BalanceMin
            AND InvoiceTotal - (PaymentTotal + CreditTotal) <= @BalanceMax
    END
ELSE IF
    (
        @VendorVar != NULL
        AND @BalanceMin = NULL
        AND
            (
                @BalanceMax = NULL
                OR @BalanceMax = 0
            )
    )
    BEGIN
        SELECT VendorName, InvoiceNumber, InvoiceTotal - (PaymentTotal + CreditTotal) AS BalanceDue
        FROM Invoices JOIN Vendors
            ON Invoices.VendorID = Vendors.VendorID
        WHERE
            VendorName = @VendorVar
            AND InvoiceTotal - (PaymentTotal + CreditTotal) > 0
    END
ELSE
    BEGIN
        SELECT VendorName, InvoiceNumber, InvoiceTotal - (PaymentTotal + CreditTotal) AS BalanceDue
        FROM Invoices JOIN Vendors
            ON Invoices.VendorID = Vendors.VendorID
        WHERE
            InvoiceTotal - (PaymentTotal + CreditTotal) > 0
    END
;

理想情况下你应该使用动态sql来避免参数嗅探像这样的查询中的问题,动态sql的解决方案看起来像这样......

CREATE PROC spBalanceRange
    @VendorVar varchar(50) = NULL,
    @BalanceMax money = NULL,
    @BalanceMin money = NULL

AS
BEGIN
  SET NOCOUNT ON;
  DECLARE @Sql NVARCHAR(MAX);



SET @Sql  = N'SELECT VendorName, InvoiceNumber, InvoiceTotal - (PaymentTotal + CreditTotal) AS BalanceDue
        FROM Invoices 
        INNER JOIN Vendors ON Invoices.VendorID = Vendors.VendorID
        WHERE '
        + CASE 
        WHEN         (@VendorVar IS NOT NULL 
                      AND @BalanceMin IS NOT NULL             
                      AND @BalanceMax IS NOT NULL)
         THEN N' VendorName = @VendorVar
            AND InvoiceTotal - (PaymentTotal + CreditTotal) >= @BalanceMin
            AND InvoiceTotal - (PaymentTotal + CreditTotal) <= @BalanceMax' 

        WHEN          ( @VendorVar IS NOT NULL
                        AND @BalanceMin IS NULL
                        AND (@BalanceMax IS NULL OR @BalanceMax = 0))
         THEN N' VendorName = @VendorVar
               AND InvoiceTotal - (PaymentTotal + CreditTotal) > 0'
        ELSE N' InvoiceTotal - (PaymentTotal + CreditTotal) > 0' END

Exec sp_executesql @Sql 
                  ,N'@VendorVar varchar(50),@BalanceMax money,@BalanceMin money'
                  ,@VendorVar 
                  ,@BalanceMax 
                  ,@BalanceMin 

END

我认为这是因为你用==将它们与null进行比较。 使用t-sql,您总是需要使用is运算符。

尝试

x is not null

x is null

代替。

我不在Windows机器附近所以这可能需要调整:

CREATE PROC spBalanceRange
    @VendorVar varchar(50) = NULL,
    @BalanceMax money = NULL,
    @BalanceMin money = NULL

AS
SELECT VendorName, InvoiceNumber, InvoiceTotal - (PaymentTotal + CreditTotal) AS BalanceDue
FROM Invoices JOIN Vendors
ON Invoices.VendorID = Vendors.VendorID
WHERE
case when @VendorVar is null then true else vendorName=@vendorVar end
AND InvoiceTotal - (PaymentTotal + CreditTotal) >= coalesce(@BalanceMin,0)
AND case when @BalanceMax is null then true else InvoiceTotal - (PaymentTotal + CreditTotal) <= coalesce(@BalanceMax, 1e15) end;

使用case语句的另一种方法可能会显示您想要的结果:

CREATE PROCEDURE spBalanceRange

@VendorVar varchar(50) = NULL,
@BalanceMax money = NULL,
@BalanceMin money = NULL

AS
BEGIN
SELECT 

b.VendorName, a.InvoiceNumber, 

case 
when InvoiceTotal - (PaymentTotal + CreditTotal) between @BalanceMax and     @BalanceMin
then InvoiceTotal - (PaymentTotal + CreditTotal) 
else 0
end BalanceDue
FROM Invoices a
JOIN Vendors b
ON a.VendorID = b.VendorID
WHERE
b.VendorName = @VendorVar 
and InvoiceTotal - (PaymentTotal + CreditTotal) between @BalanceMax and @BalanceMin
END

希望我理解你正在努力完成的事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM