I am trying to find a string in a MySQL field which is encoded in base64 (for international characters)
Usual search:
$sql = "SELECT * FROM table WHERE field LIKE '%term%' ";
I have tried this:
$sql = "SELECT * FROM table WHERE field name LIKE '%".base64_encode($term)."%' ";
But it does not work all the time, depending on the search term length... For some reason, it gives result whenever my term is an odd-number long...
I have also tried using the MySQL function TO_BASE64() and FROM_BASE64() which did not work...
Can someone please help?
You need to compare the input value against the base64-decoded stored value, so reverse your attempt a little to call FROM_BASE64() on the stored value and compare against the plain input value. You cannot compare a partial match in $term if it is encoded because the partial value will never produce the same or even similar base64 string as the full stored value.
SELECT * FROM `table` WHERE FROM_BASE64(`field`) LIKE '%$term%'
In this context, $term is a plain string, not base64 encoded. It's of course recommended that $term be a bound parameter rather than a plain PHP variable concatenated into the query.
However, this is going to be slow. If you are in any position to change the way your data has been stored, you are highly encouraged to store it in a plain unencoded form. Every query will need to base64-decode every row to find a matching one, which is extremely inefficient.
Note also, that TO_BASE64(),FROM_BASE64() were recently added in MySQL 5.6.1, and therefore may not be available in a lot of installations. You really should change the way the data is stored to eliminate the encoding.
If you don't want to upgrade to MySQL 5.6 or above, you can use the following trick which is removing the padding issue:
SELECT * FROM `table` WHERE
field LIKE '%" . base64_encode($term) . "%'
OR field LIKE '%" . substr(base64_encode($term .'a'),0,-4) . "%'
OR field LIKE '%" . substr(base64_encode($term .'aa'),0,-8) . "%'
OR field LIKE '%" . substr(base64_encode($term .'aaa'),0,-12) . "%'
The search term length issue is therefore avoided. You may optimize this query by using only one of the four LIKE depending on the length of the $term.
Related
What would be the right SQL statement so that when I search two words, like for example 'text field' in a text box, it will return all results that has 'text' and 'field' in it using the LIKE statement?
I cant find the right terms to make a search.
EDIT : If possible, I want to make it dynamic. Like if a user search 5 words, all 5 words would be in the Like statement. I am trying to achieve a statement
SELECT * FROM table WHERE search (LIKE %searchterm1%) OR (LIKE %searchterm2%) OR (LIKE %searchterm3%) ....
The the words are unordered use a standard logical conjunction (aka AND)
LIKE '%word1%' AND LIKE '%word2%'
If the words are ordered use an implicit conjunction in the search term itself
LIKE '%word1%word2%'
Modify the like wildcards (and quotes) as needed; also consider if a full-text search might be more appropriate.
The correct syntax is;
SELECT * FROM table WHERE (column1 LIKE '%text%' AND column1 LIKE '%field%')
To allow the user to input multiple words, firstly take a look at the problems of SQL injection, but assuming you're using PHP you can explode an input string and implode the resulting array, like this;
$values = explode(" ", $input); // delimiter is a space
$query = "SELECT * FROM table WHERE (column1 LIKE '%" . implode("%' AND column1 LIKE '%",$values) . "%')";
Hope this helps!
I want to do a "select all" from a table, using an URL. However the URLs stored in my database have funny characters; an URL in my database looks something like this:
http%3A%2F%2Fwww.indeed.co.uk%2Fviewjob%3Fjk%3D62643ba09fe2e936%26qd%3DUl8d87NuQZQD4fDpyxUj6Q3nWG6Z80ksB5Olwd1QWW3wG-YZeyT0yxf8fUYia7g-jLgw8Q9quijZp6li7FQTOh_bZiy_HhLQe1iSKacCzeM%26indpubnum%3D2878078796677777%26atk%3D185867g360mq25sg
How would I select this by using a normal URL string such as "http://www.indeed.co.uk/blablabla", without all the funny %3A%2F characters.
Or is there a way to insert the urls into the database without these characters getting added in. If so how?
If you use PHP, you can use the function urlencode :
$query = "SELECT * FROM table WHERE url = '" . urlencode($urlToSearch) . "'";
Documentation PHP.net
Those are URI encoded characters. It's not clear how those ended up in your database, though it's possible they weren't properly decoded before being saved.
It's sort of possible to decode these in MySQL alone but it's usually better to use a scripting language of some sort to do the conversion for you.
First I want to say, I'm sorry if this question have be asked already (haven't been able to find it then).
My problem is that I've got a LIKE clause in mysql where I have to find some numbers in a comma seperated row.
(Yes I know comma separated rows aint a good thing to use, but I'm not the one who made the database structure).
So I have the following:
SELECT pfd.*, pu.username, pu.user_email
FROM phpbb_profile_fields_data pfd
LEFT JOIN phpbb_users pu ON pfd.user_id=pu.user_id
WHERE pfd.pf_pf_produktionsteknik LIKE '%" . ($id) . "%'
AND pu.user_type!=1 AND pfd.pf_status=2";
But the problem is here that it returns where the LIKE equal 1 (as it should) but also 11 (which it should not).
I have tried using field_in_set wich I couldn't get to work, and I'm now lost at what to do about it.
If your list is comma separated, can you look for number then comma, OR comma then number, or equalling number on its own. That should cover all cases including single number instances.
The value searched for could be embraced by commas or followed by a comma when positioned at the list start or following a comma when positioned at the list end or it is the only value (no commas in the list)
WHERE (pfd.pf_pf_produktionsteknik LIKE '%," . ($id) . ",%'
OR pfd.pf_pf_produktionsteknik LIKE '"($id) . ",%'
OR pfd.pf_pf_produktionsteknik LIKE '%," .($id) . "'
OR pfd.pf_pf_produktionsteknik = '" .($id) . "' ) AND ...
You're dealing with data that's badly structured, so you need to have that addressed -- comma-delimited sets of numbers are not in 1nf, which is pretty basic.
Now that I've got that out of the way, you can try using a regexp instead of LIKE:
As SQL (note the value 1):
WHERE pfd.pf_pf_produktionsteknik REGEXP '\b1\b'
or as a PHP string:
..." WHERE pfd.pf_pf_produktionsteknik REGEXP '\b" . $id . "\b'"
...which will match 1 but not 11: \b is the regex for "word boundary", which means it requires the start of a string or punctuation or whitespace on either side of your value $id.
The find_in_set (manual) mysql function is what you're looking for : it searches a value inside a comma separated value.
select find_in_set('1', 'a,b,1,c');
Gives this :
+-----------------------------+
| find_in_set('1', 'a,b,1,c') |
+-----------------------------+
| 3 |
+-----------------------------+
1 row in set (1.10 sec)
If the function fails, it returns 0.
In your case, doing WHERE find_in_set('1', pfd.pf_pf_produktionsteknik) > 0 will give you what you need.
I need some help with a RegEx. The concept is simple, but the actual solution is well beyond anything I know how to figure out. If anyone could explain how I could achieve my desired effect (and provide an explanation with any example code) it'd be much appreciated!
Basically, imagine a database table that stores the following string:
'My name is $1. I wonder who $2 is.'
First, bear in mind that the dollar sign-number format IS set in stone. That's not just for this example--that's how these wildcards will actually be stored. I would like an input like the following to be able to return the above string.
'My name is John. I wonder who Sarah is.'
How would I create a query that searches with wildcards in this format, and then returns the applicable rows? I imagine a regular expression would be the best way. Bear in mind that, theoretically, any number of wildcards should be acceptable.
Right now, this is the part of my existing query that drags the content out of the database. The concatenation, et cetera, is there because in a single database cell, there are multiple strings concatenated by a vertical bar.
AND CONCAT('|', content, '|')
LIKE CONCAT('%|', '" . mysql_real_escape_string($in) . "', '|%')
I need to modify ^this line to work with the variables that are a part of the query, while keeping the current effect (vertical bars, etc) in place. If the RegEx also takes into account the bars, then the CONCAT() functions can be removed.
Here is an example string with concatenation as it might appear in the database:
Hello, my name is $1.|Hello, I'm $1.|$1 is my name!
The query should be able to match with any of those chunks in the string, and then return that row if there is a match. The variables $1 should be treated as wildcards. Vertical bars will always delimit chunks.
For MySQL, this article is a nice guide which should help you. The Regexp would be "(\$)(\d+)". Here's a query I ripped off the article:
SELECT * FROM posts WHERE content REGEXP '(\\$)(\\d+)';
After retrieving data, use this handy function:
function ParseData($query,$data) {
$matches=array();
while(preg_match("/(\\$)(\\d+)/",$query,$matches)) {
if (array_key_exists(substr($matches[0],1),$data))
$query=str_replace($matches[0],"'".mysql_real_escape_string($data[substr($matches[0],1)])."'",$query);
else
$query=str_replace($matches[0],"''",$query);
}
return $query;
}
Usage:
$query="$1 went to $2's house";
$data=array(
'1' => 'Bob',
'2' => 'Joe'
);
echo ParseData($query,$data); //Returns "Bob went to Joe's house
If you aren't sticky about using the $1 and $2 and could change them around a bit, you could take a look at this:
http://php.net/manual/en/function.sprintf.php
E.G.
<?php
$num = 5;
$location = 'tree';
$format = 'There are %d monkeys in the %s';
printf($format, $num, $location);
?>
If you want to find entries in the database, then you can use a LIKE statement:
SELECT statement FROM myTable WHERE statement LIKE '%$1%'
Which will find all statements that include $1. I'm assuming that the first number to replace will always be $1 - it doesn't matter, in that case, that the total number of wildcards is arbitrary, as we're just looking for the first one.
The PHP replacement is a little trickier. You could probably do something like:
$count = 1;
while (strpos($statement, "$" . $count)) {
$statement = str_replace("$" . $count, $array[$count], $statement);
}
(I've not tested that, so there might be typos in there, but it should be enough to give the general idea.)
The one downside is that it will fail if you have more than ten parameters in your string to replace - the first runthrough will replace the first two characters of $10, as it's looking for $1.
I asked a different, but similar, question, and I think the solution applies to this question just as well.
https://stackoverflow.com/a/10763476/1382779
I have the following code:
mysql_query("SELECT * FROM list WHERE name LIKE '%'$searchTerm'%' OR description LIKE '%'$searchTerm'%';");
The only problem is, in pure SQL, such a query would look like:
SELECT * FROM list WHERE name LIKE '%asdf%' OR description LIKE '%asdf%'
What I'm confused about is how to put my variables into the string properly, normally a variable in a mysql_query would be surrounded by single quotes, but the addition of the single quotes in the SQL itself is confusing me.
I tried concatenating with . but I don't think that's a good solution.
mysql_query("SELECT * FROM list WHERE name LIKE '%$searchTerm%' OR description LIKE '%$searchTerm%';");
Why won't you just...
echo "SELECT * FROM list WHERE name LIKE '%$searchTerm%' OR description LIKE '%$searchTerm%';"
...and see how the query actually will look like..
I don't know PHP, but I suggest to use a replace function to manage the character "'" into $searchterm. This also allow to avoid sql injections..
This is the clearest way to me, using "." to concatenate:
mysql_query("SELECT * FROM list WHERE name LIKE '%".$searchTerm."%' OR description LIKE '%".$searchTerm."%'");
Try and use that, it should work on what you're trying :)