sql-server - SQL 嵌套 IF-ELSE 语句

标签 sql-server if-statement case

好吧,我正式不知所措了。我正在尝试创建一个过程来运行每个后续检查并执行相应的查询。

但是,当我使用一个/两个/所有参数执行该过程时,它总是会陷入最后的 ELSE 中并吐出“覆盖所有”结果集。为什么???

我怀疑可能是: -If/Else 语法 - 括号的使用 - 开始/结束关键字 -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

关于sql-server - SQL 嵌套 IF-ELSE 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31999797/

相关文章:

python - if python 中的 Elif 语句

r - 寻找更高效的 ifelse()

Oracle plsql switch case 和 sqlplus spool

MySQL IF 语句求和

c# - C#回到程序的开头

MySQL 案例计数

sql - 如何管理数据库中的 "groups"?

sql - 使用 T-SQL 将数据从 CSV 格式的文本变量插入表中

sql - 检查表 1 的某一列的所有单词是否存在于表 2 的其他列中

sql-server - 用于计算过去 10 分钟内出现次数的窗口函数