How to use common parameter for Mysql PDO query - php

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.

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: Can't bind value to multiple variables?

I am trying to execute a query that joins several tables using the same foreign key via the below query but it returns false.
$question_id = 11406;
$query = $db->prepare("SELECT q.question_attempts_permitted, q.question_range, a.answer_text, r.attempt_count
FROM checkup_questions q, checkup_answers a, user_responses r
WHERE a.question_id=:question_id AND q.question_id=:question_id AND r.question_id=:question_id");
$query->bindValue(':question_id', $question_id, PDO::PARAM_INT);
$query->execute();
However, if I inject the question_id directly the query returns the desired result.
$query = $db->prepare("SELECT q.question_attempts_permitted, q.question_range, a.answer_text, r.attempt_count
FROM checkup_questions q, checkup_answers a, user_responses r
WHERE a.question_id=11406 AND q.question_id=11406 AND r.question_id=11406");
$query->execute();
Is there some limitation with the bindValue interface that causes the first query to fail while the second one returns as expected?
Query text should be rewritten using JOIN:
$query = $db->prepare("
SELECT q.question_attempts_permitted, q.question_range, a.answer_text, r.attempt_count
FROM checkup_questions q
JOIN checkup_answers a ON a.question_id = q.question_id
JOIN user_responses r ON r.question_id = q.question_id
WHERE q.question_id=:question_id
");
// you can provide placeholder without `:`
$query->bindValue('question_id', $question_id, PDO::PARAM_INT);
$query->execute();
Here you have only one placeholder.

php mysql select something and get columns from other tables

I'm using prepared statements and I need to "select" other table, apart from these two, to get data but I get this:
Fatal error: Call to a member function bind_param() on a non-object in C:\xampp\htdocs\views\user\referral.php on line 16
If I add in SELECT table1.* , table.* , "theothertable.*"
$stmt = $mysqli->prepare("SELECT friends.*, rc_usuario.* // or just *
FROM friends
INNER JOIN rc_usuario ON rc_usuario.id = friends.friendID
WHERE friends.userID = ?");
$stmt->bind_param('s', $connectedUserID);
This is working fine, I get what i need, but I also need to get data from another table and I can't make other select because i need it all in a while to print all the data together.
The question is, can I SELECT something like that from 2 tables and also get data from other table/s?
Thank YOU!
EDIT: Add the new statement:
if ($stmt = $mysqli->prepare("SELECT friends.*, members.*, account_type.*
FROM friends
INNER JOIN members ON members.id = friends.friendID
INNER JOIN account_type ON account_type.name = members.acc_type
WHERE friends.userID = ? AND members.acc_type = ?")) {
$stmt->bind_param('is', $connectedUserID, $connectedAcc_type);
$stmt->execute();
} else echo $mysqli->error;
You can join more tables by using another INNER JOIN, like as follows;
INNER JOIN rc_usuario ON rc_usuario.id = friends.friendID
INNER JOIN rc_another ON rc_another.col = friends.coljoin
Just make sure you select all the columns you want in the joined table.
It might also help to run your prepare statement in an if, like this;
if($stmt = $mysqli->prepare("SELECT ...")) { // ... where the rest of your query is
$stmt->bind_param('s', $connectedUserID);
$stmt->execute();
}
else {
echo $mysqli->error;
}
which will give you an idea of any problems with the SQL syntax.
Hope this helps.

PHP: output count()

How do i work with the COUNT()
$sql = $connect->prepare("SELECT COUNT() FROM discos_events e INNER JOIN discos_events_guests eg ON (e.ID = eg.eID) INNER JOIN users u ON (eg.uID = u.id) WHERE e.dID =:id");
$sql->bindValue(":id", $cID);
$sql->execute();
...then what? echo $sql["count"]; ? to output the count?
You need an alias name for your COUNT() column:
$sql = $connect->prepare("SELECT COUNT() AS num_events FROM discos_events e INNER JOIN discos_events_guests eg ON (e.ID = eg.eID) INNER JOIN users u ON (eg.uID = u.id) WHERE e.dID =:id");
$sql->bindValue(":id", $cID);
// Fetch the results and then access the alias
$sql->execute();
$result = $sql->fetch();
echo $result['num_events'];
you need to execute() the query, so:
$result = $sql->execute(array('id' => $cId)); // just to illustrate that you can use this instead of bindParam
if ($result) {
$row = $sql->fetch();
}
after execute, you have to store_result() and fetch()
As #Michael suggests, you may alias the count(), to get it in more reatable form.
Your query needs to assign the count value to a name, like so:
SELECT COUNT() n FROM discos_events ...
Then you can reference the name n in your PHP array:
echo $sql["n"];
You can, of course, call it 'count' or any other name you prefer, but be careful of using names which are reserved words in SQL (such as 'count'). If you want to give it a reserved name, you need to enclose it in backtick characters so that SQL recognises that it's a name you want to use rather than its own reserved word.

inner join wont work with mysqli prepared statement in 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 = ?"

Categories