- Jeśli wykonasz,
SELECT -100/-100*10
wynikiem jest0
. - Jeśli wykonasz,
SELECT (-100/-100)*10
wynikiem jest10
. - Jeśli wykonasz,
SELECT -100/(-100*10)
wynikiem jest0
. - Jeśli wykonasz,
SELECT 100/100*10
wynikiem jest10
.
BOL stwierdza:
Gdy dwa operatory w wyrażeniu mają ten sam poziom pierwszeństwa operatorów, są one oceniane od lewej do prawej na podstawie ich pozycji w wyrażeniu.
I
Level Operators
1 ~ (Bitwise NOT)
2 * (Multiplication), / (Division), % (Modulus)
3 + (Positive), - (Negative), + (Addition), + (Concatenation), - (Subtraction), & (Bitwise AND), ^ (Bitwise Exclusive OR), | (Bitwise OR)
Czy BOL jest źle, czy coś mi brakuje? Wygląda na -
to, że odrzuca (oczekiwany) priorytet.
sql
sql-server
tsql
operator-precedence
cuizizhe
źródło
źródło
-
to wydaje się być przyczyną „nieprawidłowego” przepływu. Jeśli spróbujesz-100/(-100)*10
, otrzymasz wynik10
. wydaje się, że/
jest on stosowany względem wartości-
w równaniu, a następnie równanie100*10
jest określane. Nie jestem pewien, czy jest to błąd w BOL, ale bardziej niż SQL Server nie zachowuje się zgodnie z oczekiwaniami. Warto poruszyć problem dotyczący sql-docs i sprawdzić, jaka jest ich odpowiedź; być może można by dodać notatkę do dokumentacji informującą o „funkcji”.SELECT -100/(-100)*10
również zwraca 10. Wygląda na to, że-
jest traktowany jako-
operator, który powinien być zastosowany dopiero po100*10
obliczeniuA / -B * C
jestA <div> <negate> B <multiply> C
. Negacja ma niższy priorytet niż mnożenie, zgodnie z dokumentami, więc wynik jestA / -(B * C)
. Możesz to zobaczyć wyraźniej, używając stałych zmiennoprzecinkowych: w12e / -13e * 14e
porównaniu12e / (-13e) * 14e
z12e / 13e * 14e
. Powodem, dla którego to nas wytrąca z równowagi, jest to, że generalnie oczekujemy, że jednoargumentowy minus stanie się częścią literału lub przynajmniej będzie miał bardzo wysoki priorytet, ale nie w ten sposób T-SQL Pracuje.Odpowiedzi:
Zgodnie z tabelą pierwszeństwa jest to oczekiwane zachowanie. Operator o wyższym priorytecie (
/
i*
) jest oceniany przed operatorem o niższym priorytecie (jednoargumentowy-
). Więc to:jest oceniany jako:
Zauważ, że to zachowanie różni się od większości języków programowania, w których jednoargumentowa negacja ma wyższy priorytet niż mnożenie i dzielenie, np. VB , JavaScript .
źródło
-
jest uważany za operatora w-100
. W niektórych językach jest częścią składni liczby całkowitej.-
.BOL ma rację.
-
ma niższy priorytet niż*
, takjest analizowany jako
Mnożenie jest tym, czym jest, zwykle tego nie zauważasz, z wyjątkiem mieszania dwóch innych operatorów binarnych z równym priorytetem:
/
i%
(i%
jest rzadko używane w takich wyrażeniach złożonych). WięcJest analizowany jako
wyjaśnianie wyników. Jest to sprzeczne z intuicją, ponieważ w większości innych języków jednoargumentowy minus ma wyższy priorytet niż
*
i/
, ale nie w T-SQL, i jest to poprawnie udokumentowane.Miły (?) Sposób, aby to zilustrować:
tworzy przepełnienie arytmetyczne, ponieważ
-(1073741824 * 2)
produkuje2147483648
jako półprodukt, który nie pasuje doINT
, aledaje oczekiwany wynik
-2147483648
, który tak.źródło
-
jest „negatywne”. Ludzie, którzy mówią na przykład „minus 10”, gdy mają na myśli „minus 10”, są nieprecyzyjni.-
Operator, po nałożeniu na jednym argumencie, nazywa sięMINUS
w planów kwerend SQL. Jego binarny odpowiednik nazywa sięSUB
. Jeśli chcesz, interpretuj „jednoargumentowy minus” jako skrót od „jednoargumentowego operatora oznaczanego znakiem minus” - oznaczenie składniowe, a nie semantyczne.Zauważ w dokumentacji, że (być może wbrew intuicji) kolejność pierwszeństwa dla
- (Negative)
jest trzecia.Więc skutecznie otrzymujesz:
-(100/-(100*10)) = 0
Jeśli umieścisz je w zmiennych, nie zobaczysz, że to się stanie, ponieważ po pomnożeniu nie ma operacji jednoargumentowej.
Więc tutaj A i B są takie same, podczas gdy C, D, E pokazują wynik, który widzisz (gdzie E ma pełne nawiasy)
źródło