Why "=" and "like" work in the same statement - sql

I was practicing SQL injection skill, and I found that I could put = and LIKE in a single statement.
However, I'm not sure what does this mean and why it works?
SELECT 1 FROM users WHERE name='' LIKE '%'
So, what does that mean when I put = and LIKE in a statement, and when would I write something like this?

I am guessing that you are using MySQL, because this is syntactically correct in MySQL. It treats boolean types as numbers (which will be converted to integers and strings).
So, your code should be parsed as:
WHERE (name = '') LIKE '%'
This is because = and LIKE have the same precedence, and when operators have the same precedence, they are evaluated left-to-right (as explained in the documentation).
This, in turn evaluates to one of these three possibilities:
WHERE 1 LIKE '%' -- when name = ''
WHERE 0 LIKE '%' -- otherwise when name is not null
WHERE NULL like '%'
The first two will always evaluate to true. The third would discard any row where name is null.

(in MySQL and other popular DBMS) The LIKE operator is used to search for a specified pattern in a column. It admits "%" as a wildcard that represents zero, one, or multiple characters.
Your query always passes because the string '' meets this wildcard (zero characters). Incidentally, almost anything will. Some DBMS will react differently to such a query though.

Related

Want to use Wild Card for declared variable in Case statement

"AND" is in where clause of the query
Trying to use the Like operator in the "else" part
AND TCD.ANI = Case when #CallerID is null then TCD.ANI Else #CallerID end
Is this what you want?
AND (#CallerID is null OR TCD.ANI LIKE #CallerID)
I don't see many cases where CASE comes handy in conditions. Usually, things are simpler expressed with boolean logic.
Maybe you want to concatenate wildcards to the variable as well. In standard SQL, using string concatenation operator ||:
AND (#CallerID is null OR TCD.ANI LIKE '%' || #CallerID || '%')

Underscore and LEFT function

I have a column that has values that look like the following:
17_data...
18_data...
1801151...data
The data isn't the cleanest in this columns, so I am trying to use a LEFT function to identify the rows that have the 2017 year followed by an underscore LEFT(column, 3) = '17[_]' This doesn't return a single column. So to troubleshoot, I added this WHERE clause to the SELECT statement to see what was getting returned, and I got the value 175 where the actual first three characters are "17_".
Why is this, and how can I structure my WHERE clause to pick up those rows?
When you tried adding 'where' with a rule of LEFT(column, 3) = '17[_]', it was doomed to fail. Operator '=' performs exact comparison: both sides must be equal. That is, it would look for rows whose first 3 characters (left,3) are equal to 17[_], that is, 5 characters, one, seven, bracket, underscore, bracket. Text of 3 characters will not exactly-match 5 characters, ever.
You should have written simply:
WHERE LEFT(column, 3) = '17_'
I guess that you've got the idea for adding a bracket from reading about LIKE patterns. LIKE operator allows you to look for strings contained at start/end/middle of the data.
WHERE column LIKE 'mom%' - starts with mom
WHERE column LIKE '%dad' - ends with dad
and so on. LIKE supports '%' meaning "and then text of any length", and also "_" meaning "and then just one character". This forms a problem: when you want to say "starts with _mom", you cannot write
WHERE column LIKE '_mom%'
because it would also match 9mom, Bmom, and so on, due to _ meaning 'any single character'. That's why in such cases, only in LIKE, you have to write the underscore in brackets:
WHERE column LIKE '[_]mom%' - starts with _mom
Knowing that, it's obvious that you could construct your 'starts with 17_' with LIKE as well:
SELECT column1, column2, ..., columnN
FROM sometable
WHERE column LIKE '17[_]%'

Match Character Whether or Not It Exists in Like Statement

I need a like expression that will match a character whether or not it exists. It needs to match the following values:
..."value": "123456"...
..."value": "123456"...
"...value":"123456"...
This like statement will almost work: LIKE '%value":%"123456"%'
But there are values like this one that would also match, but I don't want returned:
..."value":"99999", "other":"123456"...
A regex expression to do what I'm looking to do is 'value": *?"123456"'. I need to do this in SQL Server 2008 and I don't believe there is good regex support in that version. How can I match using a like statement?
Remove the whitespace in your compare with REPLACE():
WHERE REPLACE(column,' ','') LIKE '%"value":"123456"%'
May need a double replace for tabs:
REPLACE(REPLACE(column,' ',''),' ','')
I don't think you can with the like operator. You could exclude ones you could match, like if you want to make sure it just doesn't contain other:
[field] LIKE '%value":%"123456"%` AND [field] NOT LIKE '%"other"%'
Otherwise I think you'd have to do some processing on the string. You could write a UDF to take the string and parse it to find the value for 'value' and compare based on that:
dbo.fn_GetValue([field], 'value') = '123456'
The function could find the index of '"' + #name + '"', find the next index of a quote, and the one after that, then get the string between those two quotes and return it.

MS SQL What does = '%' and '%%%' mean when in a where clause

In a vendor's database that the company I work for, they have some expressions that I don't think I have ever seen:
FROM CO_ITEM_MASTER WHERE smartpart_num = '%'
I have seen = '%Text%'
and I know what that means, but if there is no text along with the '%' what does that mean?
I also have the following:
AND (lower(CO_ITEM_MASTER.ITEM_NUM) like lower('%%%')
What does the '%%%' mean when there is no text between the '' characters?
% means
Match Any string of zero or more characters.
Because a zero length string matches this can be repeated as many times as desired without affecting the semantics and will return any row where ITEM_NUM is not NULL.
It is of course pointless to use more than one, perhaps this is code generated by code rather than a human.

Use '=' or LIKE to compare strings in SQL?

There's the (almost religious) discussion, if you should use LIKE or '=' to compare strings in SQL statements.
Are there reasons to use LIKE?
Are there reasons to use '='?
Performance? Readability?
LIKE and the equality operator have different purposes, they don't do the same thing:
= is much faster, whereas LIKE can interpret wildcards. Use = wherever you can and LIKE wherever you must.
SELECT * FROM user WHERE login LIKE 'Test%';
Sample matches:
TestUser1
TestUser2
TestU
Test
To see the performance difference, try this:
SELECT count(*)
FROM master..sysobjects as A
JOIN tempdb..sysobjects as B
on A.name = B.name
SELECT count(*)
FROM master..sysobjects as A
JOIN tempdb..sysobjects as B
on A.name LIKE B.name
Comparing strings with '=' is much faster.
In my small experience:
"=" for Exact Matches.
"LIKE" for Partial Matches.
There's a couple of other tricks that Postgres offers for string matching (if that happens to be your DB):
ILIKE, which is a case insensitive LIKE match:
select * from people where name ilike 'JOHN'
Matches:
John
john
JOHN
And if you want to get really mad you can use regular expressions:
select * from people where name ~ 'John.*'
Matches:
John
Johnathon
Johnny
Just as a heads up, the '=' operator will pad strings with spaces in Transact-SQL. So 'abc' = 'abc ' will return true; 'abc' LIKE 'abc ' will return false. In most cases '=' will be correct, but in a recent case of mine it was not.
So while '=' is faster, LIKE might more explicitly state your intentions.
http://support.microsoft.com/kb/316626
For pattern matching use LIKE. For exact match =.
LIKE is used for pattern matching and = is used for equality test (as defined by the COLLATION in use).
= can use indexes while LIKE queries usually require testing every single record in the result set to filter it out (unless you are using full text search) so = has better performance.
LIKE does matching like wildcards char [*, ?] at the shell
LIKE '%suffix' - give me everything that ends with suffix. You couldn't do that with =
Depends on the case actually.
There is another reason for using "like" even if the performance is slower: Character values are implicitly converted to integer when compared, so:
declare #transid varchar(15)
if #transid != 0
will give you a "The conversion of the varchar value '123456789012345' overflowed an int column" error.