6
votes

CTE à l'intérieur de SQL Structure SQL

Je veux faire quelque chose comme ça

declare @a int=1
if (@a=1)
with cte as 
(
select UserEmail from UserTable 
)
else
with cte as
(
select UserID from UserTable
)
select * from cte


0 commentaires

3 Réponses :


6
votes

Vous ne pouvez pas faire cela - le CTE doit être immédiatement suivi d'une instruction SQL exactement qui peut y référer. Vous ne pouvez pas diviser la "définition" du CTE de la déclaration qui l'utilise.

Vous devez donc le faire de cette façon: xxx

Vous ne pouvez pas diviser le CTE " Définition "Pour son utilisation ( SELECT * à partir de CTE )


3 commentaires

@Martinsmith: J'avais peur de cela (mais je ne pouvais pas trouver une déclaration claire dans les docs) :-( Ainsi supprimé ma section. Merci d'avoir souligné!


Je sais que CTE doit être immédiatement suivi d'une déclaration SQL. Mais je cherche un moyen de voir. Je ne veux pas écrire des déclarations de sélection en double.


@Megamind: Il n'y a pas de chemin autour de cette - c'est la façon dont les CTE sont définies au fonctionnement.



13
votes

Si possible, trouvez un moyen d'éviter le si code> relève entièrement.

E.g. Dans un exemple aussi trivial que dans votre question: P>

;with CTE as (
      select UserEmail from UserTable where @a = 1
      union all
      select UserID from UserTable where @a != 1 or @a is null
)
select /* single select statement here */


3 commentaires

Une très belle solution de contournement de Damien, utilisant "Union tout" et ajoutant le filtre de condition "si" dans la clause WHERE. Pour la performance, je suggère d'utiliser le filtre comme première clause de «où»


@Damien_the_unbeliever, pourriez-vous élaborer pourquoi devrions-nous éviter si , s'il vous plaît?


@Nikitasilverstruk - Ce n'est pas une interdiction absolue, plus un guide général - si vous essayez de produire un ensemble de résultats, vous devriez essayer de formuler comment produire ce résultat défini dans une seule requête et laissez l'optimiseur à déterminer comment mieux produire, plutôt que de casser manuellement cette interrogation dans des morceaux. Comme vous pouvez le voir de la réponse de Marc_s, l'alternative utilisant si finit par deux requêtes avec une duplication entre elles.



4
votes

Le avec CTE (...) Sélectionnez de CTE ... est une seule déclaration . N'est pas "suivi" par une déclaration, celle-ci est partie de la déclaration. Vous demandez de scinder la déclaration sur deux qui est évidemment impossible.

En règle générale, SQL est une langue très hostile pour des choses comme sèches et en évitant la répétition de code. En essayant de rendre le code plus maintenu, plus lisible, ou simplement d'essayer de sauver quelques coups de frappe peut (et généralement) entraîner des pénalités sérieuses de performance d'exécution (par exemple, une tentative de déplacement de la CTE dans une fonction de valeur de table UDF). La chose la plus simple serait de mordre la balle (cette fois et dans l'avenir ...) et d'écrire le CTE deux fois. Parfois, il est logique de matérialiser le CTE dans une table #Temp, puis de fonctionner dans la table #TEpp, mais seulement parfois .

Ce statut-quo est malheureux , mais est tout ce que vous pouvez attendre de conception par commission ...


0 commentaires