SQL Server's T-SQL syntax seems to allow multiple plus signs in succession:
SELECT 1 + 2 --3
SELECT 1 ++ 2 --3
SELECT 1 ++++++ 2 --3
SELECT 1 + '2' --3
SELECT 1 ++ '2' --3
SELECT '1' + '2' --'12'
SELECT '1' ++ '2' --'12'
Multiple pluses seem to behave just like a single plus. Why does the "multiple plus operator" ++ exist? What does it do?
The first plus sign is interpreted as an addition operator. Each of the remaining plus signs is interpreted as a unary plus operator:
1 ++ 2 means 1 + (+2)
1 +++ 2 means 1 + (+(+2))
It's very common in programming languages to have this unary plus operator, though it's rarely used in SQL as it doesn't actually do anything.
Although a unary plus can appear before any numeric expression, it performs no operation on the value returned from the expression. Specifically, it will not return the positive value of a negative expression.
The unary plus operator is mentioned in the SQL-92 standard.
As well as the usual arithmetic operators, plus, minus, times, divide, unary plus, and unary minus, there are the following functions that return numbers: ...
While unary plus isn't all that useful, it has a more useful companion: unary minus. It is also known as the negative operator.
SELECT -(expression), ...
-- ^ unary minus
SELECT 1 ++ 2 means 1 plus (+2) which means 3
Same logic for the others 1+(+(+2)) and so on
SELECT '1' + '2' --'12' you are concatenating 2 strings, string '1' and string '2', which results '12'
Related
I have seen that greater than and less than operators can be applied on string values in SQL Server but I haven't figured out yet what logic is being applied here behind the scenes to perform the comparison.
For example, the string value 'Gabriel' is greater than 'Cassandra':
SELECT 1 WHERE 'Gabriel' > 'Cassandra'
The query above returns 1, whereas an empty result set is returned if the comparison operator is changed to '<'.
The comparison is alphabatical, so 'B' is greater than 'A', and 'C' is greater than 'B' and so on.
I just started reading C.
Situation :
x = ( y = 3, ( z = ++y + 2 ) + 5 )
It is evaluating y = 3 first then evaluating ( z = ++y + 2 )
My Problem :
It should first evaluate ( z = ++y + 2 ) because the precedence of comma(,) is much less than parenthesis
My way of Thinking :
Due to precedence we select outer parenthesis
Then we need to evaluate parenthesis
Under this (parenthesis) I again started applying precedence rule
So I took inner bracket to evaluate first
P.S. :
This is not a Duplicate
I have already gone through these links but still unable to understand
Behavior of comma operator in C
C comma operator
What does the comma operator , do?
https://learn.microsoft.com/en-us/cpp/cpp/comma-operator
Uses of C comma operator
https://en.wikipedia.org/wiki/Comma_operator
You're confusing operator precedence with order of evaluation.
Operator precedence dictates how subexpressions are grouped. It does not dictate when each operand is evaluated.
The comma operator has a sequence point between its left operand and its right operand. In the case of y = 3, ( z = ++y + 2 ) + 5, that means that y = 3 must be fully evaluated before ( z = ++y + 2 ) + 5 can be evaluated.
Note also in the subexpression ( z = ++y + 2 ) + 5 that there is no guarantee that everything inside the parenthesis are evaluated before everything inside. You only know that ( z = ++y + 2 ) and 5 are evaluated before ( z = ++y + 2 ) + 5 is evaluated. If for example you had (z = ++y + 2) + y this would invoke undefined behavior because the second y could be evaluated before or after the side effect of ++y.
As another example, if you had x = (func1() + 3) + func2(), either func1 could be called first or func2 could be called first since the order of evaluation of operands is unspecified. If both of those functions modified the same global variable, you wouldn't be able to reliably know the value of that variable.
Precedence and evaluation order are different things. In the expression (a*b) - (c+d), the compiler is free to evaluate (c+d) before (a*b), even though multiplication has higher precedence than addition. But in the expression a,b, as well as the code a;b, the compiler is required to sequence the computation of a before the computation of b.
You are confused between Precedence and Order of Evaluation. Precedence is the priority for grouping different types of operators with their operands.
The comma (,) operator constitute Sequence Point and therefore guarantee a particular order of evaluation for their operands which is left to right.
Order of evaluation
Ordering
......
If a sequence point is present between the subexpressions E1 and E2, then both value computation and side effects of E1 are sequenced-before every value computation and side effect of E2
Rules
.....
2) There is a sequence point after evaluation of the first (left) operand and before evaluation of the second (right) operand of the following binary operators: && (logical AND), || (logical OR), and , (comma).
In this expression:
x = ( y = 3, ( z = ++y + 2 ) + 5 )
First y = 3 will be evaluated first and then ( z = ++y + 2 ) + 5.
If I run
select '1' + '1'
the result is 11, since I have added a text to another one.
If I run
select 1 + '1'
the result is 2. I assume the arithmetic operator is chosen over the concatenator because of the type of the first operand. If my reasoning was valid, then the result of
select '1' + 1
would be 11. But instead, it is 2. So, it seems that the operator + is tried to be used as an arithmetic operator and if neither of the operands is arithmetic, then goes on to the next operator. If that is true, that would explain why did I get the error of
Conversion failed when converting the varchar value 'customer_' to data type
int.
instead of customer_<somenumber> when I ran a select and had 'customer_' + <somenumber>.
Long story short: I think I observed that arithmetic + is preferred over its meaning of concatenation at SQL Server. Am I right? If so, is there an official reason of this behavior?
What you're running into is a matter of data type precedence. SQL Server looks to character data types after numerics. So regardless of the ordering of your operands (1 + '1' vs '1' + 1), it's attempting to convert your types to numerics, and succeeding.
The same happens with your second attempt - it's trying to convert the string customer_ to an integer because you're using an arithmetic operator along with an integer.
Yes, the precedence is arithmetic first when compared to concatenation.
https://msdn.microsoft.com/en-us/library/ms190276.aspx
Your error, as you know, is because the it won't implicitly attempt to convert INT to VARCHAR
So i recently encountered a wierd bug when comparing two values.
My values was a range from -1 to 2.
Sometimes it thought that -1 was bigger than 0, the solution was easy. Apparently was the column set to varchar(50) instead of int.
But this made me think why this happened. Because even if the column was set to varchar(50) the '-' should have a lower char value than '0' (charvalue for '-' is 45 and charvalue for '0' should be 48)
I made some tests and it turns out, what i can find, that '-' is the only character that ORDER BY doesn't care about.
Example:
SELECT
A.x
FROM
(
VALUES
('-5'), ('-4'), ('-3'), ('-2'), ('-1'),
('0'), ('1'), ('2'), ('3'), ('4'), ('5')
) A(x)
ORDER BY
A.x;
SELECT
B.x
FROM
(
VALUES
('+5'), ('+4'), ('+3'), ('+2'), ('+1'),
('0'), ('1'), ('2'), ('3'), ('4'), ('5')
) B(x)
ORDER BY
B.x
Result:
Result of A
0
1
-1
2
-2
3
-3
4
-4
5
-5
Result of B
+1
+2
+3
+4
+5
0
1
2
3
4
5
(+ has a charvalue of 43)
The '+' order by feels right but the '-' seems... wrong
Anyone knows why it is like this?
Additional info
Server version: 12.0.4213
Collation: Finnish_Swedish_CI_AS
No clue what else could skew the result. Ask if you need more information.
Found out why.
TLDR: Non-unicode and unicode collation sorts '-' differently.
"A SQL collation's rules for sorting non-Unicode data are incompatible
with any sort routine that is provided by the Microsoft Windows
operating system; however, the sorting of Unicode data is compatible
with a particular version of the Windows sorting rules. Because the
comparison rules for non-Unicode and Unicode data are different, when
you use a SQL collation you might see different results for
comparisons of the same characters, depending on the underlying data
type. For example, if you are using the SQL collation
"SQL_Latin1_General_CP1_CI_AS", the non-Unicode string 'a-c' is less
than the string 'ab' because the hyphen ("-") is sorted as a separate
character that comes before "b". However, if you convert these strings
to Unicode and you perform the same comparison, the Unicode string
N'a-c' is considered to be greater than N'ab' because the Unicode
sorting rules use a "word sort" that ignores the hyphen."
Source: https://support.microsoft.com/en-us/kb/322112
When you run the following query in SQL Management studio the result will be 1.
SELECT
CASE WHEN '-' = 0 THEN
1
ELSE
0
END
That scares me a bit, because I have to check for 0 value a numerous number of times and it seems it is vulnerable for being equal to value '-'.
You're looking at it the wrong way around.
'-' is a string, so it will get implicitly casted to an integer value when comparing it with an integer:
select cast('-' as int) -- outputs 0
To make sure that you are actually comparing a value to the string '0', make your comparison like this instead:
select case when '-' = '0' then 1 else 0 end
In general, you're asking for trouble when you're comparing values of different data types, since implicit conversions happen behind the scene - so avoid it at all costs.