Parameterized string and wildcards in MySQL - mysql

I'm trying to build a MySQL query for a database search operation, where a user can specify a text string to match against a particular column. I figured that using the LIKE operator and surrounding the user input with % signs, to act as wildcards, would be best practice. I want the wildcards to be there on both the start and end so the user does not have to enter the whole string. Furthermore, I'd like to parameterize the query to avoid injection and whatnot. This leaves me with a query that looks something like this:
SELECT * FROM `sometable`
WHERE `name` LIKE ?
ORDER BY `id` ASC
LIMIT 1,10
(Note that the name column is a VARCHAR(50) with collation utf8_general_ci.)
The parameter from the WHERE clause is added like so:
Using cmd As New OdbcCommand()
cmd.Parameters.AddWithValue("name", "%" & strUserInput & "%")
...
However, what I now ended up with appears to be MySQL actually matching the name column against the concatenated string, treating the %'s as literals and not as wildcards as I had intended.
I also tried LIKE CONCAT('%', ?, '%'), but this doesn't work either.
How would I glue a wildcard character to the start and end of a parameterized string? Or is there a much better way of doing this?

Your SqlParameter name is #name not name : cmd.Parameters.AddWithValue("#name", string.Format("%{0}%", strUserInput);
And your sql should be:
SELECT * FROM `sometable`
WHERE `name` LIKE #name
ORDER BY `id` ASC
LIMIT 1,10

Apparently I oversaw something really stupid. The LIMIT clause was the problem - the database I was testing with was supposed to return only one or two rows per query, but because I specified 1,10 it skips the first result. I did not know LIMIT is zero-based. Oops.
Learning oppurtunity, I guess.

Related

finding the a sub string at the end of a string in a sql query

I am trying to search for domains ending in a keyword, e.g. 'travel', and would want to yield results like 'summertravel.com', 'besttravel.net'. However, if I search for the end of the domain
SELECT * FROM `domains` WHERE `domain_name` LIKE '%com' ORDER BY domain_name ASC
then all its going to look for is the TLD, which will always be .com, .net, etc, not the actual domain name. I have limited knowledge when it comes to sql queries, however I think there may be some sort of regex, that can find the string up to the first '.', and search for the of that string.
Is that possible? Is there an easier way?
Use this query:
SELECT * FROM DOMAINS WHERE DOMAIN_NAME LIKE '%travel.%'
Use REGEXP like below:
SELECT * FROM `domains` WHERE `domain_name` REGEXP 'travel' ORDER BY domain_name ASC
Query to find all the names, which contain 'travel'
I hope it will help

SQL SELECT LIKE (Insensitive casing)

I am trying to execute the sql query:
select * from table where column like '%value%';
But the data is saved as 'Value' ( V is capital ).
When I execute this query i don't get any rows.
How do i make the call such that, it looks for 'value' irrespective of the casing of the characters ?
use LOWER Function in both (column and search word(s)). Doing it so, you assure that the even if in the query is something like %VaLuE%, it wont matter
select qt.*
from query_table qt
where LOWER(column_name) LIKE LOWER('%vAlUe%');
If you want this column be case insensitive :
ALTER TABLE `schema`.`table`
CHANGE COLUMN `column` `column` TEXT CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
Thus, you don't have to change your query.
And the MySQL engine will process your query quicker than using lower() function or any other tricks.
And I'm not sure that using lower function will be a good solution for index searching performance.
Either use a case-insensitive collation on your table, or force the values to be lower case, e.g.
WHERE lower(column) LIKE lower('%value%');
Try using a case insensitive collation
select * from table
where column like '%value%' collate utf8_general_ci
Use the lower() function:
select t.*
from table t
where lower(column) like '%value%';
you should use either lower or upper function to ignore the case while you are searching for some field using like.
select * from student where upper(sname) like 'S%';
OR
select * from student where lower(sname) like 'S%';
If you are using PostgreSQL, a simpler solution is to use insensitive like (ILIKE):
SELECT * FROM table WHERE column ILIKE '%value%'
I know this is a very old question, but I'm posting this for posterity:
Non-binary string comparisons (including LIKE) are case-insensitive by default in MySql:
https://dev.mysql.com/doc/refman/en/case-sensitivity.html
This will eventually do the same thing. The ILIKE works, irrespective of the casing nature
SELECT *
FROM table
WHERE column_name ILIKE "%value%"

mysql substr not working like php

Please help me resolve my query when using query - I just want to subtract a few characters and then use the % to find the matching LIKE:
select * from `providers` WHERE `name` LIKE SUBSTR('telin',1,4)%
Please let me know what i'm doing wrong, any kind of help is greatly appreciated!
Assuming telin is a column name rather than the literal string, it should be quoted in backticks. If it is the literal string, then there is obviously no need to extract a substring from it. I suspect however, that it was the result of a PHP variable you pasted here after echoing out the full query, then it is correctly single-quoted.
Anyway, you will need to concatenate the SUBSTR() result onto the '%' via CONCAT():
SELECT * FROM `providers` WHERE `name` LIKE CONCAT(SUBSTR(`telin`,1,4), '%');
But better would be to use LEFT() to compare the first 4 characters of each:
SELECT * FROM `providers` WHERE LEFT(`name`, 4) = LEFT(`telin`,4);

SQL Query where a field value does not contain empty spaces

I am currently using the follow query:
SELECT *
FROM `wp_usermeta`
WHERE meta_key='avatar'
AND meta_key NOT LIKE '% '
ORDER BY RAND()
LIMIT 4
In that way, I want to try to get only field values, where no empty spaces re in the file name. Where is the error in my query? It still selects filenames with empty spaces in the filename.
Try
NOT LIKE '% %'
Your current wildcard match only catches trailing spaces.
Also, you're using meta_key twice. Should the column used in your LIKE clause be meta_value (or whatever it is in Wordpress).
This question is probably worth reading if you're concerned about performance - Which is faster — INSTR or LIKE?

MySQL regex query case insensitive

In my table I have firstname and last name. Few names are upper case ( ABRAHAM ), few names are lower case (abraham), few names are character starting with ucword (Abraham).
So when i am doing the where condition using REGEXP '^[abc]', I am not getting proper records. How to change the names to lower case and use SELECT QUERY.
SELECT * FROM `test_tbl` WHERE cus_name REGEXP '^[abc]';
This is my query, works fine if the records are lower case, but my records are intermediate ,my all cus name are not lower case , all the names are like ucword.
So for this above query am not getting proper records display.
I think you should query your database making sure that the names are lowered, suppose that name is the name you whish to find out, and in your application you've lowered it like 'abraham', now your query should be like this:
SELECT * FROM `test_tbl` WHERE LOWER(cus_name) = name
Since i dont know what language you use, I've just placed name, but make sure that this is lowered and you should retrieve Abraham, ABRAHAM or any variation of the name!
Hepe it helps!
Have you tried:
SELECT * FROM `test_tbl` WHERE LOWER(cus_name) REGEXP '^[abc]';
I don't know since when, but nowadays MySql REGEXP is case insensitive.
https://dev.mysql.com/doc/refman/5.7/en/pattern-matching.html
You don't need regexp to search for names starting with a specific string or character.
SELECT * FROM `test_tbl` WHERE cus_name LIKE 'abc%' ;
% is wildcard char. The search is case insensitive unless you set the binary attribute for column cus_name or you use the binary operator
SELECT * FROM `test_tbl` WHERE BINARY cus_name LIKE 'abc%' ;
A few valid options already presented, but here's one more with just regex:
SELECT * FROM `test_tbl` WHERE cus_name REGEXP '^[abcABC]';