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.