I set off down this path of enlightenment as I investigated a customer issue that “could never happen”. I paused briefly to wipe the egg off my face then dug into how it could happen.
To keep my Car Garage analogy flowing, imagine you own a franchise that sells many flavours of car - BMW, Mercedes, and the like. The used car market is booming and you now automate the process of diverting incoming shipments to the right garage - for example you want all Mercedes to go to Garage A, All BMWs to Garage B, and so on (I’m really trying here..).
Now imagine you receive a shipment of fancy new Mercedes’, and you make a typo inputting those and instead input “Mercedes ” - to your shock these cars are not assigned to the right place 😱 🤯.
The Java developer in me looks at the 2 strings and thinks “But of course, they don’t match!“. To which the SQL developer in me now says - ah of course, ANSI/ISO SQL-92.
So why does it do this? 🙋♂️
The ANSI/ISO SQL-92, for those that don’t know, requires padding for the strings used in comparisons so that their lengths match before comparing them. This padding affects the semantics of
HAVING clause predicates among other TSQL string comparisons. For example, TSQL would consider both
'A ' to be the same for most comparison operations.
The only exception to this is the
LIKE predicate, because the purpose of this predicate (by definition) is to facilitate pattern searches rather than equality tests.
1MBP:~ mtjb$ sqlcmd -b -S "127.0.0.1" -U sa -P 'password'21>31>41> SELECT CASE WHEN 'A ' = 'A' THEN 1 ELSE 0 END52> GO67-----------8 1910(1 rows affected)111>121>131> SELECT CASE WHEN ' A' = 'A' THEN 1 ELSE 0 END142> GO1516-----------17 01819(1 rows affected)201>211>221> SELECT CASE WHEN 'A ' LIKE 'A' THEN 1 ELSE 0 END232> GO2425-----------26 02728(1 rows affected)291>