Stored procedure errors in CakePHP - php

Any idea how to call a stored procedure in CakePHP?
$results = $this->query('call p2');
echo $results;
I keep getting this error though:
Error: SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered
queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code
is only ever going to run against mysql, you may enable query buffering by setting the
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.

I've done this within a transaction to ensure that no other instance of the procedure is called inbetween:
$this->begin();
$this->query("CALL procedure();");
$result = $this->query("SELECT something");
$this->commit();
Your problem may be that you're calling:
$this->query('call p2');
Where you should be calling:
$this->query('call p2()');
as procedures are much like functions.

you should you open and close parentheses
$results = $this->query('call p2()');
echo $results;

Related

Checking if sql query has any results in PHP

I'm trying to check if an sql query brings back any results in PHP, I've tried using mysql_num_rows($res) but I keep getting an error saying that the function expected parameter to be a resource but it is instead getting an object.
I've attached the relevant code here
$dsn = "mysql://$username:$password#$host/$dbName";
require_once('MDB2.php');
$db =& MDB2::connect($dsn);
if(PEAR::isError($db)){
    die($db->getMessage());
}
$sql=//sql query
$res =& $db->query($sql);
if(PEAR::isError($res)){
    die($res->getMessage());
}
$resultsFound = false;
if (mysql_num_rows($res)>0){
while($row=$res->fetchRow()){
//insert results here
}
} else {
echo "<br><h2>Sorry, invalid input</h2>";
}
I'm sure the solution is fiendlishly simple but I'm new to php and sql and would really appreciate your help!
Maybe this one helps?
https://pear.php.net/manual/en/package.database.mdb2.intro-fetch.php
You could use fetchAll() to fetch all results - count() on the response of fetchAll() should do the trick for you.
After you've built up your functionality, I suggest you migrate to some newer stuff, you should not use MDB2 anymore - it's deprecated stuff.
https://www.php.net/manual/en/pdo.query.php may be the more modern way to use PHP with mysql.
Otherwise use https://www.php.net/manual/en/mysqli.query.php - you can also retrieve the number of datasets in there.

Cannot run mysql stored procedure in laravel4

Have some php code:
// Fetch PDO instance
$pdo = $this->conn->getPdo();
// Call procedure that checks is user credentials is ok
$stmt = $pdo->prepare('CALL Users_CheckLogin(:username, :password);');
$passw = md5($credentials['passw']);
$stmt->bindValue(':username', $credentials['username']);
$stmt->bindValue(':password', $passw);
// Execute procedure
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_CLASS, 'ArrayObject');
$stmt->closeCursor();
For some reasons this code doesn't work here and returns:
SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.
I also googled about this error and haven't found any fix for this. So perhaps someone here can explain me what the problem is? I don't have paralels queries, only my procedure, inside this procedure I executing additional queries so perhaps that a reason but then it is huge bug in pdo. This procedure call works in mysql manager and with mysqli also.

how to execute multiple statements in loop

Hallo I have several queries to execute, all returning independent resultsets:
select * from table;
call procedureA(par1);
call procedureB(par2);
I would like to execute them within a loop to perform other operations:
$queries = array("select * from table;", "call procedureA(par1);", "call procedureB(par2);");
foreach($queries as $query) {
$res=$db->query($query);
// do something here with the query result
someFunction($res);
}
The first statement runs fine; at the second iteration, it stops stating that $res is a non object:
Call to a member function ... on a non-object
Apart from using mysqli_multi_query(), in which way could I loop execute multiple queries?
UPDATE I removed $res->close(); from the code sample since it was misleading and ininfluent for the issue.
UPDATE2 - SOLUTION
For anyone's sake, here is a complete working code:
$queries = array(
"CALL procedureA(par1)"
,"CALL procedureB()"
, "Select * from tableC"
);
// Open connection
$db = new mysqli(
$config['host']
,$config['user']
,$config['pwd']
,$config['dbname']
);
foreach($queries as $query) {
if ($res instanceof mysqli_result) {
$res->free();
}
$res=$db->query($query);
// do something with the query
echo getHtmlTable($res);
// free current result
$res->free();
// free subsequent resultset (es. the one with OK/ERR sp call status)
while ($db->next_result()) {
//free each result.
$res = $db->use_result();
if ($res instanceof mysqli_result) {
$res->free();
}
}
}
There is nothing special in running queries in a loop.
There will be no difference, either if you write two queries just one after another, or run them in a loop. So, generally speaking, a couple of queries run in a loop is no different from a couple of queries run in order just like in all our scripts.
The only possible problem a query itself. Say, a stored procedure call always return at least two resultsets. And no other query can be run until all resultsets get retrieved.
So, as a quick-and-dirty solution a line like this could be added
while ($db->next_result()) {}
at the bottom of the loop to clean up all the resultsets possibly remained in a queue after the query execution.
It qould be also highly convenient to turn on error reporting for mysqli, to make you aware of all the mysql error occurred. Having that, you would have added such error message to your question (Which is "Commands out of sync"). To do so, add this line before mysqli connect:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$r->close();
should be
$res->close();
You are referencing a non existent object ($r).
The execution of multiple queries depends of a server configuration. But aside from thas. This would be better to use transactions (that depending of the effect of those stored procedures, of course)

Codeigniter DB errors after stored procedure call

I have a database that has a few stored procedures in it that I would like to call via CodeIgniter. I have the following code in my Model class:
$sql = "CALL `stored_proc`(1)";
$query = $this->db->query($sql); //This call breaks the DB :(
$this->db->select('status');
$this->db->where('id', $id);
$query = $this->db->get('table');
print($query->num_rows()); //line 1116
When I run this code, I get the following error:
Fatal error: Call to a member function num_rows() on a non-object in C:\server\apache\htdocs\application\models\let_model.php on line 1116
If I remove the query line, the select works properly. Also, if I replace the call to a stored procedure with say a SELECT command, it also works properly.
Is there something obvious I'm missing for why I'm getting this error? If there isn't a good answer, is there a way to work around this problem?
Thanks for your time!
Edit: After delving a little deeper into the problem, it seems that this error will occur if my stored procedure contains a SELECT command. UPDATES seem to work properly. Perhaps this problem has something to do with how CodeIgniter deals with SELECT results?
Since this question appears first on google, i've managed to solve this by using :
$this->db->simple_query($query);
Instead of the regular query function.
The problem was that the SELECTs in the stored procedure were causing problems in CodeIgniter. By making sure that all of the SELECTs were directed (i.e. with the INTO clause), the stored procedure was able to run successfully.
For example,
-- This causes an error in CodeIgniter when inside a stored procedure.
SELECT GET_LOCK('lock1',0);
-- This does not.
DECLARE _lock_result INT;
SELECT GET_LOCK('lock1',0) INTO _lock_result;
I am still unaware of the underlying causes of why this causes an error, but this solution will suffice for my current work.
use only
$query->num_rows instead of $query->num_rows()

PHP: MySQL error hook?

I've been developing a web application with PHP and MySQL. The other day, I made some changes to the database and adapted one page to the new table layout but not another page. I didn't test well enough, so the site went online with the error still in the other page. It was a simple MySQL error, and once one of my co-workers spotted it, it was a simple fix.
Now that it's happened, I'd like to know how I can catch other MySQL errors. I'm thinking about some sort of notification system, that would send me an email when a mysql_query() fails.
I understand, of course, that I wouldn't be notified until after the error occurred, but at least I would have been notified immediately, rather than my co-worker come tell me after who-knows-how-many other people had run into the same fatal error.
Is there some sort of way to put in a hook, so that PHP automatically runs a function when an error happens? Or do I need to go through my code and add this functionality to every location where I use mysql_query()?
If the latter, do you have any recommendations on how to prevent something like this in the future? If this is the case I'll probably create a class to abstract SQL operations. I know I should have been doing this the whole time... But I did organize my sets of functions into different include files, so at least I'm doing most things right. Right?
You could use a wrapper function like this:
function mysql_query_wrapper($query, $link=null)
{
if (is_null($link)) {
$result = myql_query($query);
} else {
$result = myql_query($query, $link);
}
if (mysql_error($result)) {
// error occurred
}
return $result;
}
Then you just need to replace each mysql_query call with mysql_query_wrapper.
You can use custom functions for error handling using set_error_handler().
However, mysql_query won't trigger an error, but return false. The errors turn up only afterwards when trying to work with the results. In this case it might be better to define a custom wrapper function that calls mysql_query() and outputs possible errors using mysql_error(). That way, you can immediately halt your application on an error if so desired.

Categories