Stored procedure causes "Commands out of sync" on the next query - php

I am running a query with a mysql stored procedure :
$AddProf_qr = mysql_query("call AddStudent('$d_Pass', '$d_Titl', '$d_Firs', '$d_Midd', '$d_Last', '$d_Addr', '$d_City', '$d_Stat', '$d_County', '$d_Zipc', $d_Gend, '$d_Birh', '$d_Phom', '$d_Phoh', '$d_Phoo', '$d_Email', '$d_Webs', '$d_Natn', '$d_Profsn', '$d_Compny', '$d_Desig', $d_ProfAcc)", $this->c_remote) or die ("first call" . mysql_error($this->c_remote));
I am supposed to get just one result from the call : ##IDENTITY = a number;
$AP_result = mysql_fetch_array($AddProf_qr);
$CurrentSID = $AP_result['##IDENTITY'];
which works fine. but when i run another mysql update query right after this, it gives an error saying :
Error: 2014 (CR_COMMANDS_OUT_OF_SYNC)
Message: Commands out of sync; you can't run this command now
i have tried inserting :
mysql_free_result($AddProf_qr);
but still the same.
The MySQL call executes fine also
the rest of the script runs without issues the above is commented out. but they don't run at the same time. My best guess is, the call is doing something that's messing this up.

Your stored procedure is returning multiple resultsets. See this post
Solution?
Use mysqli_multi_query
Stop using the ancient mysql library - the i in mysqli stands for "Improved" - with good reason.

#DMin Yes that's would work, but you'll crash the server sooner or later.
Just make the math, one resquest to a page that makes 3 * number of procedures to database!
Just think about it!
[UPDATE] solution:
$aCategory = array();
$it=0;
$res = $mysqli->multi_query( "call ListCategory();" );
if( $res ) {
do {
if ($result = $mysqli->store_result()) {
while( $row = $result->fetch_row() ) {
$aCategory[$it] =$row;
$it= $it + 1;
}
$result->close();
}
} while( $mysqli->next_result() );
}
foreach($aCategory as $row){
echo . $row[0] . " - " . $row[1] . "<br />";
}
Just wanted to add that you are ready to call the next Routine.
PS: By this way I couldn't use
echo $aCategory['category_id'] ;
//or
echo $aCategory->category_id;
//just
echo $aCategory[0]

Check out here: http://us3.php.net/manual/en/function.mysql-query.php In comments, one guy claims that he made it work by setting connection flag to MYSQL_MULTI_RESULTS (131072).
But it would be much better to use mysqli...

mysql_free_result(client->res);
while (mysql_more_results(client->conn))
{
mysql_next_result(client->conn);
}
This did the charm for me :)

Result sets returned from a stored procedure cannot be fetched correctly using mysqli_query(). The mysqli_query() function combines statement execution and fetching the first result set into a buffered result set, if any. However, there are additional stored procedure result sets hidden from the user which cause mysqli_query() to fail returning the user expected result sets.
Result sets returned from a stored procedure are fetched using mysqli_real_query() or mysqli_multi_query(). Both functions allow fetching any number of result sets returned by a statement, such as CALL.
look at official manual

Related

mysqli_affected_rows return -1 but update query is successful

I have a page of php code take user's new password string to change user password and after some validation code send to process page for update record in users table. after sending new password string to process page and doing the update query, mysqli_affected_rows return -1 but update query was successful and password was changed Or If previous password string was the same previous password, update query does not make any changes but still returns -1.
I use mysqli functions in all of my codes.
db_conncet_fnc(),db_query_func(),db_fetch_assoc_func(),... These functions include the same mysqli functions.
my proccess page code is this:
$link_con=db_conncet_fnc();
require_once("PassHash.php");
$query = "SELECT * FROM mdr WHERE m_id='$md_id'";
$result = db_query_func($query);
$affecteds= mysqli_affected_rows($link_con);
$_SESSION["affecteds"]=$affecteds; //this is for test before UPDATE query
$_SESSION["affected-s-oop"]=$link_con->affected_rows; //this is for test before UPDATE query
$rec = db_fetch_assoc_func($result);
$p_hasher = new PassHsh(25, FALSE);
$ans = "2"; //answer without error is 2
if($rec)
{
if ($pass != "" && $newpsw != "" && $check = $p_hasher->checkpss($newpsw, $rec["userpass"])) {
if ($chngpsw_err < 2) {
$_SESSION["chngpsw_err"] = "has";
}
$_SESSION["pass_nwpass_is_equal"] = "yes";
header("location:index.php?page=chngpass");
exit();
} elseif ($check = $p_hasher->checkpss($pass, $rec["userpass"])) {
$hashed_psw = $p_hasher->HashPassword($newpsw);
$query = "UPDATE `mdr` SET `userpass`='$hashed_psw' WHERE m_id='" . $md_id . "' ";
$result = db_query_func($query);
$affect_upd = mysqli_affected_rows($link_con);
$_SESSION["affect_upd"] = $affect_upd; //by function
$_SESSION["affect_upd-oop"] = $link_con->affected_rows; //by object
if ($affect_upd == 0) {
$_SESSION["update_result"] = "err0";
header("location: index.php?page=chngpass");
exit();
}
if ($affect_upd == -1) {
$_SESSION["update_result"] = "err-1";
header("location: index.php?page=chngpass");
exit();
}
if ($affect_upd > 0) {
$_SESSION["update_result"] = "ok";
header("location: index.php?page=chngpass");
exit();
}
} else {
$ans = "1";
header("location: index.php?page=chngpass&ans=$ans");
}
}
I found some questions about this in stackoverflow and google and discussed about bug in mysqli with xdebug like this https://bugs.php.net/bug.php?id=67348 but I dont use $connect->stat and some pages wrote about bug in mysqli for every where xdebug is enabled, So I disable xdebug in php.ini but mysqli_affected_rows return -1 in all states and events, and all positions yet.
I used Google Chrome for debugging with phpstorme before.
Should I disable something in Chrome?
update:(2018/08/01):
After a few days searching on various sites by Google and searching in stackoverflow and doing the steps and suggestions written, I couldnt solve it.
A person named "siddharaj solanki" wrote in this question:
mysqli_affected_rows creates new connection (read details)
wrote:
Now the problem is I don't understand how to pass database link
($link) in mysqli_affected_rows() function. I tried above, but it
seems to create a new database connection, so mysqli_affected_rows
returns 0 instead of 1.
So I think the bug will not easily solve for this function based on my research and this link:
https://www.google.com/search?q=bug+mysqli_affected_rows
please guide me whats solution or what is good or best way instead of mysqli_affected_rows to check update query?
good time
Please help me to resolve that.
thanks.
The comments above do explain what's wrong, but I'll summarize here and mark this a community wiki answer.
Your code creates a connection to the database, but you said your db_query_func() function creates a separate connection to the database to run the query.
The affected-rows count can only report the rows affected by a query in the same connection. But you executed the UPDATE in a different connection.
Consider this analogy: you open two separate ssh sessions to a remote server. You run a command in one shell, and then in the other shell you use !! to repeat the command. The second shell has no idea of the command history from the first shell, so it can't repeat the same command.
You need to use the same database connection to execute the query and then report the rows-affected. Maybe the comments above did not make this clear, but you can solve this by passing the connection to your query function:
$result = db_query_func($link_con, $query);
Within that function, do not create a new mysqli connection, but use the connection that you passed as an argument.
Then when it returns, it has the proper context so you can get the mysqli_affected_rows($link_con) from the same connection.
There are other alternative solutions possible:
It's not clear why you need the db_query_func() at all. Perhaps you should just call mysqli_query() from your main code.
Or else db_query_func() should call mysqli_affected_rows() itself, and return the value.

MySQL resource, fetch(), and looping

i had a headache over the last few days trying to understand this snippet of code. it's about retrieving data from a database table nothing hard (i'm using mysql) . but i'm trying to understand the code. here is the code:
<?php
include 'PDOconnect.php';
//Query
$result = $connection->query('SELECT * FROM video_games');
//Fetch
$data = $result->Fetch();
while ($data = $result->Fetch()) {
echo $data['name']."<br />";
}
?>
first let me explain, the second line is including the connection code to the database i'm using the PDO way of connecting. the connection is fine . my table is called video_games and it had a column called 'name'. and i'm trying with this code to retrieve all the data from the column 'name'.
1- so what i want to understand is what is the $result variable (line 6) , i've heard it's a Resource. what a resource in mysql means, and what's inside of the variable $result is it the whole table or what exactly ??
2- what the function fetch() does ?? it's confusing .
3- what i know from studying the basic syntax of php is that inside the while condition
the value must be true in order to execute the code inside.
but here there is ($data = $result->Fetch()) .
4- is the fetch() method automatically incremented ?? i mean why it is working successfully inside the while condition, so it must be incrementing over and over again ??
please help my mind is blowing right now.
$result is not a Resource,. it's a PDOStatement. see the docs: http://www.php.net/manual/en/pdo.query.php
Once a PDOStatement is executed (automaticalyl using ->query()) the statement holds the result the database returned.
Everytime you ->fetch() it returns the current row the Statement is pointing to. After that it points it pointer to the next row (so yes, 'automatically incremented).
Now, your code:
Everything inside if and while statements is evaluated using loose comparision (==)
if ( $a ) actually checks or $a == true.
$data = $result->fetch() simply sets a value to $data. Then the while checks or $data == true. IF so, it does what it has to do. (see php == vs === operator for more about comparisons in php)
Now, a little remark on your code: the first row is not outputted since you don't do anything with the first fetched result. Simply remove
//Fetch
$data = $result->Fetch();
So your code would become:
<?php
include 'PDOconnect.php';
//Query
$result = $connection->query('SELECT * FROM video_games');
while ($data = $result->Fetch()) {
echo $data['name']."<br />";
}
A good tutorial about PDO: http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/
1 what is the $result variable
It is not a resource. It's actually an object of PDOStatement class
2 what the function fetch() does ?? it's confusing.
A manual page is always at your service. Just type PDO fetch in the browser's address bar and click the first link opened. It is extremely easy and no less powerful.

Function query won't execute

Why won't this query work?!?
Error
Parse error: syntax error, unexpected T_STRING in E:\xampp\htdocs\pf\shop\buy.php on line 5
Example Info For Variables
$character->islots = 20
$chatacter->name = [RE] Tizzle
$e2 = 10
The Function
function increaseSlots($e2) {
$slots = ($character->islots)+($e2);
mysql_query('UPDATE `phaos_characters` SET `inventory_slots`="'.$slots.'" WHERE `name`="'.$character->name.'"'); // <-- Line 5
if (mysql_affected_rows() != 0) {
echo 'Inventory Size Incresed By '.$e2.' Slots';
}else{
echo mysql_error();
}
}
Look at the docs: http://php.net/manual/en/function.mysql-num-rows.php
Retrieves the number of rows from a result set. This command is only valid for statements like SELECT or SHOW that return an actual result set. To retrieve the number of rows affected by a INSERT, UPDATE, REPLACE or DELETE query, use mysql_affected_rows().
You need to use mysql_affected_rows() or better yet, PDO or mysqli.
$slots = ($character->islots)+($e2);
Looks like there is a typo. Try:
$slots = ($character->slots)+($e2);
First off you should know that mysql_num_rows only returns a valid result for SELECT or SHOW statements, as stated in the PHP documentation. You can use mysql_affected_rows() for your particular needs.
However, the old PHP MySQL API (that you are using) is being phased out, so I would recommend using mysqli or PDO for your DB connection needs.
While keeping with your requirements, though, you can try to use the following syntax to make sure you receive the MySQL error if it throws one. Your PHP script will stop, but you will see the error.
$query = sprintf('UPDATE `phaos_characters` SET `inventory_slots`=%d WHERE `name`="%s"',$slots,$character->name)
$result = mysql_query($query) or die(mysql_error());
As a final idea, in situations like this it helps to print out your resulting $query and run it manually through something like phpMyAdmin to see what happens.
Bleh... I Found a better way to do it for the time being.. sorry to waste your guys' time...
I just threw the $character object into a variable before processing the function.
function increaseSlots($e2,$charname,$charslots) {
$slots = $charslots+$e2;
mysql_query('UPDATE `phaos_characters` SET `inventory_slots`="'.$slots.'" WHERE `name`="'.$charname.'"');
if (mysql_affected_rows() != 0) {
echo 'Inventory Size Incresed By '.$e2.' Slots';
}
}

Using mysql_fetch_assoc and mysql_result together?

I am having great trouble trying to use mysql_fetch_assoc and mysql_result together in the same PHP script.
Originally (when not utilizing the mysql_result function) I was getting the required database values using a combination of mysql_query and mysql_fetch_assoc and everything was fine. Then i added 2 lines into my code to obtain certain ‘title’ field values using mysql_result.
Now if i run my script as it is below i will only receive 1 result even though there are 2 result. Then if i move my do/while loop up so that it is between the other 2 blocks of code (mysql_fetch_assoc and mysql_result lines) i will receive the desired 2 results.
I need my loop to come after the mysql_result section so putting the loop before it is not an option.
// connect to DB and get values
mysql_select_db($database, $mywebsite);
$query_not_related_before = "SELECT * FROM table limit 2";
$not_related_before = mysql_query($query_not_related_before, $ mywebsite);
$row_not_related_before = mysql_fetch_assoc($not_related_before);
// Extract just the results from the title field (the problem area!)
$before_essayid4 = mysql_result($not_related_before,0, 'title');
$before_essayid5 = mysql_result($not_related_before,1, 'title');
// Display results etc
do {
echo "<br />".$row_not_related_before['title']."<br />";}
while ($row_not_related_before = mysql_fetch_assoc($not_related_before));
Plase help,
Many thanks,
David
I am unsure if this will solve your problem but I think you should "seek" the result back.
mysql_data_seek ($not_related_before, 0)
Also, check out the warning on the mysql_result page:
Calls to mysql_result() should not be
mixed with calls to other functions
that deal with the result set.
Hope this helps ;)
You get one row because the first already requested here:
$row_not_related_before = mysql_fetch_assoc($not_related_before);
So I think you have to move result pointer to beginning:
mysql_data_seek($not_related_before, 0);
// Display results etc
do {
echo "<br />".$row_not_related_before['title']."<br />";}
while ($row_not_related_before = mysql_fetch_assoc($not_related_before));
A simpler solution would be to use 2D array's, i have always found the mysql functions to be a little cumbersome.
<?php
$result = mysqli_query(db_connect(),$query);
$result_out = array();
if(#mysqli_num_rows($result))
while($row=mysqli_fetch_array($result,MYSQLI_ASSOC))$result_out[]=$row;
foreach($result_out as $row)
{
echo "<br />".$row['title']."<br />";
}
?>
hth

pg_query() seems to not execute queries in a loop

I'm converting a site from MySQL to Postgres and have a really weird bug. This code worked as-is before I switched the RDBMS. In the following loop:
foreach ($records as $record) {
print "<li> <a href = 'article.php?doc={$record['docid']}'> {$record['title']} </a> by ";
// Get list of authors and priorities
$authors = queryDB($link, "SELECT userid FROM $authTable WHERE docid='{$record['docid']}' AND role='author' ORDER BY priority");
// Print small version of author list
printAuthors($authors, false);
// Print (prettily) the status
print ' (' . nameStatus($record['status']) . ") </li>\n";
}
the FIRST query is fine. Subsequent calls don't work (pg_query returns false in the helper function, so it dies). The code for queryDB is the following:
function queryDB($link, $query) {
$result = pg_query($link, $query) or die("Could not query db! Statement $query failed: " . pg_last_error($link));
// Push each result into an array
while( $line = pg_fetch_assoc($result)) {
$retarray[] = $line;
}
pg_free_result($result);
return $retarray;
}
The really strange part: when I copy the query and run it with psql (as the same user that PHP's connecting with) everything runs fine. OR if I copy the meat of queryDB into my loop in place of the function call, I get the correct result. So how is this wrapper causing bugs?
Thanks!
I discovered that there was no error output due to having my php.ini misconfigured; after turning errors back on I started getting output, I got things like18 is not a valid PostgreSQL link resource. Changing my connect code to use pg_pconnect() (the persistent version) fixed this. (Found this idea here.)
Thanks to everyone who took a look and tried to help!

Categories