web-dev-qa-db-fra.com

SQL: clause IF dans la clause WHERE

Est-il possible d'utiliser une clause IF dans une clause dans MS SQL?

Exemple:

WHERE
    IF IsNumeric(@OrderNumber) = 1
        OrderNumber = @OrderNumber
    ELSE
        OrderNumber LIKE '%' + @OrderNumber + '%'
185
Bryan Roth

Utilisez une instruction CASE
UPDATE: La syntaxe précédente (indiquée par quelques personnes) ne fonctionne pas. Vous pouvez utiliser CASE comme suit:

WHERE OrderNumber LIKE
  CASE WHEN IsNumeric(@OrderNumber) = 1 THEN 
    @OrderNumber 
  ELSE
    '%' + @OrderNumber
  END

Ou vous pouvez utiliser une instruction IF telle que @ N. J. Reed indique.

196
bdukes

Vous devriez pouvoir le faire sans aucun IF ou CASE

 WHERE 
   (IsNumeric(@OrderNumber) AND
      (CAST OrderNumber AS VARCHAR) = (CAST @OrderNumber AS VARCHAR)
 OR
   (NOT IsNumeric(@OrderNumber) AND
       OrderNumber LIKE ('%' + @OrderNumber))

Selon le type de code SQL utilisé, vous devrez peut-être modifier les transformations du numéro de commande en INT ou VARCHAR, selon que les transformations implicites sont prises en charge.

C'est une technique très courante dans une clause WHERE. Si vous souhaitez appliquer une logique "IF" dans la clause WHERE, il vous suffit d'ajouter la condition supplémentaire avec un booléen ET à la section où elle doit être appliquée.

130
njr101

Vous n'avez pas du tout besoin d'une déclaration IF.

WHERE
    (IsNumeric(@OrderNumber) = 1 AND OrderNumber = @OrderNumber)
OR (IsNumeric(@OrderNumber) = 0 AND OrderNumber LIKE '%' + @OrderNumber + '%')
22
Rivanni

Il n'y a pas de bonne façon de faire cela en SQL. Quelques approches que j'ai vues:

1) Utilisez CASE combiné avec des opérateurs booléens:

WHERE
    OrderNumber = CASE 
        WHEN (IsNumeric(@OrderNumber) = 1)
        THEN CONVERT(INT, @OrderNumber)
        ELSE -9999 -- Some numeric value that just cannot exist in the column
    END
    OR 
    FirstName LIKE CASE
        WHEN (IsNumeric(@OrderNumber) = 0)
        THEN '%' + @OrderNumber
        ELSE ''
    END

2) Utilisez les IF en dehors du SELECT

IF (IsNumeric(@OrderNumber)) = 1
BEGIN
    SELECT * FROM Table
    WHERE @OrderNumber = OrderNumber
END ELSE BEGIN
    SELECT * FROM Table
    WHERE OrderNumber LIKE '%' + @OrderNumber
END

3) À l’aide d’une longue chaîne, composez votre instruction SQL de manière conditionnelle, puis utilisez EXEC.

La troisième approche est hideuse, mais c’est presque le seul à penser que cela fonctionne si vous avez un certain nombre de conditions variables comme celle-là.

13
Euro Micelli

Utilisez une instruction CASE au lieu de IF.

6
Joel Coehoorn

Vous voulez la déclaration CASE

WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber)=1 THEN @OrderNumber ELSE '%' + @OrderNumber END
4
Jeff Martin

Je pense que là où ... comme/... ... le cas ... alors ... peut fonctionner avec des booléens. J'utilise T-SQL.

Scénario: Disons que vous voulez obtenir les loisirs de Person-30 si la valeur bool est fausse, et les loisirs de Person-42 si la valeur bool est vraie. (Selon certains, les recherches de passe-temps représentent plus de 90% des cycles de calcul de l'entreprise, payez donc de près.).

CREATE PROCEDURE sp_Case
@bool   bit
AS
SELECT Person.Hobbies
FROM Person
WHERE Person.ID = 
    case @bool 
        when 0 
            then 30
        when 1
            then 42
    end;
3
William
 WHERE (IsNumeric (@OrderNumber) <> 1 OR OrderNumber = @OrderNumber) 
 AND (IsNumber (@OrderNumber) = 1 OR OrderNumber LIKE '%' 
 + @OrderNumber + '%') 
1
WhoIsNinja
    WHERE OrderNumber LIKE CASE WHEN IsNumeric(@OrderNumber) = 1 THEN @OrderNumber ELSE  '%' + @OrderNumber END

Dans le cas en ligne, Condition fonctionnera correctement.

0
Jubayer Hossain

L'exemple suivant exécute une requête dans le cadre de l'expression booléenne, puis exécute des blocs d'instruction légèrement différents en fonction du résultat de l'expression booléenne. Chaque bloc d'instructions commence par BEGIN et se termine par END.

USE AdventureWorks2012;
GO
DECLARE @AvgWeight decimal(8,2), @BikeCount int
IF 
(SELECT COUNT(*) FROM Production.Product WHERE Name LIKE 'Touring-3000%' ) > 5
BEGIN
   SET @BikeCount = 
        (SELECT COUNT(*) 
         FROM Production.Product 
         WHERE Name LIKE 'Touring-3000%');
   SET @AvgWeight = 
        (SELECT AVG(Weight) 
         FROM Production.Product 
         WHERE Name LIKE 'Touring-3000%');
   PRINT 'There are ' + CAST(@BikeCount AS varchar(3)) + ' Touring-3000 bikes.'
   PRINT 'The average weight of the top 5 Touring-3000 bikes is ' + CAST(@AvgWeight AS varchar(8)) + '.';
END
ELSE 
BEGIN
SET @AvgWeight = 
        (SELECT AVG(Weight)
         FROM Production.Product 
         WHERE Name LIKE 'Touring-3000%' );
   PRINT 'Average weight of the Touring-3000 bikes is ' + CAST(@AvgWeight AS varchar(8)) + '.' ;
END ;
GO

Utilisation d'instructions IF ... ELSE imbriquées L'exemple suivant montre comment une instruction IF… ELSE peut être imbriquée dans une autre. Définissez la variable @Number sur 5, 50 et 500 pour tester chaque instruction.

DECLARE @Number int
SET @Number = 50
IF @Number > 100
   PRINT 'The number is large.'
ELSE 
   BEGIN
      IF @Number < 10
      PRINT 'The number is small'
   ELSE
      PRINT 'The number is medium'
   END ;
GO
0
hossein

CASE L'instruction est meilleure option que SI toujours.

  WHERE  vfl.CreatedDate >= CASE WHEN @FromDate IS NULL THEN vfl.CreatedDate ELSE  @FromDate END
    AND vfl.CreatedDate<=CASE WHEN @ToDate IS NULL THEN vfl.CreatedDate ELSE @ToDate END 
0
Majedur Rahaman