I have a problem with INNER JOIN and PDO. My query is working just fine when not using INNER JOIN. When adding INNER JOIN to the query nothing shows.
Is this a way to go or am I completely wrong?
Any suggestions?
public function search($searchterm)
{
$query = $this->db->prepare("
SELECT
ad.id AS idet,
ad.lid,
ad.firstname AS firstnamer,
ad.surname AS surnamer,
ad.socialnr AS socialnumber,
ba.class AS classes
FROM `everybody` ad
INNER JOIN `students` ba
ON idet = ba.id
WHERE (`firstname` LIKE :search OR `surname` LIKE :search OR `classes` LIKE :search)");
$searchterm = '%' . $searchterm . '%';
$query->bindParam(':search', $searchterm, PDO::PARAM_STR);
$query->execute();
while($row = $query->fetch(PDO::FETCH_ASSOC)) {
echo $row['idet']. ' : '. $row['firstnamer']. ' '. $row['surnamer']. ' - '. $row['socialnumber']. ' Class: '. $row['classes']. '<br />';
}
}
You can't use a column alias in ON or WHERE. It should be
ON ad.id = ba.id
In case there are other SQL errors, you should enable PDO exceptions:
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Try by changing
INNER JOIN `students` ba
ON ad.id = ba.id
/*^^^^*/
WHERE (ad.firstname LIKE :search OR ad.surname LIKE :search OR ad.class LIKE :search)");
/*^^*/ /*^^*/ /*^^*/
Thank you all for your help.
Yes I have enabled exceptions for PDO errors. No error are registered. I have tried your suggestions as posted above. Nothing works.
When not using INNER JOIN, this code works like a charm:
public function search($searchterm)
{
$query = $this->db->prepare("
SELECT
id,
lid,
firstname,
surname,
socialnr
FROM `everybody`
WHERE (`firstname` LIKE :search OR `surname` LIKE :search)");
$searchterm = '%' . $searchterm . '%';
$query->bindParam(':search', $searchterm, PDO::PARAM_STR);
$query->execute();
while($row = $query->fetch(PDO::FETCH_ASSOC)) {
echo $row['id']. ' : '. $row['firstname']. ' '. $row['surname']. ' - '. $row['socialnr']. '<br />';
}
}
The difference between the code in my first post and this one, is the absence of INNER JOIN. I hope it will help any one to help me to understand why.
Is this the right approach? Do I need to rethink this and rewrite my function? Please advice in any direction to help me on the right track. You are most helpful. Thanks.
Related
my query is working but I don't know how to put it in a prepared statement
This is my query(working)
SELECT P.first_name, P.middle_name, P.last_name, P.lrn, P.section
FROM students P INNER JOIN student_load C ON P.lrn = C.lrn
WHERE subject_code = 12332654
This is my prepared statement(I'm new to the prepared statement so I don't know much)
function get_total_all_records()
{
include('../config.php');
//IM NOT SURE IF THE PROBLEM IS HERE($statement)
$statement = $connection->prepare("SELECT P.first_name, P.middle_name,
P.last_name, P.lrn, P.section
FROM students P
INNER JOIN student_load C ON P.lrn = C.lrn");
$statement->execute();
$result = $statement->fetchAll();
return $statement->rowCount();
}
$query = '';
$output = array();
// OR IF THE PROBLE IS HERE($query)
$query = "SELECT P.first_name, P.middle_name, P.last_name, P.lrn, P.section
FROM students P INNER JOIN student_load C ON P.lrn = C.lrn
WHERE subject_code = 12332654";
if(isset($_POST["search"]["value"])){
$query .= 'AND ( lrn LIKE "%'.$_POST["search"]["value"].'%"
OR teacher LIKE "%'.$_POST["search"]["value"].'%"
OR sem LIKE "%'.$_POST["search"]["value"].'%" )';
}
One of the points of preparing a query is that you can use parameters for the parts you want to replace with data. This helps to protect you from SQL Injection Attack which concatenating variables into the string does not.
As your first query has no need of parameters it could quite happily be run using a simple ->query() but the second would be best run using a prepare and execute
$params = [':subjcode'=>$subject_code];
$query = "SELECT P.first_name, P.middle_name, P.last_name, P.lrn, P.section
FROM students P INNER JOIN student_load C ON P.lrn = C.lrn
WHERE subject_code = :subjcode ";
if(isset($_POST["search"]["value"])){
$query .= 'AND ( lrn LIKE :s1
OR teacher LIKE :s2
OR sem LIKE :s3 )';
$params = array_merge($params,
[':s1'=> '%' . $_POST["search"]["value"] . '%'],
[':s2'=> '%' . $_POST["search"]["value"] . '%'],
[':s3'=> '%' . $_POST["search"]["value"] . '%']
);
}
$stmt = $connection->prepare($query);
$stmt->execute($params);
Note I also added a space after :subjcode "; which was missing in your original query
I have set up a query as such:
$query = 'SELECT SGC.sys_id, TBL.semester, SGC.bonus, SGC.exam, SGC.ca FROM SubjectGradeComponent AS SGC, ';
$query .= '(SELECT `sys_id`, `semester` FROM AcademicYearTerm AS AYT, SubjectYearTermLevel AS SYTL WHERE academic_year = "' . $academic_year . '" AND SYTL.subject_id = ' . $subject_id . ' AND SYTL.form_level = ' . $form_level. ' AND SYTL.yearTerm_id = AYT.yearTerm_id) AS TBL ';
$query .= 'WHERE SGC.sys_id = TBL.sys_id;';
However when I run the query, $mysql->query($query);it returns an empty result with 0 rows. Running the same query on phpmyadmin shows the desired result. I have looked around but do not understand the problem.
$mysql->error does not show any error message either
EDIT:
generated query is like this:
SELECT SGC.sys_id, TBL.semester, SGC.bonus, SGC.exam, SGC.ca FROM SubjectGradeComponent AS SGC, (SELECT `sys_id`, `semester` FROM AcademicYearTerm AS AYT, SubjectYearTermLevel AS SYTL WHERE academic_year = "2018-2019" AND SYTL.subject_id = 1 AND SYTL.form_level = 1 AND SYTL.yearTerm_id = AYT.yearTerm_id) AS TBL WHERE SGC.sys_id = TBL.sys_id;""
Question is where are the "" from?
Looks like you want a JOIN query instead.
You should also use prepared statement with placeholders ? instead of injecting values directly into the query.
$query = "SELECT SGC.sys_id,
AYT.semester,
SGC.bonus,
SGC.exam,
SGC.ca
FROM SubjectGradeComponent AS SGC
JOIN AcademicYearTerm AS AYT
ON SGC.sys_id = AYT.sys_id
JOIN SubjectYearTermLevel AS SYTL
ON SYTL.yearTerm_id = AYT.yearTerm_id
WHERE academic_year = ?
AND SYTL.subject_id = ?
AND SYTL.form_level = ?";
I was wondering how I can prevent sql injections with this search query of mine? Unfortunately I had to use the string due to me needing to concatenate the first and last names to search. I have tried prepared statements but they don't seem to work here too. I hope someone can help me with this. Thank you.
My function
public function admin_search($input,$limit,$start){
$sql = "SELECT * FROM agent_accounts as aa LEFT JOIN person as p ON aa.person_id = p.id "
. "WHERE CONCAT_WS('', p.first_name, p.last_name) LIKE '%$input%' "
. "OR p.email LIKE '%$input%' OR p.phone_number LIKE '%$input%' "
. "OR aa.account_number LIKE '%$input%' LIMIT $limit OFFSET $start";
$query = $this->db->query($sql);
if($query->num_rows()>0){
foreach($query->result()as $row){
$documents[] = $row;
}
return $documents;
}else{
return false;
}
}
Codeigniter Active records automatically escape queries to prevent from SQL injection
Like this
$query = $this->db->get_where('table_name', array('id' => $id), $limit, $offset);
But if you use query siblings
Try this :
$sql = "SELECT * FROM agent_accounts as aa LEFT JOIN person as p ON aa.person_id = p.id "
. "WHERE CONCAT_WS('', p.first_name, p.last_name) LIKE ? "
. "OR p.email LIKE ? OR p.phone_number LIKE ? "
. "OR aa.account_number LIKE ? LIMIT ? OFFSET ?";
$query = $this->db->query($sql,array('%{$input}%','%{$input}%','%{$input}%','%{$input}%',$limit,$start));
The question marks in the query are automatically replaced with the values from array.
This question already has answers here:
How to include a PHP variable inside a MySQL statement
(5 answers)
Closed 1 year ago.
I looked for an answer but could not find it as the issue seems to be slightly different here.
$vid = $_SESSION['ID_Vendor'];
echo "ID: $vid";
$q = 'SELECT business_name, vd.ID_Vendor, res.ID_RestaurantEstablishment
FROM restaurant res
INNER JOIN vendor_data vd
ON vd.ID_Vendor=res.ID_Vendor AND res.ID_Vendor="$vid" ORDER BY business_name ASC';
The variable $vid has indeed a value (equal to 2 in this case, but it could be different), HOWEVER, when I specifically set
WHERE res.ID_Vendor=2
my query returns the correct and expected list of values, but when, instead, I use
WHERE res.ID_Vendor="$vid"
with "$vid", the echo of my values is simply empty.
Below is the full snippet of the code to also echo the output.
Thanks for your help.
$vid = $_SESSION['ID_Vendor'];
echo "ID: $vid";
$q = 'SELECT business_name, vd.ID_Vendor, res.ID_RestaurantEstablishment
FROM restaurant res
INNER JOIN vendor_data vd
ON vd.ID_Vendor=sfe.ID_Vendor AND res.ID_Vendor="$vid" ORDER BY business_name ASC';
$r = mysqli_query($connection, $q);
while ($row = mysqli_fetch_array ($r, MYSQLI_NUM)) {
echo '>' . htmlspecialchars($row[0]) . ' ' . htmlspecialchars($row[1]) . ' ' . htmlspecialchars($row[2]) .'</option>';
}
PHP does not recognize variable in apostrophes pair ''. Put your variable in "". EG:
"WHERE res.ID_Vendor='$vid'"
Since I raised the idea, I suppose I should illustrate the use of prepared statements.
Using mysqli one would proceed as follows (assuming $connection has been successfully initialized):
// The indentation here is purely a matter of personal preference
$query = 'SELECT business_name, vd.ID_Vendor, res.ID_RestaurantEstablishment
FROM restaurant res
INNER JOIN vendor_data vd
ON vd.ID_Vendor = res.ID_Vendor
WHERE res.ID_Vendor = ?
ORDER BY business_name ASC';
$stmt = $connection->prepare($query);
$stmt->bind_param('s', $vid); // 's' assumes $vid is string; use 'i' for int
$stmt->execute();
$res = $stmt->get_result();
while ($row = $res->fetch_array(MYSQLI_NUM))
{
echo '>' . htmlspecialchars($row[0]) . ' ' . htmlspecialchars($row[1]) . ' ' . htmlspecialchars($row[2]) .'</option>';
}
The idiom is the same using PDO. The format of the PDO data source name (DSN) is documented online.
$conn = new PDO($dsn, $username, $password); // define these vars elsewhere
$query = 'SELECT business_name, vd.ID_Vendor, res.ID_RestaurantEstablishment
FROM restaurant res
INNER JOIN vendor_data vd
ON vd.ID_Vendor = res.ID_Vendor
WHERE res.ID_Vendor = :vid
ORDER BY business_name ASC';
$stmt = $conn->prepare($query);
$stmt->execute(array(':vid' => $vid));
while ($row = $stmt->fetch(PDO::FETCH_NUM))
{
echo '>' . htmlspecialchars($row[0]) . ' ' . htmlspecialchars($row[1]) . ' ' . htmlspecialchars($row[2]) .'</option>';
}
In both cases I leave error handling as an exercise for the reader.
There's a few problems with your code:
Firstly, this won't work and will echo $vid literally.
echo "ID: $vid";
This will return: ID: $vid
You'll need to concat the string with the variable, it should be:
echo "ID: " . $vid;
This will return: ID: 2
Secondly, your query won't work:
$q = 'SELECT business_name, vd.ID_Vendor, res.ID_RestaurantEstablishment
FROM restaurant res
INNER JOIN vendor_data vd
ON vd.ID_Vendor=res.ID_Vendor AND res.ID_Vendor="$vid" ORDER BY business_name ASC';
You should enclose the query with double quotes and your variable with single quotes instead:
$q = "SELECT business_name, vd.ID_Vendor, res.ID_RestaurantEstablishment
FROM restaurant res
INNER JOIN vendor_data vd
ON vd.ID_Vendor=res.ID_Vendor AND res.ID_Vendor='$vid' ORDER BY business_name ASC";
For SQL, not like javascript or php, only single quote is allowed for string or char.
For MySQL, if the column type of res.id_vendor is number, res.id_vendor='1' is the same as res.id_vendor=1, so it is better always wrap the variable with single quote, as in res.id_vendor='$vid'
Lastly, comments on coding conventions: it is recommended to not mix upper case and lower case characters in column naming, use "_" as word delimiters, like
vd.id_vendor
res.id_restaurant_establishment
$user_res_get = do_mysql_query("SELECT /* forums.php */ userid, subject, " .
" forumid FROM topics WHERE id=$topicid") or sqlerr(__FILE__, __LINE__);
and:
$user_res_get = do_mysql_query("SELECT /* forums.php */ id, name, FROM " .
"forums WHERE id=$forumid") or sqlerr(__FILE__, __LINE__);
forumd and id are identical
How to "JOIN" them ?
I tryed create something like this:
$user_res_get = do_mysql_query("SELECT u.userid, u.subject, u.forumid, a.id, " .
"a.name FROM topics AS u JOIN forums as a ON u.forumid = a.id WHERE " .
"u.forumid=$topicid") or sqlerr(__FILE__, __LINE__);
But no luck :/
Any suggestions ?
EDIT:
Ant tryed to print with:
$user_row_get = mysql_fetch_assoc($user_res_get);
$user_row_get['subject']
$user_row_get['name']
and others...
Instead of:
WHERE u.forumid=$topicid
try:
WHERE u.id=$topicid