Use DB::select + binding too select a row - mysql

I'm trying to get a row from the database but when using binding. I know that this doesn't work because the query automatically puts single quotes so it will be like this: select model, magazine, round('name', 2) etc. This doesn't work of course but how do I get rid of the single quotes?
$merkinformation = DB::select('select Model, Magazine, round(?, 2) as Rondetijd from rondetijden where Merk = ? order by ? limit 3;', [$track, $merk, $track]);

You can't use column nmaes like this.
You must concatinate the name of the column. But this is vulnerable to sql injection. So you must check if $track has a valid content
$merkinformation = DB::select('select Model, Magazine, round(`' . $track . '` , 2) as Rondetijd from rondetijden where Merk = ? order by ? limit 3;', [$merk, $track]);

there is ['] single quote and [`] punctuation mark. If start with single quote or double quote mysql will translate that as string where punctuation mark will be recognize as field name.
Are you sure that is a single quote ?

Related

Strip special characters and space of a DB column to compare in rails

I have 4 types of last_name:
"Camp Bell"
"CAMPBELL"
"CampBellJr."
"camp bell jr."
Now, in rails when an user is searched by it's last name like camp bell, I want to show all the 4 records. So, I tried:
RAILS
stripped_name = params[last_name].gsub(/\W/, '')
#=> "campbell"
User.where("LOWER(REPLACE(last_name, '/\W/', '')) LIKE ?", "#{stripped_name}%")
Give me only 2 records with following last_name:
"CAMPBELL"
"CampBellJr."
I guess, this is because, the mysql REPLACE is not working correctly with regex.
Any ideas?
EDIT
Guys, sorry for the confusion. My idea is to strip off all special characters including space. So I'm trying to use \W regex.
For example, the input can be: camp~bell... But, it should still fetch result.
You can check for both stripped_name without space and ones that include both names seperated with space like this.
stripped_name = params[last_name].gsub(/\W/, '')
split_names = params[last_name].split(" ")
User.where('name LIKE ? OR (name LIKE ? AND name LIKE ?)', "%#{stripped_name}%", "%#{split_names[0]}%", "%#{split_names[1]}%")
Next step would to search for complete array of split names not just first two.
Here my solution:
User.where("REPLACE(last_name, ' ', '') ILIKE CONCAT ('%', REPLACE('?', ' ', ''),'%')", stripped_name)
ILIKE is like LIKE but the I is for insensitive case.
To understand easily step by step:
lastname ILIKE '%campbell% you need % because you want lastname
contain this string, not necessary at the begin or the end of you
string.
'campbell%' => search string who begin by campbell
'%campbell' => search string who finish by campbell
We need generate '%campbell%, so we use CONCAT for that
I just use a simply REPLACE, but maybe you should use a regex.

Insert into table SET - rows with special characters skipped

I have this query:
$sql = "
INSERT INTO table SET
name = '$name',
sku = '$number',
description = '$desc'
";
But the rows containing some special characters (in my case this ') are not inserted.. How I can solve?
Thanks in advance.
When you construct your query, you need to escape the data you are inserting.
You need to at least use addslashes() function in PHP, like this:
$sql = "INSERT INTO table SET name = '".addslashes($name)."', sku = '".addslashes($number)."', description = '".addslashes($desc)."'";
However more correct way is to use a different function than addslashes, which would properly handle all characters in the data, not only apostrophes.
I am using my custom 'escape' function like this:
function escape($text)
{
return str_replace(array('\\', "\0", "\n", "\r", "'", '"', "\x1a"), array('\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'), $text);
}
So using this function, you would write:
$sql = "INSERT INTO table SET name = '".escape($name)."', sku = '".escape($number)."', description = '".escape($desc)."'";
You must use parameterised queries instead of manually appending those values. Currently if name, number or description would contain any sql it would get executed.
A lot more detailed answer is in How can I prevent SQL injection in PHP?
Read about escaping characters in mysql. I think it is done with \

Remove last char if it's a specific character

I need to update values in a table by removing their last char if they ends with a +
Example:
John+Doe and John+Doe+ should both become John+Doe.
What's the best way to achieve this?
UPDATE table
SET field = SUBSTRING(field, 1, CHAR_LENGTH(field) - 1)
WHERE field LIKE '%+'
If you are trying to display the field instead of update the table, then you can use a CASE statement:
select
case
when right(yourfield,1) = '+' then left(yourfield,length(yourfield)-1)
else yourfield end
from yourtable
SQL Fiddle Demo
you didn't explain exactly the situation.
but if you search for names in a text. I'll remove all the non chars (anything not a-z and A-Z) including spaces and then compare.
if you want just the last char, try the SUBSTRING_INDEX function.
if you are passing to the DB as a string, you can do this with str_replace
<?php
$str = "John+Doe+";
$str = str_replace("+"," ",$str);
echo $str;
?>

Unknown column '' in 'where clause'

My query is throwing up this error. Can anyone see why?
$query = "SELECT * FROM Units WHERE ID = `$uniqueUnits[a]`";
Unknown column '' in 'where clause'
Two problems.
You're using backticks to delimit a string. Backticks delimit fields, so MySQL thinks you're trying to give it a column name.
The error message indicates that, in fact, this value that it thinks is a column name, is empty. So your value $uniqueUnits[a] is probably broken, or not being interpolated correctly.
You should do the following:
Interpolate your variables explictly with the "complex syntax" to be sure that the string forms properly;
Check the value of $query so that you can see what's going on:
print $query;
Use actual quotation marks to delimit strings:
$query = "SELECT * FROM Units WHERE ID = '{$uniqueUnits[a]}'";
// ^ quote
// ^ PHP variable interpolation
try
$query = "SELECT * FROM Units WHERE ID = '$uniqueUnits[a]'";
^--- ^---
Backticks are for escaping reserved words, so mysql is translating your variable's contents into a field name.
Because apparently $uniqueUnits[a] resolves to the empty string. And there is no column like this in the database.
Try surrounding your array with {}, like this:
$query = "SELECT * FROM Units WHERE ID = `{$uniqueUnits[a]}`";
Also, is column ID actually in your table?

mysql_real_escape_string ISSUE

If I type
'
into my search bar I get a mysql error as the "sting" has not been escaped- it think.
But the reason why I cant escape it is because I dont think it currently is a string.
the search box generates search results dynamically with ajax it is as I type and it finds the results that I get the error:
You have an error in your SQL syntax; check the manual that corresponds to
your MySQL server version for the right syntax to use near '%' OR Location
LIKE '%'%' OR Map LIKE '%'%' LIMIT 0, 16' at line 2
This is the mysql query:
<?php
if($_POST['q']!=""){
include $_SERVER['DOCUMENT_ROOT'] . "/include/datebasecon.php";
$result = mysql_query("
SELECT id, Name, Location, Map
FROM Accommodation WHERE Name LIKE '%".$_POST['q']."%' OR Location LIKE '%".$_POST['q']."%' OR Map LIKE '%".$_POST['q']."%' LIMIT 0, 16")
or die(mysql_error());
$output = "";
while($row = mysql_fetch_array($result)){
$N = preg_replace("/(".$_POST['q'].")/i","<span>$1</span>",$row['Name']);
$L = preg_replace("/(".$_POST['q'].")/i","<span>$1</span>",$row['Location']);
$M = preg_replace("/(".$_POST['q'].")/i","<span>$1</span>",$row['Map']);
$output .= "<p>".$N." - ".$L."</p>";
}
print $output;
}
?>
Is there anyway i can fix this after its post the query maybe?
When magic_quotes_gpc is off (as it should be!), $_POST['q'] is simply the string ', as just one character. That's why it's appearing in your SQL code like this:
%' OR Location LIKE '%'%' OR Map LIKE '%'%' LIMIT 0, 16
The error takes place at '%'%' because the LIKE string is being prematurely terminated.
You can just use mysql_real_escape_string() on $_POST['q'] and it'll be escaped:
$q = mysql_real_escape_string($_POST['q']);
$result = mysql_query("
SELECT id, Name, Location, Map
FROM Accommodation WHERE Name LIKE '%".$q."%' OR Location LIKE '%".$q."%' OR Map LIKE '%".$q."%' LIMIT 0, 16")
or die(mysql_error());
You wrote "I dont think it currently is a string"... it is a string. You can pass it to mysql_real_escape_string() and use the result to make your query secure and reliable. Everything your script receives by the $_POST, $_GET, $_REQUEST and $_COOKIE params can be used as string, except it is an array.
To make you understand.
Look at your query:
LIKE '%search string%'
note apostrophes you have used to delimit search string.
These apostrophes does mean that data inside IS a string.
Everything you put in quotes into query is a string.
Everything you put in quotes into query must be escaped.
No need to think, consider or estimate. The rule is simple and unambiguous: quoted text should be always escaped.