Procédure stockée T-SQL pour renvoyer tous les loggings lorsque le paramètre d'input est 'ALL'

J'ai une procédure stockée qui a le paramètre:

@desk VARCHAR(50) 

je veux

 SELECT * FROM dbo.Desk WHERE DeskName = @desk 

et je veux aussi returnner tous les loggings quand la valeur de @desk = 'All' .

Quelle est la meilleure façon de faire cela?

Il suffit d'inclure cette condition dans votre clause WHERE comme ceci:

 SELECT * FROM dbo.Desk WHERE DeskName = @desk OR @desk = 'All' 

Comme Martin Smith le remarque ci-dessous, les performances ne seront pas optimales – si la table est petite, vous préférerez peut-être cette approche concise plutôt qu'une option plus performante simplement pour des raisons de clarté / maintenabilité de votre code T-SQL, mais Jetez aussi un coup d'oeil à l'article qu'il lie à …

Comme @MartinSmith l'a fait remarquer, le field = @var or @var = 'ALL' type de réponse a un énorme inconvénient …

Lorsque la procédure stockée est compilée, elle génère un plan d'exécution unique. Et ce plan d'exécution doit être suffisant pour gérer tous les scénarios que les parameters peuvent lui lancer.

Dans ce cas particulier, vous avez probablement (MartinSmith dit définitivement) scruter toute la table à chaque fois. C'est parce qu'un tel plan d'exécution est capable de remplir les deux exigences possibles.

Donc, effectivement, vous vous retrouvez avec un plan d'exécution de least-worst case .

Pour get un plan différent pour chaque cas ( @desk = 'ALL' et @desk != 'All' ), vous devez avoir deux requêtes. Cela signifie que, malheureusement, le code plus simple et less élégant est un code beaucoup plus performant …

 IF (@desk = 'ALL') SELECT * FROM dbo.Desk ELSE SELECT * FROM dbo.Desk WHERE deskName = @desk 

Le lien posté par @MartinSmith, dans son commentaire à la Question, aborde cela de manière beaucoup plus détaillée. En fonction de votre niveau d'expérience SQL, il est fortement recommandé de lire; cela explique beaucoup le comportement de SQL Server. Mais c'est très en profondeur.

Une approche plus simplist est simplement; essayez-le et voyez.

Créez une table avec un set de données réalist pour vos besoins, avec des contraintes et des index appropriés. Ensuite, créez un process stocké pour chaque réponse possible et testez-les. Idéalement, en utilisant le profileur pour voir le time CPU, time réel, lectures, écritures, etc.

Vous pouvez voir que la différence est si petite que vous pouvez vivre avec la "pire" réponse et en tirer profit étant court (et en faisant ainsi le "meilleur" pour vous).

Vous pouvez voir que l'un est plus court en time réel, mais considérablement plus élevé en time CPU. Si vous avez une simultanéité élevée, vous pouvez donc décider d'utiliser le time CPU le plus faible. Ou, si vous avez une simultanéité faible, un time de processeur plus élevé mais un time réel inférieur peuvent être préférables.

La programmation est merveilleuse, tant de reflections, d'échanges et de bilans. Même avec un morceau de SQL aussi simpel que celui-ci 🙂

La meilleure et la plus simple approche:

 SELECT * FROM dbo.Desk WHERE deskName = CASE WHEN @desk='All' THEN deskName ELSE @desk END 
 Declare @Desk varchar(50) if @Desk = 'All' set @Desk = null select * from dbo.desk where deskname = coalesce(@desk, deskname)