mysqli->query(); works sometimes - php

i have a kind of problems here and i don't know how to solve it... google said nothing and the search function here didn't shown me anything...
i use this code
$GAME_DB = new mysqli($__CONFIG['MySQL']['HOST'], $__CONFIG['MySQL']['USER'], $__CONFIG['MySQL']['PASS'], $__CONFIG['MySQL']['DB']['GAME']);
if($GAME_DB->connect_errno) { echo $GAME_DB->connect_error; exit; }
$VILLAGE_DATA['villageID'] = $mysqli->real_escape_string($VILLAGE_DATA['villageID']);
$query = "SELECT name, level, time FROM actions WHERE type='build' AND villageID='".$VILLAGE_DATA['villageID']."'";
if($result = $GAME_DB->query($query))
{
// table header
while($row = $result->fetch_row())
{
// some rows in here
}
// table footer
}
there aren't any syntax errors in that query and the results are there!
sometimes the query is successful and i see my table but sometimes (for example: when i reload) i receive the error message Commands out of sync; you can't run this command now
how can this just work "sometimes"? where is my problem?

http://dev.mysql.com/doc/refman/5.6/en/commands-out-of-sync.html
If you get Commands out of sync; you can't run this command now in
your client code, you are calling client functions in the wrong order.
This can happen, for example, if you are using mysql_use_result() and
try to execute a new query before you have called mysql_free_result().
It can also happen if you try to execute two queries that return data
without calling mysql_use_result() or mysql_store_result() in between.
But from the code you've posted I don't see how this could happen. Either there's more code than what you've posted and something there is happening out of order, or your MySQL connections are being improperly established/pooled/persisted somewhere outside of PHP.

Related

Codeigniter Commands out of sync; you can't run this command now

I've been spent hours trying to figure out how I'm supposed to get around this error in my scenario. I'm trying to run a few queries in sequence.
I have read: codeigniter : Commands out of sync; you can't run this command now, however I am not able to update /system/database/drivers/mysqli/mysqli_result.php
I've tried:
$this->db->reset_query();
$this->db->close();
$this->db->initialize();
$this->db->reconnect();
mysqli_next_result( $this->db->conn_id );
$query->free_result();
But they either give me the same error, or different errors which I will detail in the comments of my code.
The way my code is organized- I have a make_query method that takes a bunch of search options and figures out which tables to join and fields to search based on those. Sometimes, I just want to count results, sometimes I want all of the resulting data, sometimes I just want distinct values for certain fields or to group by certain fields. So I call make_query with my options, and then decide what to select afterwards. I have also been saving my query text to report, so that users can see what query is being run.
One interesting thing I have noted is that when I have no options set (ie there are no WHERE clauses in my SQL), I do not get this error and the multiple queries are able to run with no problem!
Here is my code:
//Get rows from tblPlots based on criteria set in options array
public function get_plot_data($options=array()){
$this->db->save_queries = TRUE;
log_message('debug','before make query 1 get plot data');
$this->make_query($options,'plot');
log_message('debug','after make query 1 get plot data');
$this->db->distinct();
//Now, set select to return only requested fields
if (!empty($options['fields']) and $options['fields']!="all" ){
//Because other tables could be joined, add table name to each select
array_walk($options['fields'], function(&$value, $key) { $value = 'tblPlots.'.$value;} );
$this->db->select($options['fields']);
}
if (!empty($options['limit']) and $options['limit']>0){
$this->db->limit($options['limit'], $options['offset']);
}
//Get the resulting data
$result=$this->db->get('tblProgram')->result();
$query_text = $this->db->last_query(); //tried removing this but didn't help
log_message('debug','query text '.$query_text);
$this->db->save_queries = FALSE;
//get the number of rows
//$this->db->reset_query();
//$this->db->close();
//$this->db->initialize();
//$this->db->reconnect();
//mysqli_next_result( $this->db->conn_id );
//$this->db->free_result(); //Call to undefined method CI_DB_mysqli_driver::free_result()
//$result->free_result(); //Call to a member function free_result() on array
log_message('debug','before make query 2');
$this->make_query($options,"plot");
$this->db->select('pkProgramID');
log_message('debug','before count results');
//this is where my code errors out trying to do the next step:
$count=$this->db->count_all_results('tblProgram');
}
I'm not including the code for make_query because it is long and calls other functions, but it runs successfully the first time and outputs the SQL query I would expect. If it would be helpful, I can include that code as well.
I'm not sure how to correctly call free_result() given that the CI documentation only gives an example using query('SQL QUERY') and I am building the query using Active Record, so I'm not sure how to use free result in my scenario? Maybe that's the issue?
$query2 = $this->db->query('SELECT name FROM some_table');
$query2->free_result();
Thank you for any help!
I ended up posting on a CI forum that suggested https://www.youtube.com/watch?v=yPiBhg6r5B0 which worked! Also I ended up having to join my tables differently to avoid timeouts (I think I was having trouble because I was using AJAX to call many queries asynchronously and one of them was timing out). Hope this helps someone!

Internal 500 server error in Codeigniter while using JOIN query Builder

I want to perform join on two table in codeigniter
Table 1: (registered_cname)
roll_no(int),name(varchar);
Table 2: (student_registered)
roll_no(int),status(varchar),company_name(varchar)
Query Code:
$this->db->select($table.'.roll_no,student_placement.stud_name,student_placement.status,student_placement.company_name');
$this->db->from($table);
$this->db->join('student_placement', $table.'.roll_no = student_placement.roll_no');
$this->db->where_in('student_placement.status',$dept);
$this->db->get();
To debug this you need to examine and test the generated SQL.
You can do so by adding the following to the end of your SQL...
echo $this->db->last_query(); // DEBUG
And you might need to add in an exit() to trap it depending upon your code.
echo $this->db->last_query(); // DEBUG
exit();
And look at the SQL and even copy and paste it into your SQL Tool like phpmyadmin and see what happens.
That will give you an indication of what isn't correct.
So you don't have DEBUG code appearing and cant remember where it is, you can modify the exit to be ( and this is only a suggestion) ...
echo $this->db->last_query(); // DEBUG
exit(__FILE__ .' '.__LINE__);
There are also __METHOD__ and __CLASS__ magic constants you can use as well, if you feel so inclined.

Prevent "Commands Out of Sync" error from MySQL stored procedure called via AJAX

I have a MySQL stored procedure that updates data across a set of tables (basically for one record in the principal table and related records in a set of child tables). It's called via AJAX through a PHP function. (That is, the AJAX call is to a PHP page, which ultimately calls this SP.) It was working fine, but now I'm trying to make it do one more thing and running into the "Commands out of sync; you can't run this command now" error.
The change is to store one more item in the principal table, but to do so may require adding an item to a child table (called ActionTopic). The page lets the user either choose from a dropdown or type in a new value. I've added two parameters to the SP: one is the PK chosen in the dropdown, the other is the new value typed in. In the SP, I've added the code below. It checks whether there was a new value typed in. If so, it calls another SP that checks whether the value typed in is already in the table and, if not, adds it. (I've tried with the code to check and add the record inline rather than in a separate SP and I have the same problem.)
if cNewTopic <> '' then
-- First, make sure the new topic isn't already there
call aoctest.AddActionTopic(cNewTopic);
-- SELECT #iTopicID := iID FROM ActionTopic WHERE UPPER(Description) = UPPER(cNewTopic);
SET #iTopicID = LAST_INSERT_ID();
else
SET #iTopicID = Topic;
end if;
The page works if the user makes a choice from the dropdown. The problem only occurs when the user types in a new value. Even when I get the error, everything else works as expected. The new value is added to the child table, and the parent table and other children are updated as expected.
Interestingly, if I call the SP in MySQL Workbench with the same parameters (after ensuring that the new value isn't in the new table), it runs without error. The only odd thing I've noticed is that I get two rows in the Output section of MySQL Workbench rather than one. Both show the call to the SP. The first shows "1 row(s) returned" and a period of time, while the second shows "0 row(s) returned" and "-/0.000 sec". A call to the SP in MySQL Workbench where the new value is already in the table also shows two rows in the Output section, but the second one shows "1 row(s) returned".
Not sure whether any of the other code is needed here. If you think I need to show more, please ask.
UPDATE: Based on the comment from Pete Dishman, I took a harder look at where the error is occurring. It's not the original SP call giving an error. It's the next call to MySQL, which is still inside the Ajax call.
The code processing the result already had this code:
//not sure why next line should be needed.
mysqli_next_result($conn);
I tried both simply doubling the call to mysqli_next_result (that is, two in a row) and putting it into a loop along the lines Pete suggested. With two calls, I still get the same error. With a loop, I wait 30 seconds and then get error 500: Internal server error.
UPDATE 2: I tried with a loop for mysqli_more_results() (similar to the one in Pete Dishman's reply) and echoing a counter inside the loop. The code brought my internet connection to a crawl and I finally had to break out of it, but there were dozens of iterations of the loop. Just tried the following:
mysqli_free_result($result);
$result = mysqli_store_result($conn);
mysqli_free_result($result);
if (mysqli_more_results($conn)) {
$result = mysqli_store_result($conn);
mysqli_free_result($result);
}
$allresult = getsubmissions($conn);
Found a noticeable delay before it failed.
Even if you can't tell me what's wrong, I'd appreciate ideas for how to debug this.
This may be because the stored procedure is returning multiple result sets (the two rows in workbench).
When querying from php you need to retrieve both result sets before you can send another query, otherwise you get the "commands out of sync" error.
The documentation seems to imply this is only the case when using mysqli_multi_query but we have it in our code when using mysqli_real_query.
Our query code is along the lines of:
mysqli_real_query($conn, $sql);
$resultSet = mysqli_store_result($conn);
while (!is_null($row = mysqli_fetch_array($resultSet, MYSQLI_BOTH)))
{
$results[] = $row;
}
mysqli_free_result($resultSet);
// Check for any more results
while (mysqli_more_results($conn))
{
if (mysqli_next_result($conn))
{
$result = mysqli_store_result($conn);
if ($result !== FALSE)
{
mysqli_free_result($result);
}
}
}
return $results;
The code would be different obviously if you're using PDO, but the same principle may apply (See http://php.net/manual/en/pdostatement.nextrowset.php)
I've solved my own problem by reworking the code that processes the result as follows:
if (mysqli_more_results($conn)) {
mysqli_free_result($result);
mysqli_next_result($conn);
$result = mysqli_store_result($conn);
mysqli_free_result($result);
if (mysqli_more_results($conn)) {
mysqli_next_result($conn);
$result = mysqli_store_result($conn);
if (!is_null($result) and gettype($result)!== 'boolean') {
mysqli_free_result($result);
}
}
}
$allresult = getsubmissions($conn);

Ajax calling memcache functions always querying Db

I'm experiencing a strange problem. I'm caching the output of a query using memcache functions in a file named count.php. This file is called by an ajax every second when a user is viewing a particular page. The output is cached for 5 seconds, so within this time if there will be 5 hits to this file i expect the cached result to be returned 3-4 times atleast. However this is not happening, instead everytime a query is going to db as evidenced from a echo statement, but if the file is called from the browser directly by typing the url (like http://example.com/help/count.php) repeatedly many times within 5 seconds data is returned from cache (again evidenced from the echo statement). Below is the relevant code of count.php
mysql_connect(c_dbhost, c_dbuname, c_dbpsw) or die(mysql_error());
mysql_select_db(c_dbname) or die("Coud Not Find Database");
$product_id=$_POST['product_id'];
echo func_total_bids_count($product_id);
function func_total_bids_count($product_id)
{
$qry="select count(*) as bid_count from tbl_userbid where userbid_auction_id=".$product_id;
$row_count=func_row_count_only($qry);
return $row_count["bid_count"];
}
function func_row_count_only($qry)
{
if($_SERVER["HTTP_HOST"]!="localhost")
{
$o_cache = new Memcache;
$o_cache->connect('localhost', 11211) or die ("Could not connect to memcache");
//$key="total_bids" . md5($product_id);
$key = "KEY" . md5($qry);
$result = $o_cache->get($key);
if (!$result)
{
$qry_result = mysql_query($qry);
while($row=mysql_fetch_array($qry_result))
{
$row_count = $row;
$result = $row;
$o_cache->set($key, $result, 0, 5);
}
echo "From DB <br/>";
}
else
{
echo "From Cache <br/>";
}
$o_cache->close();
return $row_count;
}
}
I'm confused as to why when an ajax calls this file, DB is hit every second, but when the URL is typed in the browser cached data is returned. To try the URL method i just replaced $product_id with a valid number (Eg: $product_id=426 in my case). I'm not understanding whats wrong here as i expect data to be returned from cache within 5 seconds after the 1st hit. I want the data to be returned from cache. Can some one please help me understand whats happening ?
If you're using the address bar, you're doing a GET, but your code is looking for $_POST['...'], so you will end up with an invalid query. So for a start, the results using the address bar won't be what you're expecting. Is your Ajax call actually doing a POST?
Please also note that you've got a SQL injection vulnerability there. Make sure $product_id is an integer.
There are many problems with your code, first of all you always connect to the database and select a table, even if you don't need it. Second, you should check $result with !empty($result) which is more reliable as just !$result, because it's also covers empty objects.
As above noted, if the 'product_id' is not in the $_POST array, you could use $_REQUEST to also cover $_GET (but you shouldn't, if you are certain it's coming via $_POST).

What causes SQL Server to return the message 'The statement has been terminated'?

I have a very simple INSERT statement being executed from a PHP script running on a Linux Apache web server. I can run the query fine from within SQL Management Studio and it normally runs fine from PHP as well. However, every once in awhile I get an error message from my PHP script that the query failed and the mssql_get_last_message() function returns 'The statement has been terminated'.
What sources can cause this message to be returned from SQL Server?
You have found one of the most annoying parts of SQL Server. There are situations where an error can be raised, and SQL will generated two error messages: the first to explain what the error was, and the second to say something useful like "The statement has been terminated" (which, technically, is error number 3621). The thing is that SQL, and most everything else that touches it--such as PHP--can only see/pick up/process/or otherwise utilize that last unlcear error message. The one that's actually useful gets lost.
The quick way to figure out what's going on is to run the sequence of commands leading up to the error from SSMS. This, apparently, will not work for you.
A fussier way to figure it out is to fire up SQL Profiler to track the Exception event, and then run your process. This should show all errors that occured. Tossing in relevant other events (SP:Starting, SP:StmtStarting, SQL:BatchStarting, whatever is applicable to the code your submitting to the database) will show which command is raising the error.
To get a numeric error code from mssql you can do a select that looks something like
SELECT ##ERROR AS ErrorCode
Which SHOULD return the correct error code.
You can also try this code which is posted on PHP.NET.
function query($sQuery, $hDb_conn, $sError, $bDebug)
{
if(!$rQuery = #mssql_query($sQuery, $hDb_conn))
{
$sMssql_get_last_message = mssql_get_last_message();
$sQuery_added = "BEGIN TRY\n";
$sQuery_added .= "\t".$sQuery."\n";
$sQuery_added .= "END TRY\n";
$sQuery_added .= "BEGIN CATCH\n";
$sQuery_added .= "\tSELECT 'Error: ' + ERROR_MESSAGE()\n";
$sQuery_added .= "END CATCH";
$rRun2= #mssql_query($sQuery_added, $hDb_conn);
$aReturn = #mssql_fetch_assoc($rRun2);
if(empty($aReturn))
{
echo $sError.'. MSSQL returned: '.$sMssql_get_last_message.'.<br>Executed query: '.nl2br($sQuery);
}
elseif(isset($aReturn['computed']))
{
echo $sError.'. MSSQL returned: '.$aReturn['computed'].'.<br>Executed query: '.nl2br($sQuery);
}
return FALSE;
}
else
{
return $rQuery;
}
}
You can use the code in the message to know which is the error. For example:
[2627: The statement has been terminated.]
In this case, the error code is 2627, so if you execute the sql below you'll know the message
SELECT msg.text
FROM sys.messages msg
INNER JOIN sys.syslanguages lng ON lng.msglangid = msg.language_id
WHERE msg.message_id = 2627
AND lng.alias = 'English'
Violation of %ls constraint '%.*ls'. Cannot insert duplicate key in
object '%.*ls'. The duplicate key value is %ls.
This is a way to know the right message error. In my example the error is violation of primary key

Categories