PDO/MYSQL parentheses () in query - mysql

Having some issues performing a PDO LIKE Query containing ().
<?php
...
$text_with_parentheses = '%'.$text_with_parentheses.'%'
$sth = $dbh->prepare('SELECT * FROM '.$table.' WHERE alarm LIKE :alarm');
$sth->bindParam(':alarm' , $text_with_parentheses);
$sth->execute();
$response = $sth->fetch();
...
?>
The string value I'm querying is an alarm text, stored in a varchar utf8_uncode_ci column. It Looks like this:
'ABCD. Status ABCD (6): (fail)'
It seems I cannot figure out how to escape the parentheses. Tested both via PHP/PDO and directly in MYSQL console. For testing i tested the follwoing in directly in the MYSQL console
SELECT * FROM `table` WHERE `column`='ABCD. Status ABCD (6): (fail)'
It returns 0 results.
The only way to get any results - both in PDO and MYSQL console - is doing:
SELECT * FROM `table` WHERE `column` LIKE 'ABCD. status ABCD%'
But that returns several values which is not viable. When searching for values that does not contain parentheses it works fine.
Anyone have any ideas? This seems like a MYSQL issue.

Parenthesis have absolutely no meaning neither in mysql strings nor in PDO.
Your problem is caused by something else.
Select the existing value from database and encode it to see all non-printable characters:
echo rawurlencode($value);
and then compare.
The genuine ABCD. Status ABCD (6): (fail) string will make
ABCD.%20Status%20ABCD%20%286%29%3A%20%28fail%29
while one from database something different. Compare and check the difference.

Related

Django raw SQL query trouble with format characters and string interpolation

In my Django app, I need to generate a MySQL query like this:
SELECT * FROM player WHERE (myapp_player.sport_id = 4 AND (myapp_player.last_name LIKE 'smi%'))
UNION
SELECT * FROM player WHERE (myapp_player.sport_id = 4 AND (myapp_player.first_name LIKE 'smi%'));
I can't use Q objects to OR together the __istartswith filters because the query generated by the Django ORM does not use UNION and it runs at least 40 times slower than the UNION query above. For my application, this performance is unacceptable.
So I'm trying stuff like this:
Player.objects.raw("SELECT * FROM myapp_player WHERE (sport_id = %%s AND (last_name LIKE '%%s%')) UNION SELECT * FROM sports_player WHERE (sport_id = %%s AND (first_name LIKE '%%s%'))", (sport.id, qword, sport.id, qword))
I apologize for the long one-liner, but I wanted to avoid using a triple-quoted string while trying to debug this type of issue.
When I execute or repr this queryset object, I get exceptions like this:
*** ValueError: unsupported format character ''' (0x27) at index 133
That's a single-quote in single quotes, not a triple-quote. If I get rid of the single-quotes around the LIKE clauses, then I get a similar exception about the close-paren ) character that follows the LIKE clause.
Apparently Django and MySQL disagree on the correct syntax for this query, but is there a syntax that will work for both?
Finally, I'm not sure that my %%s syntax for string interpolation is correct, either. The Django docs suggest that I should be able to use the regular %s syntax in the arguments for raw(), but several online resources suggest using %%s or ? as the placeholder for string interpolation in raw SQL.
My sincere thanks for just a little bit of clarity on this issue!
I got it to work like this:
qword = word + '%'
Player.objects.raw("SELECT * FROM myapp_player WHERE (sport_id = %s AND (last_name LIKE %s)) UNION SELECT * FROM myapp_player WHERE (sport_id = %s AND (first_name LIKE %s))", (sport.id, qword, sport.id, qword))
Besides the fact that %s seems to be the correct way to parameterize the raw query, the key here was to add the % wildcard to the LIKE clause before calling raw() and to exclude the single quotes from around the LIKE clause. Even though there are no quotes around the LIKE clause, quotes appear in the query ultimately sent to the MySQL sever.

placeholder use in perl DBI

I have perl script as following my $tb = 'rajeev';
$query = 'select * from table where name = ?'
$sth = $dbh->prepare($query);
$sth->execute($tb);
Does $tb replaced by rajeev or 'rajeev' when query executes ? means does query executs as select * from table where name = rajeevorselect * from table where name = 'rajeev'
DBI handles all the escaping for you. In the case of a string, it will be 'rajeev'. Calling select * from table where name = rajeev will give you an error.
If you provide a number, it will not add quotation marks because they are not needed.
See the DBI Doc. It also says:
The quote() method should not be used with "Placeholders and Bind Values".
Using placeholders sometimes takes care of the quoting for you, depending on which DBD you are using. In your case the DBD::mysql calls $dbh->quote() as mentioned in the doc:
An alternative approach is
$dbh->do("INSERT INTO foo VALUES (?, ?)", undef, $number, $name);
in which case the quote method is executed automatically.
If you have access to the query log you can check what the queries look like. If you have queries that take a long time you can also open a mysql console and say SHOW FULL PROCESSLIST; to see a list of the running queries. That will also hold the complete SQL statements for you to look at. On Windows you could use HeidiSQL to do it.

MySQL query with regexp not working in Drupal

I have the following query, courtesy of SO:
SELECT field_website_value FROM field_data_field_website WHERE field_website_value NOT REGEXP('^(https?://|www\\.)[\.A-Za-z0-9\-]+\\.[a-zA-Z]{2,4}(/\S*)?') AND field_website_value!=''
When executing this query directly in the MySQL client, it works (shows the values that don't match the pattern).
However when putting it in Drupal, it stops working, it just returns the rows which are not empty.
$query = "SELECT field_website_value FROM field_data_field_website WHERE field_website_value NOT REGEXP('^(https?://|www\\.)[\.A-Za-z0-9\-]+\\.[a-zA-Z]{2,4}(/\S*)?') AND field_website_value!=''";
$res = db_query($query)->fetchAll();
echo count($res);
echo "<pre>";print_r($res);die();
Is there any way I can use Regexp in Drupal?
Note: getting all rows and applying the regex in PHP isn't an option.
I'm no drupal expert but I bet db_query function is doing a mysql_real_escape_string() call which will mess up the regular expression, are there any other functions you can pass that won't do this?
Actually it is the {} brackets causing the issue, you need to pass the data as a variable,
$query = "SELECT field_website_value FROM field_data_field_website WHERE field_website_value NOT REGEXP('%s') AND field_website_value!=''";
$regexp = '^(https?://|www\\.)[\.A-Za-z0-9\-]+\\.[a-zA-Z]{2,4}(/\S*)?';
db_query($query, $regexp);

mysql perl placeholder rules

MySQL, Perl
The following select works fine with no placeholders, but doesn't with placeholders. It doesn't generate any SQL errors, but it returns all blanks/zeros - not the same counts as the same statement without placeholders.
my $sql="SELECT ?, SUM(IF(H1='1',1,0)) AS banner1 FROM table_name WHERE (?!='' and ? IS NOT NULL) GROUP BY ?";
my $sth = $dbh->prepare($sql);
my $variable = "Q1";
$sth->execute($variable, $variable, $variable, $variable);
What am I doing wrong?
Am I trying to use placeholders in ways not intended? It works when I only use placeholders in the WHERE clause. It does not work when I use a placeholder in the SELECT or GROUP BY clause. Is that the issue - placeholders can only be used in the WHERE clause?
You can't use placeholders in the SELECT portion of an SQL statement. This is described in the documentation:
With most drivers, placeholders can't be used for any element of a statement that would prevent the database server from validating the statement and creating a query execution plan for it. For example:
"SELECT name, age FROM ?" # wrong (will probably fail)
"SELECT name, ? FROM people" # wrong (but may not 'fail')
You can't use placeholders to substitute a column or table name. Even in your WHERE clause, it's not doing what you think it's doing. When you substitute Q1 for the placeholder, you get:
WHERE ('Q1'!='' and 'Q1' IS NOT NULL)
i.e. an expression that is always true.

Search returns no rows in mysql query using LIKE and values having "\"

I have some problem regarding the search in mysql.
Below is my query.
SELECT * FROM table WHERE name LIKE "%admin\'s%";
When i am executing this query it will return zero data.
actually i have "admin\'s" stored in db. this "\" is to prevent sql injection. i have used mysql_real_escape_string to prevent the sql injection.
but when i use three times addslashes to my variable it works.
So my below query is working.
SELECT * FROM table WHERE name LIKE "%admin\\\\\\\'s%";
My above query will return the data with name like admin's.
I am not getting where i am wrong.
well for one you shouldnt have data like this in your DB admin\'s .. most likely you double escaped your string ( check if you don't have magic_quotes enabled on your server ).
If you only do
INSERT ... username = "admin\'s";
you will have in your db the username value admin's
so my recomandation would be to go ahead and remove the slashes from your database and then your first query should work.