Error calling SPCommands when running multiple MYSQL Stored Procedures - php

I am new to php but not as a programmer...
I am having difficulty calling and displaying the content when I call a procedure more than once in a page. I am trying to display two separate record sets from two different SP calls for MYSQL. I can display the first call but the second fails. I'm not sure what I am doing wrong but perhaps someone can kind help?
I keep getting the error when I call the second procedure:
Error calling SPCommands out of sync; you can't run this command now
I'm running on windows btw
Code below... PHP
// First call to SP
$page = 2;
$section = 1;
include("DatabaseConnection.php"); //general connection - works fine
$sql = 'CALL GetPageContent("'.$page.'", "'.$section.'")';
$result = mysqli_query($conn, $sql) or die('Error calling SP' .mysqli_error($conn));
while($row=mysqli_fetch_assoc($result))
{
// DO STUFF< REMOVED TO MAKE READING CLEARER
}
mysqli_free_result($result);
//SECOND CALL BELOW
$section = 2; // change parameter for different results
$sql = 'CALL GetPageContent("'.$page.'", "'.$section.'")';
$result = mysqli_query($conn, $sql) or die('Error calling SP' .mysqli_error($conn));
while($row=mysql_fetch_assoc($result))
{
// DO STUFF< REMOVED TO MAKE READING CLEARER
}
mysqli_free_result($result);

The trouble is that your SP is giving you multiple results.
Use the mysqli_multi_query, see http://us2.php.net/mysqli_multi_query

Related

Multiple stored procedure are not getting called?

Below image contain my code.
here, only one procedure is invoked at a time.Both procedure are not working .
here if state procedure is commented then city procedure called.
and if city in commented then State procedure is working.
for example , you can call multiple stored procedure like this below code
$db = mysqli_connect([...]);
$r = mysqli_query($db, " CALL getSomething(2); ");
while($row = mysqli_fetch_assoc($r)) {
print_r($row);
}
mysqli_free_result($r);
mysqli_next_result($db);
$r = mysqli_query($db, " CALL getSomethingElse(); ");
while($row = mysqli_fetch_assoc($r)) {
print_r($row);
}
mysqli_free_result($r);
mysqli_next_result($db);
mysqli_close($db);
it is important to use the functions mysqli_free_result() and mysqli_next_result() after the MySQL stored procedure is called, otherwise, the code will not work and you may see an error like "Commands out of sync; you can't run this command now".

Call MySql Stored Procedure from PHP (PDO)

I am trying to execute a MySQL Stored Procedure using PDO connection, i tried almost everything but not able to execute it.
The SP will only insert and update. Following is the codes I tried till now.
$config = require('protected/config/main.php');
try
{
$db_adat = new PDO($config['components']['db']['connectionString'], $config['components'] ['db']['username'], $config['components']['db']['password']);
$result= $db_adat->prepare('CALL pdv()');
$a = $result->execute();
$a->fetchAll(PDO::FETCH_ASSOC);
I tried with only fetch(), with only fetchAll(), fetchObject(), with fetch(PDO::FETCH_ASSOC), with fetchAll(\PDO::FETCH_ASSOC), but I always get following error
Fatal error: Call to a member function fetchAll() on a non-object in D:\ADAT_System\www\test\protected\controllers\ExportPDVController.php on line 35
I also tried using query() instead of execute(), but that doesn't work either.
I also tried adding a (select * ) statement in SP and tried with all above "fetch" options, but got same error.
The SP takes 7 minutes to complete, but all gave error immediately, so I am guessing it never ran the SP.
I tried as following too
$result= $this->$db_adat->prepare("CALL pdv()");
$result->execute();
but the I got following error:
Object of class PDO could not be converted to string
I am not passing any parameters in SP, just a simple call. Please let me know if any more information is required.
This part of your code is wrong
$result= $db_adat->prepare('CALL pdv()');
$a = $result->execute();
$a->fetchAll(PDO::FETCH_ASSOC);
Because execute() returns a boolean upon success or failure.
You cannot use that to fetch.here is the proper way with appropriate variable names:
$stmt= $db_adat->prepare('CALL pdv()');
$success = $stmt->execute();
if($success){
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
}else{
echo 'failed to run sp';
}
<?php
if(isset($_POST) && !empty($_POST)){
$SearchPO = (($_POST)['SearchPO']);
}
$stmt = $pdo->prepare("CALL spPO(?)");
$stmt->bindParam(1, $SearchPO, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT|PDO::ATTR_EMULATE_PREPARES, 4000);
$stmt->execute();
do {
$result = $stmt->fetchAll();
} while ($stmt->nextRowset() && $stmt->columnCount());
?>
You must use the nextRowset() function because the next record is 'empty' without it. Source

custom function for mysqli queries

I'm trying my hand at custom functions in PHP in order to streamline a lot of stuff I'm otherwise doing manually. I'm damn new to custom functions so I'm not sure the limitations. Right now I'm trying to get data with MySQLi using custom functions Here's the code, and then I'll explain the issue:
function connect_db($db = 'db_username') {
iconv_set_encoding("internal_encoding", "UTF-8");
mb_language('uni');
mb_internal_encoding('UTF-8');
# $mysqli = new mysqli('host',$db,'password',$db);
if(mysqli_connect_errno())
{
die('connection error');
}
}
This one seems to be working fine. It's the next function I'm having more trouble with.
edit: Updated thanks to Jeremy1026's response
function do_query($db = 'default_db', $query) {
connect_db();
$result = $mysqli->query($query);
if(!$result){
trigger_error("data selection error");
}
while($row = $result->fetch_assoc()){
$result_array[] = $row;
}
return $result_array;
}
My host forces database names and usernames as the same, so if the db name is 'bob' the username to access it will be 'bob' as well, so that's why $db shows up twice in the connection.
The problem I'm having is that these two functions are in functions.php and being called from another page. I want to be able to pull the results from the query in that other page based on the column name. But I also need to be able to do this with formatting, so then maybe the while() loop has to happen on that page and not in a function? I want this to be as universal as possible, regardless of the page or the data, so that I can use these two functions for all connections and all queries of the three databases I'm running for the site.
God I hope I'm being clear.
Big thanks in advance for any suggestions. I've googled this a bit but it's tough to find anything that's not using obsolescent mysql_ prefixes or anything that's actually returning the data in a way that I can use.
Update: I'm now getting the following error when accessing the page in question:
Fatal error: Call to a member function query() on a non-object in /functions.php`
with the line in question being $result = $mysqli->query($query);. I assume that's because it thinks $query is undefined, but shouldn't it be getting the definition from being called in the page? This is that page's code:
$query = "SELECT * FROM `table`";
$myArray = do_query($db, $query);
echo $myArray['column_name'];
In your 2nd function you aren't returning any data, so it is getting lost. You need to tell it what to return, see below:
function do_query($db = 'default_db', $query) {
connect_db();
$result = $mysqli->query($query);
if(!$result){
trigger_error("data selection error");
}
while($row = $result->fetch_assoc()){
$result_array[] = $row;
}
return $result_array;
}
Then, when using the function you'll do something like:
$myArray = do_query($db, 'select column from table');
$myArray would then be populated with the results of your query.
This is a half-answer. The following single function works in place of the two.
function query_db($database, $new_query) {
$sqli = new mysqli('host', $database, 'password', $database);
$sqli->set_charset("utf8");
global $result;
if($result = $sqli->query($new_query)){
return $result;
}
}
By adding global $result I was able to access the results from the query, run from another page as
query_db("username","SELECT * FROM `column`");
while($row = $result->fetch_assoc()){
print_r($row);
}
It's more streamlined than I have without functions, but it's still not idea. If I have the connection to the database in another function, it doesn't work. If I try to put the while loop in the combined function, it doesn't work. Better than nothing, I guess.

Using the same mysqli connection ($conn=mysqli_connect) multiple times gives errors

I am using the mysqli functions (mysqli_connect, mysqli_select_db, mysqli_query) to call 1 select query and 2 stored procedures.
It seems that when I am using the same $connection (returned by mysqli_connect) multiple times, I am getting the following error message: "Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given in..."
Below is my code:
<?php
$server="localhost";
$user="user";
$pass="pass";
$db="db";
$connection=mysqli_connect("$server","$user","$pass");
mysqli_select_db($connection, "$db") or die('Unable to select database.');
//First SELECT using $connection
$query=mysqli_query($connection, "SELECT item_name FROM items ORDER BY item_name DESC");
While ($result=mysqli_fetch_array($query,MYSQL_NUM))
{
$complete_result[] = $result[0];
$total_rows = $total_rows + 1;
}
//CALL to first sp using $connection
$query2 = mysqli_query($connection, "CALL sp_check_edits_remaining()");
while ($row2 = mysqli_fetch_array($query2, MYSQL_ASSOC)) {
$edits_remaining = $row2['edits_remaining'];
} // End while
//CALL to second sp using $connection
$query3 = mysqli_query($connection, "CALL sp_edit_data");
while ($row3 = mysqli_fetch_array($query3, MYSQL_ASSOC)) {);
$edits_id = $row3['id'];
} // End while
?>
Like I described, when I call the second sp, the above code gives me the error message mentioned above. (Please note that the connection is never closed.)
However, when I create another connection and provide it to the second sp call, this error disappears. This is shown in the code below
$connection2=mysqli_connect("$server","$user","$pass");
mysqli_select_db($connection2, "$db") or die('Unable to select database.');
//CALL to second sp using $connection
$query3 = mysqli_query($connection2, "CALL sp_edit_data");
while ($row3 = mysqli_fetch_array($query3, MYSQL_ASSOC)) {
$edits_id = $row3['id'];
} // End while
Can anyone please help me why this unexpected behavior?
Thanks and in advance!
It seems I have found a solution, which might be specific to my scenario.
My stored procs return only one row in the resultset.
So, after the CALL to the first sp and the corresponding while loop, I have simply added:
mysqli_next_result($connection);
This has removed the error message/warning I was receiving.
Anyone wants to comment whether this is the 'professional' approach?
You have an error somewhere, causing one of the mysql functions (probably the query call(s)) to return a boolean false, which you then blindly use in a fetch call. You need to add extra error handling, e.g.
$query = mysqli_query($connection, "...") or die(mysqli_error($connection));
never assume a query has succeeded.
enter code hereafter the query is finished, you must close the $connection then for another query, connect and assign the $connection again.
mysqli_close($connection);
$connection=mysqli_connect(bla,bla,bla,bla).

Calling 3 Stored Procedures with PDO DBLIB in PHP 5.4.4 fails

I try to call 3 SQL Server 2000 Stored Procedures one after the other using PDO DBLIB in PHP 5.4.4 (Linux) and I get an error at the second query : Fatal error: Call to a member function fetchAll() on a non-object
The first query works perfectly, returning results as expected. If I move query order, every time the first query succeeds and the others fail.
Also, when the exact same code is run on a PHP 5.3.14 server, everything works great.
Example code:
$dbh = new PDO ("dblib:host=myhost;dbname=mydb","user","pass");
$query = $dbh->query("EXEC dbo.storedProc1 'param1'");
$result = $query->fetchAll();
var_dump($result);
$query = $dbh->query("EXEC dbo.storedProc2 'param1'");
$result = $query->fetchAll(); // <-- Fails here
var_dump($result);
$query = $dbh->query("EXEC dbo.storedProc3 'param1'");
$result = $query->fetchAll();
var_dump($result);
Any clue to make this code run on PHP 5.4 ?
EDIT : PDO::errorInfo gives me that error : Attempt to initiate a new Adaptive Server operation with results pending [20019] (severity 7) [EXEC dbo.storedProc2 'param1']
Also, calling query with a SELECT (SELECT 1, SELECT 3 and SELECT 3 for example) gives the same result (first result is given, following are empty)
EDIT 2 : Looks like it's related to a PHP bug, as noticed by Capilé in the comments
I'm going to do out on a limb and say that your stored procedure returns more than one result set. Either that, or SQL Server 2000 is bloody-mindedly insisting that you close the cursor before next query when it's empty. Either way, this should fix the problem:
$dbh = new PDO ("dblib:host=myhost;dbname=mydb","user","pass");
$results = array();
$query = $dbh->query("EXEC dbo.storedProc1 'param1'");
do {
$results[] = $query->fetchAll();
} while ($query->nextRowset());
$query->closeCursor();
var_dump($results);
$results = array();
$query = $dbh->query("EXEC dbo.storedProc2 'param1'");
do {
$results[] = $query->fetchAll();
} while ($query->nextRowset());
$query->closeCursor();
var_dump($results);
$results = array();
$query = $dbh->query("EXEC dbo.storedProc3 'param1'");
do {
$results[] = $query->fetchAll();
} while ($query->nextRowset());
$query->closeCursor();
var_dump($result);
Be aware that when actually using $results it will be one level deeper than you might expect, because it can store multiple result sets, and these would be stored in separate keys.

Categories