- Si vous exécutez
SELECT -100/-100*10
le résultat est0
. - Si vous exécutez
SELECT (-100/-100)*10
le résultat est10
. - Si vous exécutez
SELECT -100/(-100*10)
le résultat est0
. - Si vous exécutez
SELECT 100/100*10
le résultat est10
.
BOL déclare:
Lorsque deux opérateurs dans une expression ont le même niveau de priorité d'opérateur, ils sont évalués de gauche à droite en fonction de leur position dans l'expression.
Et
Level Operators
1 ~ (Bitwise NOT)
2 * (Multiplication), / (Division), % (Modulus)
3 + (Positive), - (Negative), + (Addition), + (Concatenation), - (Subtraction), & (Bitwise AND), ^ (Bitwise Exclusive OR), | (Bitwise OR)
Est-ce que BOL a tort ou est-ce que je manque quelque chose? Il semble que cela -
jette la préséance (attendue).
sql
sql-server
tsql
operator-precedence
cuizizhe
la source
la source
-
semble provoquer un «mauvais» flux. Si vous essayez,-100/(-100)*10
vous obtenez le résultat10
. il semble que le/
soit appliqué à la valeur-
de l'équation, puis l'équation100*10
est en cours de détermination. Je ne suis pas sûr que ce soit une erreur avec BOL, mais plus que SQL Server ne se comporte pas comme prévu. Cela pourrait valoir la peine de soulever un problème sur sql-docs et de voir quelle est leur réponse; peut-être qu'une note pourrait être ajoutée à la documentation informant de la "fonctionnalité".SELECT -100/(-100)*10
renvoie également 10. On dirait qu'il-
est traité comme l'-
opérateur qui ne devrait être appliqué qu'après le100*10
calculA / -B * C
estA <div> <negate> B <multiply> C
. Negate a une priorité inférieure à multiplier, selon la documentation, le résultat est doncA / -(B * C)
. Vous pouvez le voir plus clairement en utilisant des constantes flottantes:12e / -13e * 14e
vs12e / (-13e) * 14e
vs.12e / 13e * 14e
La raison pour laquelle cela nous dérange est que nous nous attendons généralement à ce que le moins unaire fasse partie du littéral, ou du moins ait une priorité très élevée, mais ce n'est pas ainsi que T-SQL travaux.Réponses:
Selon la table de priorité, il s'agit du comportement attendu. L'opérateur avec une priorité plus élevée (
/
et*
) est évalué avant l'opérateur avec une priorité inférieure (unaire-
). Donc ça:est évalué comme:
Notez que ce comportement est différent de la plupart des langages de programmation où la négation unaire a une priorité plus élevée que la multiplication et la division, par exemple VB , JavaScript .
la source
-
est considéré comme un opérateur dans-100
. Dans certaines langues, cela fait partie de la syntaxe d'un entier.-
.BOL est correct.
-
a une priorité inférieure à*
, doncest analysé comme
La multiplication étant ce qu'elle est, vous ne le remarquez généralement pas, sauf lorsque vous mélangez les deux autres opérateurs binaires avec une priorité égale:
/
et%
(et%
est rarement utilisé dans des expressions composées comme celle-ci). AlorsEst analysé comme
expliquer les résultats. Ceci est contre-intuitif car dans la plupart des autres langages, le moins unaire a une priorité plus élevée que
*
et/
, mais pas dans T-SQL, et cela est documenté correctement.Une belle (?) Façon de l'illustrer:
produit un débordement arithmétique, car
-(1073741824 * 2)
produit2147483648
comme intermédiaire, qui ne rentre pas dans unINT
, maisproduit le résultat attendu
-2147483648
, ce qui fait.la source
-
est "négatif". Les gens qui disent des choses comme «moins 10» alors qu'ils veulent dire «moins 10» sont imprécis.-
opérateur, lorsqu'il est appliqué à un seul opérande, est appeléMINUS
dans les plans de requête SQL. Son équivalent binaire est appeléSUB
. Si vous le souhaitez, interprétez «moins unaire» comme un raccourci pour «l'opérateur unaire signifié par le signe moins» - une désignation syntaxique plutôt que sémantique.Remarquez dans la documentation que (peut-être contre-intuitivement) l'ordre de priorité pour
- (Negative)
est troisième.Ainsi, vous obtenez effectivement:
-(100/-(100*10)) = 0
Si vous les placez dans des variables, vous ne verrez pas cela se produire, car il n'y a pas d'opération unaire qui se produit après la multiplication.
Donc, ici A et B sont les mêmes, tandis que C, D, E montrent le résultat que vous voyez (avec E ayant le bracketing complet)
la source