Instructions IF-ELSE nestedes SQL

D'accord, je suis officiellement perdu. J'essaye de créer une procédure qui parcourt chaque vérification suivante et exécute la requête correspondante.

Cependant, lorsque j'exécute la procédure avec des arguments un / deux / tous, il est toujours pris dans l'ELSE final et crache le jeu de résultats "cover-all". POURQUOI???

Je suppose qu'il peut être: -If / Else syntaxe -Utilisation de parenthèses -Begin / End mots-keys -Trop de nombreuses conditions IF?

Toute aide est extrêmement appréciée!

Points bonus: puis-je optimiser ceci avec un CAS recherché dans la clause WHERE? Je sais que je peux vraiment réduire ce code – mais je suis vraiment curieux de savoir pourquoi cela ne fonctionne pas.

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 ; 

Idéalement, vous devriez utiliser SQL dynamic pour éviter le reniflage des parameters comme des problèmes dans une requête comme celle-ci, une solution avec sql dynamic ressemblerait à quelque chose comme ça …..

 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 

Je pense que c'est parce que vous les comparez à null avec == . Avec t-sql, vous devez toujours utiliser l'opérateur is .

Essayer

 x is not null 

et

 x is null 

au lieu.

Je ne suis pas à proximité d'une machine Windows, donc cela pourrait avoir besoin de peaufiner:

 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; 

Une autre approche utilisant une déclaration de cas qui peut vous montrer les résultats que vous voulez:

 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 

J'espère avoir compris ce que vous essayez d'accomplir correctement.