MySQL syntax error on using if condition in WHERE clause - php

I am getting syntax error when I am using if conditions in the WHERE clause of my Mysql query. For example, if I put in WHERE 1 with only the condition like sector = 2, it is working. But when I put the if conditions, it is not working anymore.
$query= "SELECT
P.id
,P.price
,P.contract
,P.property_type
,P.sector
,P.title
,P.address
,P.bedrooms
,P.bathrooms
,P.price
,P.m2
,P.text_english
,P.photo_01
,P.utilities
,P.google_maps
,P.date
,CT.id
,CT.english_text
,PT.id
,PT.english
,C.cityname
,S.sectorname
,S.id
,O.ownername
,O.phone_one
,O.phone_two
,O.email
,O.notes
FROM properties P
JOIN contract CT
ON CT.id = P.contract
JOIN property_type PT
ON PT.id = P.property_type
JOIN city C
ON C.id = P.city
JOIN sector S
ON S.id = P.sector
JOIN owner O
ON O.id = P.owner WHERE 1";
if (!empty($sector)) { $query .= "AND P.sector = '$sector'"; }
if (!empty($property_type)) { $query .= " AND P.property_type = '$property_type'"; }
if (!empty($contract)) { $query .= " AND P.contract = '$contract'"; }
if (!empty($minimum_price)) { $query .= " AND P.price BETWEEN '$minimum_price' AND '$maximum_price'"; }
if (!empty($m2_from)) { $query .= " AND P.m2 BETWEEN '$m2_from' AND '$m2_until'"; }
if (!empty($bedrooms)) { $query .= " AND P.bedrooms = '$bedrooms'"; }
This is the error:
Fatal error: Uncaught exception 'PDOException' with message
'SQLSTATE[42000]: Syntax error or access violation: 1064 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 'P.sector = 2
LIMIT 0, 30' at line 43' in
E:\xampp\htdocs\dolche\admin\class\pagination.php:451 Stack trace: #0
E:\xampp\htdocs\dolche\admin\class\pagination.php(451):
PDOStatement->execute() #1
E:\xampp\htdocs\dolche\admin\search.php(190): pagination->execute() #2
{main} thrown in E:\xampp\htdocs\dolche\admin\class\pagination.php on
line 451
Any help resolving this issue will be very welcome. Thanks!

You are missing a space between 1 and AND:
if (!empty($sector)) { $query .= "AND P.sector = '$sector'"; }
^^^^
HERE
Interestingly enough, you got it right everywhere else.

You have to add a space before your AND.
Try:
if (!empty($sector)) { $query .= " AND P.sector = '$sector'"; }
instead of
if (!empty($sector)) { $query .= "AND P.sector = '$sector'"; }

Add Space before AND P.sector = '$sector'
Change from
if (!empty($sector)) { $query .= "AND P.sector = '$sector'"; }
To
if (!empty($sector)) { $query .= " AND P.sector = '$sector'"; }

Please give space either:
ON O.id = P.owner WHERE 1 ";
or
if (!empty($sector)) { $query .= " AND P.sector = '$sector'"; }

Related

Ignore function on if condition PHP

I have some code but I want it to ignore 'customer::$data['vehicle_id']' when category_id = 1, 4, 9.
I've struggled with the code below and to add another function is out of my capabilities, so any advice would be great. Thanks in advance.
If vehicle_id is not selected it works fine.
if (empty($_GET['manufacturer_id'])) {
$manufacturers_query = database::query(
"select distinct m.id, m.name from ". DB_TABLE_PRODUCTS ." p
left join ". DB_TABLE_MANUFACTURERS ." m on m.id = p.manufacturer_id ".
(!empty($_GET['category_id']) ? " left join " . DB_TABLE_PRODUCTS_TO_CATEGORIES . " pc on pc.product_id = p.id " : "").
(!empty(customer::$data['vehicle_id']) ? " left join " . DB_TABLE_PRODUCTS_TO_VEHICLES . " ptv on ptv.product_id = p.id " : "").
"where p.status
and manufacturer_id
". (!empty($_GET['category_id']) ? "and pc.category_id = " . (int)$_GET['category_id'] : "") ."
". (!empty(customer::$data['vehicle_id']) ? "and ptv.vehicle_id = " . (int)customer::$data['vehicle_id'] : "") ."
order by m.name asc;"
);
I've tried using this:
". (!empty(customer::$data['vehicle_id']) && (!empty($_GET['category_id']) || !array_intersect(array(1, 4, 9), $_GET['category_id'])) ? "and ptv.vehicle_id = " . (int)customer::$data['vehicle_id'] : "") ."
EDIT:
while($manufacturer = database::fetch($manufacturers_query)) {
$box_filter->snippets['manufacturers'][] = array(
'id' => $manufacturer['id'],
'name' => $manufacturer['name'],
'href' => document::ilink('manufacturer', array('manufacturer_id' => $manufacturer['id'])),
);
}
I have taken your rather messy code and refactored it so it is readable, maintainable and better in a lot of small and big ways. It's by no means perfect, but now it can be reasoned about.
I also eliminated the SQL Injection opportunities for you, but you still need to redesign your database::query() function so it accepts an array of parameters to be used with your sql query in a prepared statement execution. I used named placeholders in your query to make it readable.
Doing the refactor this way, allowed me to add a boolean flag I can set if your ignore condition is true ($_GET['category_id'] equals one of [1,4,9])
if (empty($_GET['manufacturer_id']))
{
$ignoreVehicleId = false;
$params = [];
$query = "select distinct m.id, m.name
from ${DB_TABLE_PRODUCTS} p
left join ${DB_TABLE_MANUFACTURERS} m on m.id = p.manufacturer_id ";
if( !empty($_GET['category_id'])
{
$query .= " left join ${DB_TABLE_PRODUCTS_TO_CATEGORIES} pc on pc.product_id = p.id ";
if(in_array($_GET["category_id"], [1,4,9]) // <--- This array should be better documented to not use MAGIC NUMBERS. What is 1,4 or 9?
{
$ignoreVehicleId = true;
}
}
if( $ignoreVehicleId === false && !empty( customer::$data['vehicle_id'])
{
$query .= " left join ${DB_TABLE_PRODUCTS_TO_VEHICLES} ptv on ptv.product_id = p.id ";
}
$query .= "where p.status and manufacturer_id ";
/*
* In the following two IF's named parameters for prepared statements are being used.
* You need to refactor the database::query() function to accept a params array.
* Read up on using prepared statements with mysqli_* or better, PDO.
*
* DO NOT BUILD QUERIES WITH VARIABLES ANY OTHER WAY!!!
*
* If you do you are asking to be pwned by someone using your less than secure
* practises to do SQL Injection.
*/
if( !empty($_GET['category_id'])
{
" and pc.category_id = :category_id ";
$params[":category_id"] = (int)$_GET['category_id'];
}
if( $ignoreVehicleId === false && !empty(customer::$data['vehicle_id'])
{
" and ptv.vehicle_id = :vehicle_id ";
$params[":vehicle_id"] = (int)customer::$data['vehicle_id'];
}
$query .= " order by m.name asc;"
$manufacturers_query = database::query($query, $params);
}

Error in SQL syntax

I am getting this error , Not able to make out what is going wrong , please help.
A Database Error Occurred
Error Number: 1064
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 ')' at line 1
SELECT GROUP_CONCAT(DISTINCT ud.userid) as id from pr_users_details ud INNER JOIN pr_users u ON ud.userid = u.id WHERE ud.status = '1' AND ()
My function looks like this:
function get_nomination_emailids($functions, $levels, $roles, $locations, $emails)
{
$SQL.="SELECT GROUP_CONCAT(DISTINCT ud.userid) as id from pr_users_details ud INNER JOIN pr_users u ON ud.userid = u.id WHERE ud.status = '1' ";
if(count($functions)>0)
{
$d = implode(",",$functions);
$whereand[] = " u.departmentid IN (".$d.") ";
}
if(count($levels)>0)
{
$d1 = implode(",",$levels);
$whereand[] = " ud.designation_id IN (".$d1.") ";
}
if(count($roles)>0)
{
$d2 = implode(",",$roles);
$whereand[] = " u.userroleid IN (".$d2.") ";
}
if(count($locations)>0)
{
$d3 = implode(",",$locations);
$whereand[] = " u.branchid IN (".$d3.") ";
}
if(count($emails)>0)
{
$d4 = implode(",",$emails);
$whereor[] = " ud.userid IN (".$d4.") ";
}
$whr = array();
if(isset($whereand))
$whr[] = " (".implode(" AND ",$whereand).") ";
if(isset($whereor))
$whr[] = " (".implode(" OR ",$whereor).") ";
if(count($whr > 0))
{
$SQL .= " AND (".implode(" OR ",$whr).") ";
}
$query = $this->db->query($SQL);
$return = $query->result_array();
return $return[0]['id'];
//print_r($return);die;
}
AND() remove in your query try this.
SELECT GROUP_CONCAT(DISTINCT ud.userid) as id from pr_users_details ud INNER JOIN pr_users u ON ud.userid = u.id WHERE ud.status = '1'

php does not work with apostrophe in mysql query on linux server

I'm shucked with a strange problem. when i execute this query from my phpmyadmin it works fine and returns 2 results . But When we are executing this Query form php page it returns 0 result.
$query = "SELECT distinct(vtiger_products.product_no) FROM `vtiger_products`
INNER JOIN vtiger_crmentity VC ON VC.crmid = vtiger_products.productid
inner join vtiger_tree_product vtp on vtiger_products.productid = vtp.productid";
$custom_conditions = ' cf.cf_1399 = "'.$_REQUEST['size'].'"';
$temp ='Where vtiger_products.hisotrization_status='Current'
AND vtiger_products.productid > 0
AND VC.deleted = 0
AND vtp.nodeid in (425,426,427,428,430,431,457,458,459,460,480,488,502,510,514,515,516,517,518,519,520,521,525,526,527,528,529)';
if ($custom_conditions) {
$query .= " inner JOIN vtiger_productcf cf on cf.productid = vtiger_products.productid ";
$conditions .= " AND ( " . str_replace('""','\""',str_replace("''","\''",$custom_conditions)) . " ) ";
}
$query = $query.$temp . $conditions;
SELECT distinct(vtiger_products.product_no) FROM `vtiger_products`
INNER JOIN vtiger_crmentity VC ON VC.crmid = vtiger_products.productid
inner join vtiger_tree_product vtp on vtiger_products.productid = vtp.productid
inner JOIN vtiger_productcf cf on cf.productid = vtiger_products.productid
Where vtiger_products.hisotrization_status='Current'
AND vtiger_products.productid > 0
AND VC.deleted = 0
AND vtp.nodeid in (425,426,427,428,430,431,457,458,459,460,480,488,502,510,514,515,516,517,518,519,520,521,525,526,527,528,529)
AND ( cf.cf_1399 = "20'" );
Waiting for your response Thanks
You can pass the the php variables into the query by using function mysql_real_escape_string(Escapes special characters in a string for use in an SQL statement).
e.g.mysql_real_escape_string($user);
Plain and simple:
Wrong:
$query = '... set test = 'blah' where ...'; (' before blah terminates the string)
Solution 1:
$query = '... set test = \'blah\' where ...'; (escaping)
Solution 2:
$query = "... set test = 'blah' where ..."; (double quotes aren't terminated by single quotes)
Please note that "Hello, $test !" evaluates $test while 'Hello, $test !' does not.

Can't get spaces in my SQL statement

I have two variables in my WHERE statement. I cant seem to separate them with a space so i end up getting a syntax error. Thanks for the help.
(I am using codeigniter)
btw i have tried setting a $space variable, and putting spaces before the and, after setting both variables, and in the sql.
ERROR
Error Number: 1064
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 'source_adusers.ad_account="Wolfs, Marc" GROUP BY rollout_systems.eam_user LIMIT ' at line 2
SELECT *, COUNT(rollout_systems.EAM_USER) as systems FROM rollout_systems LEFT JOIN source_adusers ON rollout_systems.EAM_User = source_adusers.ad_account WHERE rollout_systems.scope_ID = 3AND source_adusers.ad_account="Wolfs, Marc" GROUP BY rollout_systems.eam_user LIMIT 0,50
Line Number: 330
PHP
if ($this->session->userdata('scopeId') != NULL) {
$where1 = 'WHERE rollout_systems.scope_ID = '. $this->session->userdata('scopeId') . '';
} else {
redirect('/headquarters/home');;
}
if ($search) {
$where2 = ' AND rollout_systems.sys_name ="'.$search.'"';
} else {
$where2 = '';
}
$query = $this->db->query('SELECT * FROM rollout_systems LEFT JOIN source_adusers
ON rollout_systems.eam_user = source_adusers.ad_account '. $where1 .''. $where2 .' GROUP BY rollout_systems.sys_name LIMIT '.$limit.',50');
what if you keep the spaces and the AND in the $query, instead of building them into your where variables? Then your $where 2 just needs to work without affecting the query - thus 0=0.
if ($this->session->userdata('scopeId') != NULL) {
$where1 = 'WHERE rollout_systems.scope_ID = '. $this->session->userdata('scopeId') . '';
} else {
redirect('/headquarters/home');;
}
if ($search) {
$where2 = 'rollout_systems.sys_name ="'.$search.'"';
} else {
$where2 = '0=0';
}
$query = $this->db->query('SELECT * FROM rollout_systems LEFT JOIN source_adusers
ON rollout_systems.eam_user = source_adusers.ad_account '. $where1 .' and '. $where2 .' GROUP BY rollout_systems.sys_name LIMIT '.$limit.',50');
Just add a space between the two vars - '. $where1 .' '. $where2 .'
As pointed out by others you really should be escaping your user input using mysql_real_escape_string() or intval() if you are expecting an integer value. If you are using PDO or mysqli use prepared statements.
If $this->db is a PDO instance you could use -
$params = array();
if ($this->session->userdata('scopeId') != NULL) {
$where = 'WHERE rollout_systems.scope_ID = ?';
$params[] = $this->session->userdata('scopeId');
} else {
redirect('/headquarters/home');;
}
if ($search) {
$where .= ' AND rollout_systems.sys_name = ?';
$params[] = $search;
}
$sql = "SELECT * FROM rollout_systems
LEFT JOIN source_adusers ON rollout_systems.eam_user = source_adusers.ad_account
$where
GROUP BY rollout_systems.sys_name
LIMIT ?, 50";
$params[] = $limit;
$query = $this->db->prepare($sql);
$query->execute($params);
$where = array();
if ($this->session->userdata('scopeId') != NULL) {
// better to escape your parameter here unless you trust it totally
// judging by its name, it's user-provided data, so I wouldn't trust it
$where[] = 'rollout_systems.scope_ID = '. $this->session->userdata('scopeId');
} else {
redirect('/headquarters/home');
// you may need to exit here after redirection, depends on your implementation
}
if ($search) {
// once again don't forget to escape $search in real application
$where[] = "rollout_systems.sys_name = '" . $search . "'";
}
$query = $this->db->query("
SELECT
*
FROM
`rollout_systems`
LEFT JOIN
`source_adusers`
ON rollout_systems.eam_user = source_adusers.ad_account
WHERE
" . implode (' AND ', $where) . "
GROUP BY
rollout_systems.sys_name
LIMIT " . $limit /* escape it! */ . ",50"
);
You also have the option to use the PHP syntax
$sql = " blah blah {$my_var} {$my_other_var} ";

CakePHP 1.3 query method gives SQL 1064 error

I wrote a custom query to use in CakePHP 1.3 The query is as follows:
SELECT artists.id, artists.name, artists.image_id, genres.genre
FROM artists
LEFT JOIN coupling_artist_genre
ON artists.id = coupling_artist_genre.id_in
LEFT JOIN genres
ON coupling_artist_genre.id_out = genres.id
WHERE artists.name LIKE '%tee%'
AND genres.id IN (12,14)
ORDER BY artists.name ASC
LIMIT 0,25
When I call this like this:
$this -> Artist -> query ($sql);
I get this error:
1064: 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 '
However, when I copy the generated query and paste it into PHPMyAdmin it works fine. No warnings, no errors, and most importantly: the result I expect.
Does anyone know what could cause this difference between Cake and PMA?
Edit: This is how the query is generated:
$query = "SELECT artists.id, artists.name, artists.image_id";
if ($genres != ' ' && strlen ($genres) > 0)
{
$query .= ", genres.genre";
}
$query .= " FROM artists";
if ($genres != ' ' && strlen ($genres) > 0)
{
$query .= " LEFT JOIN coupling_artist_genre ON artists.id = coupling_artist_genre.id_in";
$query .= " LEFT JOIN genres ON coupling_artist_genre.id_out = genres.id";
}
$query .= " WHERE";
if ($searchString != '' && strlen ($searchString) > 0)
{
$searchString = $searchString == ' ' ? '' : $searchString;
$query .= " artists.name LIKE '%".$searchString."%'";
}
if ($searchString != ' ' && strlen ($searchString) > 0 && $genres != ' ' && strlen ($genres) > 0)
{
$query .= " AND";
}
if ($genres != ' ' && strlen ($genres) > 0)
{
$query .= " genres.id IN (".$genres.")";
}
$query .= " ORDER BY artists.name ASC LIMIT " . ($page - 1) * 25 . ",25";
$this -> set ('artists', $this -> Artist -> query ($query));
I think there are case when your queries end up like this:
" ...
WHERE
ORDER BY ... "
or
" ...
WHERE artists.name LIKE '%tee%'
AND
ORDER BY ... "
Try this:
$query .= " WHERE True ";
if ($searchString != '' && strlen ($searchString) > 0)
{
$searchString = $searchString == ' ' ? '' : $searchString;
$query .= " AND artists.name LIKE '%".$searchString."%'";
}
if ($genres != ' ' && strlen ($genres) > 0)
{
$query .= " AND genres.id IN (".$genres.")";
}
$query .= " ORDER BY artists.name ASC LIMIT " . ($page - 1) * 25 . ",25";
$this -> set ('artists', $this -> Artist -> query ($query));
Tried to post this earlier, but I couldn't without 100 reputation. Anyway here's the answer I tried to post earlier:
Dear visitors of this question. I am terribly sorry (especially for you ypercube because you took the time to think about AND answer my question!).
I just discovered that I made a very stupid mistake. Down in my controller, in a totally different method that shouldn't even be executed I had another query in a die() call. That was the query MySQL was complaining about. I never expected it to be executed but alas, it was the query causing my error. Seeing as I didn't need it anymore I deleted it and my error was gone.
Once again, I'm sorry for all of you that put time in this question. I shall try to be more careful in the future!

Categories