inner join wont work with mysqli prepared statement in php - php

I can't seem to get this statement or statements alike to work with prepared queries, the code works just fine below:
$DBH = getDBH();
$stmt = $DBH->prepare("SELECT a.id, a.title, a.photo FROM tag t INNER JOIN tag_reference atx ON t.tag_id = atx.tag_id
INNER JOIN articles a
ON atx.article_id = a.id
WHERE t.tag_name = 'example'");
$stmt->execute();
$stmt->bind_result($id,$title,$photo);
$stmt->fetch();
but when I change t.tag_name = '?' it gives me an error that the amount of parameters do not match. This is the statement that does not work.
$DBH = getDBH();
$stmt = $DBH->prepare("SELECT a.id, a.title, a.photo FROM tag t INNER JOIN tag_reference atx ON t.tag_id = atx.tag_id
INNER JOIN articles a
ON atx.article_id = a.id
WHERE t.tag_name = '?'");
$stmt->bind_param('s',$example);
$stmt->execute();
$stmt->bind_result($id,$title,$photo);
$stmt->fetch();
Can anyone please help?

The placeholder ? does not work if enclosed in single quotes. In this case the SQL tokenizer will catch it as literal string.
Change it to:
WHERE t.tag_name = ? ");

When using placeholders, do you need to use quotes? Most placeholder languages I've used don't.
WHERE t.tag_name = ?"

Related

Not able to merge results from the three select statements

Hey look here i am trying to get result from these three select statements at once but i am noit able to do so. So please help me in rectifying my mistake. Don't rate me negative if you found my english or question method bad.
$sql = $conn->prepare("SELECT Count(c.c_id) from complaints c, users u,cell_num cn where c.status=? AND c.u_id_fk=u.u_id AND u.u_id=cn.u_id_fk");
$sql->bind_param("i",$statOpen);
$sql .= $conn->prepare("SELECT Count(c.c_id) from complaints c, users u,cell_num cn where c.status=? AND c.u_id_fk=u.u_id AND u.u_id=cn.u_id_fk");
sql->bind_param("i",$statProgress);
$sql .= $conn->prepare("SELECT Count(c.c_id) from complaints c, users u,cell_num cn where c.status=? AND c.u_id_fk=u.u_id AND u.u_id=cn.u_id_fk");
$sql->bind_param("i",$statClosed);
$sql->execute();
$sql->store_result();
if($sql->num_rows > 0)
{
$sql->bind_result($c_id);
while( $sql->fetch() )
{
$user[] = array(
'c_id'=>$c_id
);
}
echo json_encode($user);
$sql->close();
}
You can do conditional aggregation:
select
sum(c.status = ?) cnt_open,
sum(c.status = ?) cnt_progress,
sum(c.status = ?) cnt_closed
from complaints c
inner join users u on u.u_id = c.u_id_fk
inner join cell_num cn on cn.u_id_fk = u.u_id
This query accepts three parameters at once, that correspond to the three values that you were passing to your three individual queries.
Note that I modified the query to use standard joins (with the on keyword) rather than old-school, implicit joins (with commas in the from clause): this archaic syntax should not be used in new code.
You can make the query more efficient by adding a where clause that filters on the three possible statuses (this requires passing each parameter twice):
where c.status in (?, ?, ?)
you can do so, it's more optimised
select c.statut,count(c.c_id)
from complaints c
inner join users u on u.u_id = c.u_id_fk
inner join cell_num cn on cn.u_id_fk = u.u_id
where c.status in (?, ?, ?)
group by c.status

PHP / PDO : query request works, prepared request doesn't

I would like to user prepared request with PDO but it doesn't seem to return any result while the query request do return some.
Here, there are my two requests :
Prepared request :
$req = $this->bdd->prepare('SELECT u.id, u.username, hm.desc, s.name AS shop, hm.amount, hm.date FROM history_members AS hm LEFT JOIN users AS u ON u.id = hm.user_id LEFT JOIN shops AS s ON s.id = hm.shop_id WHERE hm.user_id = :id');
$req->bindValue(':id', $id, PDO::PARAM_INT);
$data = $req->fetchAll(PDO::FETCH_ASSOC);
$req->closeCursor();
Query request :
$req = $this->bdd->query('SELECT u.id, u.username, hm.desc, s.name AS shop, hm.amount, hm.date FROM history_members AS hm LEFT JOIN users AS u ON u.id = hm.user_id LEFT JOIN shops AS s ON s.id = hm.shop_id WHERE hm.user_id = '.$id);
$data = $req->fetchAll(PDO::FETCH_ASSOC);
$req->closeCursor();
What am I doing wrong with the prepared request ?
you did not execute your query.
First execute query then fetch the result.

How to use common parameter for Mysql PDO query

I have tried to make a search query and my query statement is like the following:
<?php
$query= $db->prepare("SELECT
p.id,
p.name,
p.surname,
p.phone,
t.title,
j.job,
d.department
FROM
People p
JOIN
Titles t ON p.title_id = t.id
JOIN
Departments d ON p.dept_id = d.id
JOIN
Jobs j ON p.job_id = j.id
WHERE
p.name LIKE :v1 OR
p.surname LIKE :v2 OR
p.phone LIKE :v3 OR
ORDER BY
d.department,
p.name,
p.surname"
);
$query->bindValue(":v1", $value, PDO::PARAM_STR);
$query->bindValue(":v2", $value, PDO::PARAM_STR);
$query->bindValue(":v3", $value, PDO::PARAM_STR);
?>
$value comes from a textbox in which search string is typed. The query works fine.
What I want to learn is why I have to use 3 parameters for just one value. Why cannot I type the statement like:
p.name LIKE :v1 OR
p.surname LIKE :v1 OR
p.phone LIKE :v1 OR
and then bind the parameter once only?
$query->bindValue(":v1", $value, PDO::PARAM_STR);
http://paul-m-jones.com/archives/243
Something about stability in memory handling..
I wrote this as an answer because I cant comment yet.
The doc of PDO::prepare() says:
You cannot use a named parameter marker of the same name twice in a prepared statement.

php pdo selecting from multiple tables with more than one where clauses

I am new to PHP PDO and converting some regular MySQL queries to work with PDO.
The query below when tested in phpMyAdmin works great when the assigned values replaced the current placeholders in the SQL statement. But when I configure it to work as it is now with PDO, it does not produce any results or errors. Can someone please tell me or show me what is it that I am doing wrong?
Someone told me that I cannot pass parameters as references in the array.
And if correct, what is the best way for creating a solution and by using only the user ID passed through to the variable $uid. Thanks.
<p>// For testing</p>
<pre>$uid = 1;</pre>
<p> </p>
<pre>$array = array(
':uId' => ''.$uid.'',
':aId' => 'u.user_id',
':gID' => 'a.group_id',
':eID' => 'a.entry_id',
':pID' => 'a.permit_id'
);</pre>
// create the sql for qd_user_usam table
$sql = "SELECT u.user_id, a.acl_id, g.group_name, e.entry_level, p.permit_level
FROM qd_users as u, qd_users_acl as a, qd_users_group as g, qd_users_entry as e, qd_users_permission as p
WHERE u.user_id = :uID
AND a.acl_id = :aID
AND g.group_id = :gID
AND e.entry_id = :eID
AND p.permit_id = :pID";
<p>try
{</p>
<p>// Build the database PDOStatement</p>
<pre>$_stmt = $this->_dbConn->prepare($sql);</pre>
<pre>$_stmt->execute($array);</pre>
<pre>}
catch(PDOException $e)
{</pre>
<pre>$this->_errorMessage .= 'Error processing user login access. <br /> Line #'.__LINE__ .' '.$e ;</pre>
<pre>die($this->_errorMessage);
}</pre>
<pre>$results = $_stmt->fetchAll(PDO::FETCH_ASSOC);</pre>
<pre>return $results;</pre>
<pre>$results = null;</pre>
<pre>$this->_dbConn = null;</pre>
You take prepared statements wrong.
Thy have to be used not to represent whatever value in the query, but dynamically added data only.
While a.group_id is a column name and have to be written as is, without prepared statements.
// For testing
$uid = 1;
// create the sql for qd_user_usam table
$sql = "SELECT u.user_id, a.acl_id, g.group_name, e.entry_level, p.permit_level
FROM qd_users as u, qd_users_acl as a, qd_users_group as
g, qd_users_entry as e, qd_users_permission as p
WHERE u.user_id = ?
AND a.acl_id = u.user_id
AND g.group_id = a.group_id
AND e.entry_id = a.entry_id
AND p.permit_id = a.permit_id";
$_stmt = $this->_dbConn->prepare($sql);
$_stmt->execute(array($uid));
The problem is that you're trying to write your JOINs implicitly by binding the joined columns as parameters, which would not work. The parameters can not reference another column; they are seen as strings in this case. If you rewrite the query like this it should fix the JOIN problem:
SELECT u.user_id, a.acl_id, g.group_name, e.entry_level, p.permit_level
FROM qd_users AS u
JOIN qd_users_acl AS a ON (u.user_id = a.acl_id)
JOIN qd_users_group AS g ON (g.group_id = a.group_id)
JOIN qd_users_entry AS e ON (e.entry_id = a.entry_id)
JOIN qd_users_permission AS p ON (p.permit_id = a.permit_id)
WHERE u.user_id = :uID

PHP PDO Prepared Statement Query not substituting

I have a short segment of PHP code:
$stm = $db->prepare($sql);
$result = $stm->execute($params);
$params is the following
array(1) {
[0]=>
string(3) "why"
}
However, the $sql being sent to MySQL still contains a question mark according to the MySQL logs:
1 Query SELECT a.* FROM article a
LEFT JOIN article_links al on a.id = al.from_article_id
WHERE al.to_article = '?'
Is there something else I'm missing for substitution?
You don't need to have the single quotes around the question mark:
SELECT a.* FROM article a
LEFT JOIN article_links al on a.id = al.from_article_id
WHERE al.to_article = ?;
I suspect this is true:
$sql = "SELECT a.* FROM article a LEFT JOIN article_links al on a.id = al.from_article_id WHERE al.to_article = '?'"
The question mark should not be surrounded by quotes--this means it's a string instead of a parameter placeholder. Use just al.to_article = ?.

Categories