Is it possible to invoke bind_param and execute iteratively, or must I prepare a statement at the beginning of each iteration?
$query = $db->prepare('...');
foreach ($dataItem as $item) {
$query->bind_param($v1, $v2, ..., $item);
$query->execute();
}
$query->close();
If I do have to recreate the statement each iteration, is it possible to optimize this process?
Thank you!
There is no need to prepare a statement at the beginning of each iteration.
The concept of prepared statements is to reuse the same statement multiple times in the first place, so it's good to go to prepare once and execute it multiple times.
See also this note on the manual page.
Related
I want to return all information on the offers table.
$sth = $mysqli->prepare('SELECT * from offers');
$sth->execute();
$resultex = $sth->fetch();
$sth->close();
return json_encode($resultex);
But this doesn't work. How do I do that with prepared statement in mysqli?
I do not want to use PDO in this case.
fetch and friends return a single row of the result set. Also, fetch uses bind variables, so you need a different scheme for obtaining your results. get_result and fetch_array will most likely work for you.
You need to loop over the rows, something like this:
$sth->execute();
while ($row = $sth->fetch_array(MYSQLI_NUM))
{
foreach ($row as $r)
{
/* do your json encoding for the present row */
}
}
$sth->close();
You probably need to bind your results to variables. See the documentation here. You'll need to do something like this:
/* bind result variables */
$sth->bind_result($var1, $var2, $var3);
while ($sth->fetch()) {
$intermediateVariable[] = array($var1, $var2, $var3);
}
Let's set this straight, a few things:
You don't need to use a prepared statement in this case!
Prepared statements are great when you have parameters. The golden rule: If you have variables in your query (even if they're constant, mind you), you need prepared statements. If you don't have them, you don't need prepared statements.
You want all of the information, but you only fetch once
mysqli_statement::fetch() will only fetch one row. If you want more, you need to use a while loop.
You are returning but it doesn't look like you're in a function
Are you? return doesn't output anything. So outside of a function/method scope, you won't get anything out of return in that context.
i am using prepared statements in my project in php, on localhost it work fine but on server i t stops rendering page in the middle. i saw one error like this when i was executing nested queries on single statement and fixed that using 2 statements but this time i am executing 3 independent sql queries on single statement and still it stucks in last query...
all queries are independent i mean queries are not nested.
how should i fix it?
here is the last query
if($stmt->prepare("sql"))
{
$stmt->bind_param("s", $material);
$stmt->bind_result($mid, $subject, $title);
$stmt->execute();
if($stmt->fetch()){ // do something}
}
After a long time i faced the same problem once again and solved it simple by executing my prepared statement first and then binding the result like:
if($stmt->prepare("sql query goes here"))
{
$stmt->bind_param("s", $material);
$stmt->execute();
$stmt->bind_result($mid, $subject, $title);
if($stmt->fetch()){ // do something}
}
hope this will help someone else too.
I was researching about mysqli prepared statements and i have 2 questions about it.
As i was reading, i figure out that the order of execution of a prepared statement looks something like the following:
$sql = 'SELECT image_id, filename, caption FROM images WHERE image_id = ?';
// connect to the database
$conn = ....
$stmt = $conn->stmt_init();
$stmt->prepare($sql);
$stmt->bind_param('i', $id);
$stmt->execute();
$stmt->bind_result($image_id, $filename, $caption);
// optional: get total of records in the result set
$stmt->store_result();
$numRows = $stmt->num_rows;
// loop through the result set
while ($stmt->fetch()) {
// code goes here...
}
or
// fetch the result for one record
$stmt->fetch()
// free & close
$stmt->free_result();
$stmt->close;
$conn->close();
Here's my first question:
As i was reading, it also mentions the following:
If you don't bind the result to variables, use $row = $stmt->fetch(), and access each variable as $row['column_name']. So,
Are they any pros/cons using either of the 2 methods to loop the result set?
If there's no difference, then why bother binding the result using $stmt->bind_result in the first place? What's the point if i can use $row = $stmt->fetch() instead?
Here's my other question:
$stmt->free_result(); frees what exactly? the prepare() or the store_result() or else ?
$stmt->close; what am i closing exactly? the stmt_init() or the prepare() or else?
Hopefully your answers will make me understand better prepared statements so i can build something safe...
Thanks
$stmt->free_result() does pretty much what the name says: it frees the memory associated with a result.
$stmt->close closes the statement handle (the cursor actually), making it impossible to loop through the result set (again).
Although the manual states: 'You should always free your result with mysqli_free_result(), when your result object is not needed anymore', common practice is not to use free_result and close on a statement. When closed you cannot use the result set anymore, or reuse it and when php dies, memory is freed anyway.
I'm writing a database class for my website with functions such as fetchOne, fetchAll which prepare, execute (+ bind), and fetch the query all in one so I don't have to individually call those functions every time. Some cron jobs on my site execute thousands, or even millions of queries inside of a loop.
Would using my class cause the statement to be re-prepared each iteration of the loop or would PDO "remember" the query has already been prepared? Would this significantly impact performance and if so could the solution be to just provide a function that passes the database instance and do something like $db->getDb()->prepare($query); outside of the loop? Or is there a better solution?
Example function:
public function fetchOne($query, $params = array(), $fetchMode = PDO::FETCH_ASSOC)
{
$stmt = self::prepareExecute($query, $params);
$result = $stmt->fetch($fetchMode);
if (count($result) < 1)
$result = FALSE;
$stmt->closeCursor();
unset($stmt);
return($result);
}
you would not want to "re-prepare" the same query multiple times. this is the purpose of the prepare statement. you prepare it once, bind the variable(s), then you simply switch the variables' values and re-execute each iteration of the loop.
http://www.php.net/manual/en/pdostatement.bindparam.php
doing it this way will greatly increase your performance over alternative methods.
I'm just getting to implement PDO in my site but I was wondering if it is possible to execute prepared statement multiple times?
$SQL = $dbh->prepare("SELECT * FROM user WHERE id=? AND users=?");
$SQL -> execute(array($id,$userid));
while($check = $SQL -> fetchObject()){
and then I would use a while loop for this SQL
Can I use the same $SQL for another execution within the while loop? So I don't have to type in the prepared statement again?
$SQL -> execute(array($id2,$userid2));
while($check2 = $SQL ->fetchObject(){
//while loops for second execution, but I'm not sure how it works cause
//its using the same $SQL?
}
}//this end bracket is for the first while loop
Yes, you can reuse the same prepared statement, but not how you have it in the question. What you are trying to do is essentially the same as doing this:
for ($i=0; $i<$some_number; $i++) {
echo $i."\n";
for ($i=0; $i<$some_number; $i++) {
// do something
}
}
The the second for loop moves the same pointer as the original one, so therefore the output from the above would simply be "0" indicating that the original for loop only happened once.
So in order to get around this, you will need to store the results of the first execute into an array and then iterate over it. That way you won't have to worry about any pointers
$SQL = $dbh->prepare("SELECT * FROM user WHERE id=? AND users=?");
$SQL->execute(array($id,$userid));
$checks = $SQL->fetchAll();
foreach ($checks as $check) {
$SQL->execute(array($id2,$userid2));
while ($check2 = $SQL->fetchObject(){
//while loops for second execution
}
}
This way, you are using exactly the same prepared statement (which is good) and the original $check variable is available to be used in the while loop.
However, with all that said, I have a strong hunch that you can probably get everything into one single SQL query without the need for looping over it like this.
Yes, it is possible. Prepare once, execute as many times as you need to.
Of course, I'm not sure why you're doing a SELECT in a loop... that typically doesn't make much sense.