ODBC fetch results from stored procedure in PHP - php

I'm having a little trouble getting the results from a stored procedure call to an ODBC connection.
I'm not used to calling stored procedures through ODBC from PHP, and I find the documentation incomplete (or maybe i'm missing something).
The code below seems to be working. But I can't find a way to fetch the result from $result.
$connect = odbc_connect("dsn","user","password");
$statement = "storedprocedure('IN value','OUT value_1','OUT value_2')";
$result = odbc_exec ($connect,$statement);
odbc_close($connect);
If I echo $result; it passes me a "Ressource id#" so something seems to work. But I can't figure out the fetch part :)

Your call worked and odbc returned you a resource ref from which you then need to fetch the results themselves: http://php.net/manual/en/function.odbc-fetch-array.php

Related

Executing Stored Procedure using php PDO is only returning the last result set

After connecting successfully, I am trying to get data from my Stored Procedures. But the below code is only returning successfully the last result set of the SP, instead of all the sets.
$dbh = new PDO (.....);
$sth = $dbh->prepare("EXEC ......");
$sth->execute();
while($result = $sth->fetch(PDO::FETCH_ASSOC)) {
print_r($result);
}
Is there anything I need to add to my code?
Thanks.
If you want multiple rows from a Firebird stored procedure, you need to select from it instead of executing it. Although IIRC you would only get the first result when executing it, contrary to what you say in your question.
So use:
select * from your_procedure()

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

I new there are lots of answer as well as accepted answers related to this question but none of them solve my problem. Still I am getting this error.
Procedures:
CREATE PROCEDURE getAllProducts()
BEGIN
SELECT * FROM products;
END //
CREATE PROCEDURE getAllCategories()
BEGIN
SELECT * FROM category;
END //
Connection & calling:
$link = mysql_connect($host,$username,$password) or die(mysql_error());
mysql_select_db($database, $link) or die(mysql_error());
$allProducts = mysql_query("CALL getAllProducts");
while($row = mysql_fetch_array($allProducts)) { }
$allCategory = mysql_query("CALL getAllCategories");
while($row = mysql_fetch_array($allCategory)) { }
I've even called mysql_free_result($allProducts) before executing the next query. But nothing happens.
mysql_get_client_info() return mysqlnd 5.0.5-dev - 081106 - $Revision: 1.3.2.27 $
I found that the problem only arises if I run two queries.
As the MySQL-Documentation for 'Commands out of sync' points out:
[...] 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.
The Documentation for mysql_use_result() says e.g.:
After invoking mysql_query() or mysql_real_query(), you must call
mysql_store_result() or mysql_use_result() for every statement that
successfully produces a result set (SELECT, SHOW, DESCRIBE, EXPLAIN,
CHECK TABLE, and so forth). You must also call mysql_free_result()
after you are done with the result set.
Basically you need to tell your client what it should do with the result.
Well, usually this error occurs because there are still results pending from the query. There are mysqli_store_result and mysqli_free_result functions available. Since you are using mysql and mysql extension does not have such functions, you can try closing the connection after executing the first procedure and establishing the connection again to execute next procedure. Though this is not the perfect solution, but it will work in your case.
mysql_close($connection);
$connection = mysql_connect("localhost","username","password");
You can also try
mysql_free_result($allProducts);
Stored procedures always return an extra result set with errors/warnings information. As such, your stored procedures return multiple result sets (the actual result set from your select query and the extra errors/warnings result set). Calling mysql_fetch_array in a loop you only saturate one of them, leaving the other still pending, causing the error you see.
I don't know how to fix it with vanilla mysql_ library, with mysqli_ you can issue mysqli_multi_query, and then only use the first result set. See the example in the docs.
It's not a fix per se, but if you insist on staying with mysql_* functions, and assuming that you actually want to work with more complicated stored procedures (i.e. that the ones you supplied are just a simplified example) - you can change the stored procedures code to write the resultset into a temporary table (e.g. tmp_getAllProducts) instead of returning it, and then SELECT from it in your PHP.
This is what worked for me a while back when I was stuck with mysql_* and couldn't upgrade...
This is a known limitation of the mysql extension. You must either not use more than one stored procedure per connection or upgrade to mysqli.
https://bugs.php.net/bug.php?id=39727

Quickly put all data from an SQL query into an array with PHP

I'm using something like the following PHP code to put all data from a query into an array:
<?php
$results = array();
$q = odbc_exec("SELECT * FROM table");
while ($row = odbc_fetch_array($q)) {
$results[] = $row;
}
?>
This works fine, but it is very slow when the query contains thousands of rows.
My question is, is there any way in PHP to dump all the data into an array without having to loop through each record one by one?
NOTE: Using MS SQL Server for the database.
You could try using mssql functions instead of odbc, but its unlikely to make a large difference.
With the way drivers work, the result set is an iterator handle to the result data itself. In some cases, php doesn't actually get the data until the row is requested by php. Unless there is a fetch all available in the driver, looping through all the rows is generally your only option.
If you don't need all the columns, you could limit the data being transfered by specifing only the columns you actually need.
Specifying the cursor_type in odbc_connect made odbc fetching much quicker.
$conn = odbc_connect($dsn, $user, $pass, SQL_CUR_USE_ODBC)
http://aaronsaray.com/blog/2007/08/02/odbc-for-udb-and-php-how-i-increased-performance-by-400/
I was able to find a way to do this with ADOdb (a database abstraction library for PHP) using the GetAll() function:
http://adodb.sourceforge.net/
$results = $DB->GetAll("SELECT * FROM table");
This returns all the rows as a 2-dimensional array.

SQLSRV with Linked Server

My issues basically revolves around me needing/preferring to use PHP's sqlsrv to access a sql-server 2000 database. I've worked on the project already using that with a sql server 2005 to run all the queries through and switching to something like the ODBC PHP drivers would be a pretty big headache right now. So now I have the original SQL Server 2000 database and 2005 installed on the same computer and I've created a linked server between the 2. Testing it out in Management Studio Express worked by running a simple query to one of the tables.
Now, I'm using the exact same query in PHP using sqlsrv_query and running into an error. My PHP code to test this out looks like this
$connectionOptions = array("UID"=>"user","PWD"=>"password");
$res = sqlsrv_connect("(local)\SQLExpress", $connectionOptions);
if(!$res) die("ERRORS : " . print_r(sqlsrv_errors()));
echo "SELECT * FROM [ServerName].DB.dbo.Table<br/>";
$res = sqlsrv_query($res,"SELECT * FROM [ServerName].DB.dbo.Table");
if($res===false){
die("ERRORS : " . print_r(sqlsrv_errors()));
}else{
var_dump($res);
$ary = sqlsrv_fetch_array($res);
}
var_dump($ary);
echo "<hr>";
var_dump(sqlsrv_errors());
The problem with this code is that the result of of sqlsrv_query doesn't return false but returns resource(11) of type unknown. So running fetch_array on that result tells me that an invalid parameter was passed to sqlsrv_fetch_array. I'm not sure what to do at this point. Is there just a problem running a query on a linked server through sqlsrv?
seems no error in your code.
Please try the fetch_array in a loop and update the result.
while($row = sqlsrv_fetch_array($result))
{
echo($row['field_name']);
}
also remove var_dump($ary);
Usually even if there is any error in the data display using '$row', the error message will show problem with 'sqlsrv_fetch_array'.
Well I figured out the problem. In my haste to make some code to test out whether or not the linked server worked, I just used the same variable name for the result of sqlsrv_connect and sqlsrv_query. Turns out, that was the whole problem. I switched the variable names so that the connection object is $Link and the query stays as $res. Now, I get the access to the database that I was trying to get through 2005 into 2000. So in the future, I definitely will name my variables a bit more carefully so I don't bang my head against the wall for hours.

mysql_query function in php

<?php
$con= mysql_connect("localhost","root","mysql");
mysql_select_db("Db_name",$con);
$res=mysql_query("select *from table_name");
mysql_close($con); // closing connection before fetching contents.
while($r=mysql_fetch_array($res)) {
echo $r['ename'];
}
?>
This programs works even if i close the connection before fetching contents from the table.
In order get table contents from the $res connection is not necessary ?
Is$res just a program variable ? If so what kind of data structure it is using(associative array ? )
In oracle we have implicit cursor and explicit cursor. Are there any equivalent things in mysql?
In the above program where cursors come into picture ?
$res in your case is a special type called a "Resource". Simply put it is a collection of the data returned which the mysql_fetch_* functions operate. As such, it can live beyond the connection. Check the documentation for more details.
The MySQL client library will fetch the whole result set before the call to mysql_query() returns which explains why your code works.
You can use mysql_unbuffered_query() to fetch the rows incrementally in which case you must keep the connection open.
Note that fetching the rows is handled inside the MySQL client code. $res is just an opaque ressource type that represents an internal resultset object (buffered or not). You can only operate on that ressource by passing it to other MySQL functions.
In order get table contents from the $res connection is not necessary ?
Why did not you try it and see?
Anyway, what is the reason to close connection manually?
Is $res just a program varible ? If so what kind of data structure it is using(associative array ?
Yes, it is a variable. You can see what is inside with var_dump($res);
In oracle we have implicit cursor and explicit cursor.Are there any equivalent things in mysql ?
In the above program where cursors come into picture ?
What exact task are you trying to solve?
As jason said $res is just like a normal variable of type Resource. This variable holds its value even after the mysql connection is closed as it has no connection with the mysql connection.

Categories