mysql prepared fetch loop, wont use connection for looped stmt - php

Thanks to anyone who is willing to help. I am trying to run a sql SELECT in a fetch loop of another select loop.
$mysqli = connect();
$stmt= $mysqli->prepare('SELECT lobby_id, user_penName, lobby_str
FROM `tbl_lobbies`
JOIN tbl_users ON tbl_lobbies.user_id = tbl_users.user_id
WHERE lobby_active = ?');
$stmt->bind_param('i',$on);
$stmt->execute();
$stmt->bind_result($lid, $hostName, $str);
while($stmt->fetch()){
$users=0;
$on = 1;
//echo $lid;
$stmt2= $mysqli->prepare('SELECT `user_id` FROM `tbl_usersInLobbies` WHERE lobby_id = ?');
$stmt2->bind_param('i', $lid);
echo 1;
$stmt2->execute();
$stmt2->bind_result($users);
while($stmt2->fetch()){
echo 1;
$nou .= '&nbsp<i class="fa fa-square" aria-hidden="true"></i>';
}
$stmt2->close();
This code only works if I open another connection in the loop. I know that isnt effective so im trying to see if there is another way. I know there is no variable errors in the code. I would use another form of sql in there is no other option.
PS im still a student so im sorry for any obvious answers.

Use just 1 SQL query, something like this:
SELECT tbl_lobbies.lobby_id, tbl_lobbies.user_penName, tbl_lobbies.lobby_str, tbl_usersInLobbies.user_id
FROM `tbl_lobbies`
JOIN tbl_users ON tbl_lobbies.user_id = tbl_users.user_id
LEFT JOIN `tbl_usersInLobbies` ON tbl_usersInLobbies.lobby_id = tbl_lobbies.lobby_id
WHERE lobby_active = ?

Related

php sqlite3 - get result from prepared statement

All the examples and documentation didnt really help or even offer an example for this so I m gonna ask here:
$db = new SQLite3(database.db);
$stmt = $db->prepare('SELECT COUNT(uid) FROM kunden WHERE date = :date');
$stmt->bindValue(':ldate',$today,SQLITE3_TEXT);
$result = $stmt->execute;
How can I get the result from that prepared statement? I know execute is not supposed to return a result. I tried using query and query_single but that didnt work. var_dump($result->fetchArray()); also didnt work. Help is much appreciated.
SQLite3Stmt::execute() is a function, and needs to be called as such:
$db = new SQLite3('database.db');
$stmt = $db->prepare('SELECT COUNT(uid) FROM kunden WHERE date = :date');
$stmt->bindValue(':ldate',$today,SQLITE3_TEXT);
$result = $stmt->execute();
You can then fetch the result like this:
$array = $result->fetchArray();
echo $array['COUNT(uid)'];

PHP prepared statement loop JOIN query not working

I am trying to gather some variables from my query then output them using $stmt->bind_result() however I am not getting any rows returned in my search.
I am not sure what is going wrong here?
$tag = trim($_GET['tag']);
$stmt = $mysqli->prepare('SELECT trips.trip_id FROM trips JOIN tags ON trips.post_id = tags.post_id WHERE tag = ?');
$stmt->bind_param('s', $tag);
$stmt->execute();
$stmt->bind_result($id);
while ($stmt->fetch()) {
echo $id;
}

Prepared statement, loop results to get more results

I have a query where I'm taking several results from a single table. I then need to loop through each result to get information from other tables, however, I can't get it to work.
Here's my code:
<?php
$type = 1;
if ($stmt = $cxn->prepare('SELECT username FROM users WHERE type = ?')) {
$stmt->bind_param('i', $type);
$stmt->execute();
$stmt->bind_result($username);
while ($stmt->fetch()) {
if ($stmt = $cxn->prepare('SELECT count FROM posts WHERE username = ?')) {
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->bind_result($result2);
$stmt->close();
}
}
$stmt->close();
}
?>
I get an error:
Call to a member function fetch() on a non-object
How do I fix this?
I would highly recommend a native SQL JOIN for this because it will avoid unnecessary overhead in sending potentially thousands of queries:
SELECT
u.username,
p.count
FROM
users u
LEFT JOIN // processed as LEFT OUTER JOIN so the syntax is interchangeable just fyi
posts p
ON u.username = p.username
WHERE
p.type = ?
Explaining LEFT JOIN only, we'll keep it simple =)
In the SQL above we start with username from the users table as a whole
users u just grants us the shortcut syntax for u.username so that SQL is readable and doesn't fubar
Next we want to attach the posts p table where u.username = p.username because we need the p.count for each username
Lastly we filter this conglomerate of data based on p.type being equal to something
Please note that are many things at play here depending on the DBMS. Such things include query optimizers, the exact point of filtering, etc... but that is far outside the scope of simply getting the hang of what we are trying to achieve conceptually so I will not go into detail because it will only cause confusion.
You are overwritting your stmt variable. You should use another one, like
$type = 1;
if ($stmt = $cxn->prepare('SELECT username FROM users WHERE type = ?')) {
$stmt->bind_param('i', $type);
$stmt->execute();
$stmt->bind_result($username);
while ($stmt->fetch()) {
if ($stmtCnt = $cxn->prepare('SELECT count FROM posts WHERE username = ?')) {
$stmtCnt->bind_param('s', $username);
$stmtCnt->execute();
$stmtCnt->bind_result($result2);
$stmtCnt->close();
}
}
$stmt->close();
}

Using two queries at the same time. PDO

Okay so, I don't really know anything about PDO, my friend just asked me to post this here since he's not very good at English. Anyway, this is how he explained it to me:
The code provided is supposed to get a couple of values, save them, and it's supposed to get something out of another table with the help of the values gotten from earlier. The problem according to my friend is that it doesn't get the second value.
Code:
$user_email = $_SESSION['user_email'];
$query = $db->prepare("SELECT username,id,password FROM user WHERE email=:email");
$query->bindParam(':email', $user_email, PDO::PARAM_INT);
$query->execute();
$row = $query->fetch();
$user_username=$row['username'];
$user_group=$row['group'];
$query_group = $db->prepare("SELECT color,name FROM group WHERE id=:id");
$query_group->bindParam(':id', $user_group, PDO::PARAM_INT);
$query_group->execute();
$row = $query_group->fetch();
$group_color=$row['color'];
$group_name=$row['name'];
The word group used as a table name needs to be enclosed in backticks. group is a reserved key word (GROUP BY clause).
SELECT
color,
name
FROM `group`
WHERE id = :id
Using the above would work.
You can shorten the entire code by using a JOIN clause too. As commented above by Prix, the code shall be:
$user_email = $_SESSION['user_email'];
$query = $db->prepare("SELECT
u.username,
u.id,
u.password,
g.color,
g.name
FROM user u
JOIN `group` g
ON g.id = u.id
WHERE u.email = :email");
// I think emails are supposed to be `PDO::PARAM_STR`
$query->bindParam(':email', $user_email, PDO::PARAM_INT);
$query->execute();
$row = $query->fetch();
$user_username = $row['username'];
$group_color = $row['color'];
$group_name = $row['name'];
You don't have group in your select statement .
If you don't use * in your select you must have the field name in your query .
$query = $db->prepare("SELECT username,id,password FROM user WHERE email=:email");
This query gives you only username,id,password back NOT the field group .
so try to use $row['group'] is wrong .
$user_group=$row['group'];
So also put group in your select statement
Place also group in backticks it's a reserved word
$query = $db->prepare("SELECT id, username, password, `group` FROM user WHERE email=:email");
This is also a reason for important variables (e.g for next query) to consider their validity.
if (isset($row['group'])) {
database logic
} else {
error
}
With this simple test you would have found the error itself.

Multiple prepared statements (SELECT)

I'm trying to change my SQL queries with prepared statements.
The idea: I'm getting multiple records out of the database with a while loop and then some additional data from the database in the loop.
This is my old SQL code (simplified):
$qry = "SELECT postId,title,userid from post WHERE id='$id'";
$rst01 = mysqli_query($mysqli, $qry01);
// loop trough mutiple results/records
while (list($postId,$title,$userid) = mysqli_fetch_array($rst01)) {
// second query to select additional data
$query05 = "SELECT name FROM users WHERE id='$userid";
$result05 = mysqli_query($mysqli, $query05);
$row05 = mysqli_fetch_array($result05);
$name = $row05[name ];
echo "Name: ".$name;
// do more stuff
// end of while loop
}
Now I want to rewrite this with prepared statements.
My question: is it possible to run a prepared statement in the fetch of another prepared statement ? I still need the name like in the old SQL code I do for the $name.
This is what've written so far.
$stmt0 = $mysqli->stmt_init();
$stmt0->prepare("SELECT postId,title,userid from post WHERE id=?");
$stmt0->bind_param('i', $id);
$stmt0->execute();
$stmt0->bind_result($postId,$title,$userid);
// prepare second statement
$stmt1 = $mysqli->stmt_init();
$stmt1->prepare("SELECT name FROM users WHERE id= ?");
while($stmt0->fetch()) {
$stmt1->bind_param('i', $userid);
$stmt1->execute();
$res1 = $stmt1->get_result();
$row1 = $res1->fetch_assoc();
echo "Name: ".$row1['name'] ;
}
It returns an error for the second statement in the loop:
Warning: mysqli_stmt::bind_param(): invalid object or resource mysqli_stmt in ...
If I use the old method for the loop and just the prepared statement to fetch the $name it works.
You can actually do this with a single JOINed query:
SELECT p.postId, p.title, p.userid, u.name AS username
FROM post p
JOIN users u ON u.id = p.userid
WHERE p.id = ?
In general, if you are running a query in a loop, there is probably a better way of doing it.

Categories