two mysqli querys, one in a while loop - php

Can't seam to find the answer to this.
I have a mysqli loop statement. And in that loop I want to run another query. I cant write these two sql together. Is that possible?
I thought since I use stmt and set that to prepare statement. So i add another variable stmt2. Running them seperate works, but run it like I wrote it gives me "mysqli Fatal error: Call to a member function bind_param() on a non-object"
Pseudocode :
loop_sql_Statement {
loop_another_sql_statement(variable_from_firsT_select) {
echo "$first_statement_variables $second_statemenet_variables";
}
}
$sql = "select dyr_id, dyr_navn, type_navn, dyr_rase_id, dyr_fodt_aar, dyr_kommentar, dyr_opprettet, dyr_endret
from dyr_opphald, dyr, dyr_typer
where dyropphald_dyr_id = dyr_id
and dyr_type_id = type_id
and dyropphald_opphald_id = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("i",
$p_opphald_id);
$stmt->execute();
$stmt->bind_result($dyr_id, $dyr_navn, $type_navn, $dyr_rase_id, $dyr_fodt_aar, $dyr_kommentar, $dyr_opprettet, $dyr_endret);
echo "<table>";
while($stmt->fetch()) {
echo "<tr><td>$dyr_navn</td><td>$type_navn</td><td>$dyr_rase_id</td><td>$dyr_fodt_aar</td><td>";
$sql2 = "select ekstra_ledetekst, ekstradyr_ekstra_verdi from dyr_ekstrainfo, ekstrainfo where ekstradyr_ekstra_id = ekstra_id and ekstradyr_dyr_id = ?";
try {
$stmt2 = $mysqli->prepare($sql2);
$stmt2->bind_param("i",
$dyr_id);
$stmt2->execute();
$stmt2->bind_result($ekstra_ledetekst, $ekstra_ledetekst);
echo "<td>";
while($stmt2->fetch()) {
echo "$ekstra_ledetekst => $ekstra_ledetekst<br>";
}
}catch (Exception $e) {}
echo "</td></tr>";
}
echo "</table>";
The answer:
Silly me, I didnt know I had to have two mysqli connection. So the solution was to declare another mysqli connection.
$mysqli = new mysqli($start, $name, $pwd, $selected_db);
$mysqli2 = new mysqli($start, $name, $pwd, $selected_db);

You should be able to do that, although you make have to start a second connection.

Related

Number of bound variables does not match number of tokens when using a custom PDO function

I tried the questions with similar titles, but they are all regular queries that are not in functions.
I am trying to create an update function in a Database class so I don't have to write out the entire process over and over. However, I am getting the error:
Invalid parameter number: number of bound variables does not match number of tokens
Here is my function.
public function updateRow($query, $params) {
try {
$stmt = $this->master_db_data->prepare($query);
foreach($params as $key => $val) {
$stmt->bindValue($key+1, $val);
$stmt->execute();
return true;
}
} catch(PDOException $e) {
die("Error: " . $e->getMessage());
}
}
And its usage:
$query = "UPDATE records SET content=?, ttl=?, prio=?, change_date=? WHERE id=?";
$params = array($SOA_content, $fields['SOA_TTL'], '1', $DATE_TIME, $id);
if($db->updateRow($query, $params)) {
echo "Success";
}
else {
echo "Fail";
}
Doing it without a function works:
$pdo = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8", $username, $password, $options);
$query = "UPDATE records SET content=:content, ttl=:ttl, prio=:prio, change_date=:change_date WHERE id=:id";
$stmt = $pdo->prepare($query);
$stmt->bindValue(":content", $SOA_content);
$stmt->bindValue(":ttl", $fields['SOA_TTL']);
$stmt->bindValue(":prio", 1);
$stmt->bindValue(":change_date", $DATE_TIME);
$stmt->bindValue(":id", $id);
$stmt->execute();
Am I wrong with my bindValue in the function? If so, how?
Always make sure your execute calls happen after all binding has been performed. In this situation, move the execute out of the binding loop.

Prepared Statement Return Get Results & Count

I am trying to get both the results of my query and the row count wihtout having to make two trips the the DB if possible. I am using prepared statements in a procedural way. My code is as follows:
$dbd = mysqli_stmt_init($dbconnection);
if (mysqli_stmt_prepare($dbd, "SELECT * FROM Contacts WHERE First_Name = ?" )) {
mysqli_stmt_bind_param($dbd, "s", $val1);
if (!mysqli_stmt_execute($dbd)) {
echo "Execute Error: " . mysqli_error($dbconnection);
} else {
//do nothing
}
} else {
echo "Prep Error: " . mysqli_error($dbconnection);
}
$result = mysqli_stmt_get_result($dbd);
So the above code works just fine and returns my results. What I want to do now is get the row count using this same statement but i don't want to have to write a brand new prepared statement. If I writer a separate prepared statement and use store_results and num_rows I get the row count but that would force me to have to write an entire new block of code and trip to db. I am trying to do something as follows but It throws and error:
$dbd = mysqli_stmt_init($dbconnection);
if (mysqli_stmt_prepare($dbd, "SELECT * FROM Contacts WHERE First_Name = ?" )) {
mysqli_stmt_bind_param($dbd, "s", $val1);
if (!mysqli_stmt_execute($dbd)) {
echo "Execute Error: " . mysqli_error($dbconnection);
} else {
//do nothing
}
} else {
echo "Prep Error: " . mysqli_error($dbconnection);
}
$result = mysqli_stmt_get_result($dbd);
mysqli_stmt_store_result($dbd);
$rows = mysqli_stmt_num_rows($dbd);
The throws and error as if i can't run both get results and store results using the same prepared statement. Im simply trying to keep my code compact and reuse as much as possible. If i break the above out into two separat prepared statements it works fine, Im just wondering there is a way to just add a line or two to my existing statement and get the row count. Or do i have to write an entire new block of code with new stmt_init, stmt_prepare, bind_param, execute, etc...
I tried your code (and reformatted it a bit), but I can't get it to work when I use both store_result() and get_result(). I can only use store_result then bind_result().
So the alternative is to fetch all the rows and then count them:
Example:
$sql = "SELECT * FROM Contacts WHERE First_Name = ?";
$stmt = mysqli_stmt_init($dbconnection);
if (mysqli_stmt_prepare($stmt, $sql) === false) {
trigger_error("Prep Error: " . mysqli_error($dbconnection));
return 1;
}
if (mysqli_stmt_bind_param($stmt, "s", $val1) === false) {
trigger_error("Bind Error: " . mysqli_stmt_error($stmt));
return 1;
}
if (mysqli_stmt_execute($stmt) === false) {
trigger_error("Execute Error: " . mysqli_stmt_error($stmt));
return 1;
}
$result = mysqli_stmt_get_result($stmt);
$rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
$num_rows = count($rows);
print "$num_rows rows\n";
foreach ($rows as $row) {
print_r($row);
}
In my opinion, PDO is much easier:
$pdo = new PDO("mysql:host=127.0.0.1;dbname=test", "xxxx", "xxxxxxxx");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$sql = "SELECT * FROM Contacts WHERE First_Name = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$val1]);
$num_rows = $stmt->rowCount();
print "$num_rows rows\n";
while ($row = $stmt->fetch()) {
print_r($row);
}

Looking for an alternative to get_result() [duplicate]

I am totally confused by mySQLi. Although I have been using procedural mysql calls for years, I want to get used to making prepared statements for the db security/mySQL injection protection it offers. I am trying to write a simple select statement (yes I know making a procedural call for this offers performance enhancement). When run, I get all the echoes until I hit the $result = $stmt->get_result(); component. It all seems fairly straightforward to me, but I am at a loss after hours of reading manuals on mySQLi. Any ideas why this would be failing?
*note: this is a test environment and while no sanitizing/escaping of characters is taking place, I am only passing valid content into the variables $username and $email. And also, I have looked all over SO to find the solution to my issue.
function checkUsernameEmailAvailability($username, $email) {
//Instantiate mysqli connection
#$mysqli = new mysqli(C_HOST,C_USER,C_PASS,C_BASE) or die("Failed to connect to MySQL database...");
if (!$mysqli)
{
echo 'Error: Could not connect to database. Please try again later...';
exit;
} else {
echo 'mysqli created';
}
/* Create a prepared statement */
if($stmt = $mysqli -> prepare("SELECT username,email FROM tb_users WHERE username=? OR email=?")) {
echo '<br />MYSQLi: ';
/* Bind parameters s - string, b - boolean, i - int, etc */
$stmt -> bind_param("ss", $username, $email);
echo '<br />paramsBound...';
/* Execute it */
$stmt -> execute();
echo '<br />Executed';
$result = $stmt->get_result();
echo '<br />Result acquired';
/* now you can fetch the results into an array - NICE */
$myrow = $result->fetch_assoc();
echo '<br />Fetched';
/* Close statement */
/$stmt -> close();
echo '<br />Done mysqli';
}
}
Also, do I have to instantiate a mysqli every time I call a function? I'm assuming they're not persistent db connects like in procedural mysql. Yes, I am aware this is a scope issue, and no I have not been able to understand the scoping of this class variable. When I declared it outside of the function, it was not available when I came into the function.
UPDATE
if I change line 12 from:
if($stmt = $mysqli -> prepare("SELECT username,email FROM tb_users WHERE username=? OR email=?")) {
to:
$stmt = $mysqli->stmt_init();
if($stmt = $mysqli -> prepare("SELECT username,email FROM tb_users WHERE username=? OR email=?")) {
if(!stmt) echo 'Statement prepared'; else echo 'Statement NOT prepared';
I get Statement NOT prepared. Now I'm even more confused....
UPDATE:
I contacted my hosting provider and apparently mySQLi is supported, and the mysqlnd driver is present. Perhaps there is a way to simply test this? Although they usually have given me pretty knowledgeable answers in the past.
UPDATE...AGAIN: I checked my server capabilities myself and discovered, while mysqli and PDO are present, mysqlnd is not. Thusly, I understand why get_result() will not work (mysqlnd required I think), I still don't understand why the prepared statement itself will not work.
Through some checking, even though mysqli is installed on my host, apparently the mysqlnd driver is not present. Therefore, get_result() can not be used(php manual defines get_result as mysqlnd dependent), and instead extra coding would need to be done to handle my result the way I would like.
Therefore, I decided to try and learn how PDO works, and within minutes, voila!!!
Replaced the above code with this:
function checkUsernameEmailAvailability($username, $email) {
echo 'pdo about to be created';
$dsn = 'mysql:dbname='.C_BASE.';host='.C_HOST;
$user = C_USER;
$password = C_PASS;
try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
$params = array(':username' => $username, ':email' => $email);
try{
$sth = $dbh->prepare('SELECT username,email FROM tb_users WHERE username = :username OR email = :email ');
} catch(PDOException $e) {
echo 'Prepare failed: ' . $e->getMessage();
}
try{
$sth->execute($params);
} catch(PDOException $e) {
echo 'Execute failed: ' . $e->getMessage();
}
$result = $sth->fetch(PDO::FETCH_ASSOC);
print_r($result);
}
As much error checking as I could think of, and no problems at all first crack at it!
Final Code
function checkUsernameEmailAvailability($username, $email) {
$dsn = 'mysql:dbname='.C_BASE.';host='.C_HOST;
$user = C_USER;
$password = C_PASS;
new PDO($dsn, $user, $password);
$params = array(':username' => $username, ':email' => $email);
$sth = $dbh->prepare('SELECT username,email FROM tb_users WHERE username = :username OR email = :email ');
$sth->execute($params);
$result = $sth->fetch(PDO::FETCH_ASSOC);
print_r($result);
}
mysqli_stmt :: get_result is Available only with mysqlnd package. remove php5-mysql package and install php5-mysqlnd instead

Unable to return database query results

I'm at the early stages of incorporating a search facility on a website, but I've hit a stumbling block. At the moment, I'm just doing some testing, using jQuery AJAX, but the problem definitely lies in my php:
...
$searchq = $_POST['searchq'];
$output = '';
$db = new PDO($dsn, $mysqluser, $mysqlpass, array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
function getData($db){
// Prepare resource query statement
$stmt = $db->query("SELECT * FROM mod_site_content WHERE alias = ':searchq'");
// Bind paremeters
$stmt->bindParam(':searchq', $searchq, PDO::PARAM_STR);
// Execute query
$stmt->execute();
// Grab result
$output = $stmt->fetchAll();
// Return output
done($output);
};
try {
getData($db);
} catch(PDOException $e){
echo $e->getMessage();
}
function done($out){
echo $out;
}
At the moment I'm just passing the results to console.log() in my AJAX .done() method. The above outputs "Array" with nothing in it, regardless of whether I search for something that should be there or not.
If I change the above slightly to:
function getData($db){
...
$output = $stmt->fetchAll();
$result = implode($output,"--");
// Reture output
done($result);
};
I get nothing back whatsoever.
mod_site_content looks like this:
id | type | alias
-------------------------
1 | document | home
2 | document | projects
...
Thanks.
Your issue is here:
$stmt = $db->query("SELECT * FROM mod_site_content WHERE alias = ':searchq'");
replace it by this:
$stmt = $db->prepare("SELECT * FROM mod_site_content WHERE alias = :searchq");
PDO variable i.e. :searchq shouldn't be surrounded by ' or else PDO will consider them as strings, your code should be giving an error when you try to bind searchq
Additionally notice that I used the prepare() not query(), you need to prepare the query first, then bind params then execute
third issue, you should pass $searchq to your getData function
I copied and pasted your code here, and edited, just to clear my head, can you please test it and tell me if it works?
$searchq = $_POST['searchq'];
$output = '';
$db = new PDO($dsn, $mysqluser, $mysqlpass, array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
function getData($db, $searchq){
// Prepare resource query statement
$stmt = $db->prepare("SELECT * FROM mod_site_content WHERE alias = :searchq");
// Bind paremeters
$stmt->bindParam(':searchq', $searchq, PDO::PARAM_STR);
// Execute query
$stmt->execute();
// Grab result
$output = $stmt->fetchAll();
// Return output
done($output);
};
try {
getData($db, $searchq);
} catch(PDOException $e){
echo $e->getMessage();
}
function done($out){
if(is_array($out)){
print_r($out);
} else {
echo $out;
}
}
echo json_encode($out) and make sure you are expecting a json object on the browser.
No idea offhand why imploding the return value and echoing it out failed to return anything, unless ->fetchAll doesn't return an actual array according to implode, in which case it should be kicking out an error somewhere...

Can't use database connection while inside loop

I am having a problem with mysqli. I am trying to search a database for all people who meet a category. While looping through the results, I want to create an instance of a "Person" class, passing the database connection to the class. This is where the problem starts. Here is my code.
$con = new mysqli($db_host,$db_user,$db_password,$db_name);
if (mysqli_connect_errno())
{
die(mysqli_connect_error()); //There was an error. Print it out and die
}
$sql = "SELECT id FROM users";
$stmt = $con->prepare( $sql );
if ($stmt)
{
$stmt->execute();
$stmt->bind_result($id);
while($stmt->fetch())
{
$person = new Person( $con );
}
$stmt->close();
}
If i move the $person = new Person( $con ); to just after the while loop, it successfully makes an object of the last person. It just won't work when inside the loop. What is the reason for this?
According to error shown, you can't use the same connection until previous result set is in use. In order to make it work, you can do something like this:
$personIDs = array();
while($stmt->fetch())
{
$personIDs[] = $id;
}
$stmt->close();
and than just go through all ids buffered into array:
foreach($personIDs as $id) {
$person = new Person( $con );
}
Or, you can use store_results
if ($stmt)
{
$stmt->execute();
$stmt->bind_result($id);
$stmt->store_results();
while($stmt->fetch())
{
$person = new Person( $con );
}
$stmt->free_result();
$stmt->close();
}

Categories