Could you please help me with this please, my question is about PHP, PDO and stored procedures in MySQL.
I have created a very simple stored procedure called selectAVG that returns the average grade of a subject via an output parameter, here is a stored procedure that I have created in order to test my code(I cannot post the code reffer to selectAVG because of my boss) but I hope with this you can catch up the whole idea.
DELIMITER $$
USE `ejemplo`$$
DROP PROCEDURE IF EXISTS `selectCount_sp`$$
CREATE DEFINER=`root`#`localhost`
PROCEDURE `selectCount_sp`(
OUT totalEmpleados INT <-- out parameter
)
BEGIN
SELECT COUNT(Nombre) INTO totalEmpleados FROM empleado_php;
END$$
DELIMITER ;
and this is my script.php, what it does is to call the stored procedure and get the total of employees via the output parameter
try {
$conn = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
$sql = 'CALL selectCount_sp(#total)';
$stmt = $conn->prepare($sql);
$stmt->execute();
$stmt->closeCursor(); //permite limpiar y ejecutar la segunda query
$r = $conn->query('select #total')->fetch();
print_r ($r);
}
catch (PDOException $pe) {
die("Error occurred:" . $pe->getMessage());
}
my problem is that I cannot get the output value with a simple echo, I have to use print_r in order to get this:
Array ( [#total] => 5 [0] => 5 )
but I just want to get a simple 5, what do I have to do to show for example: echo "the total is:" .$total and have this: the total is 5 ?
You can use ->fetchColumn() in this case:
$r = $conn->query('select #total');
$total = $r->fetchColumn();
If you have PHP 5.4 or greater, then dereferences will also work:
$total = $conn->query('select #total')->fetch(PDO::FETCH_ASSOC)['#total'];
You can do either of these.
This is simply how to address an item in an array.
echo $r[0];
or
echo $r['#total']
Or it might be better to do
$r = $conn->query('select #total as total')->fetch();
echo $r['total']
as I am not sure if PHP would like an # symbol in an array occurance.
Related
I have in the database a list of links from which I want to take some data.
All the script is working, except the part when I'm taking the link from the DB and paste it in Simple DOM function.
"
include ('utile/db.php');
include_once('utile/simple_html_dom.php');
$dbh = new PDO("mysql:host=$servername;dbname=$dbname;charset=utf8;", $username, $password);
$sth = $dbh->query("SELECT link FROM pilots where year = '2007' and Contry ='CZ' and zboruri <> '101' limit 3 ");
foreach ($sth as $url) {
functie ($url['link']);
}
function functie($lin){
$linkul=file_get_html("$lin");
// pages number
$paging = $linkul->find('div[class*=paging]',0);
echo $paging;
$numar=-4;
foreach($paging->find('a') as $element=>$item){$numar++;}
echo $numar;
}
"
I receive the following error:
Fatal error: Call to a member function find() on null in C:\xampp\htdocs\para\teste.php on line 269
If I change the link manually it will work.
I think it is something related how I extract the link from DB and insert it the function.
Thank you
The issue with fetchALL in foreach.
The line changed:
foreach($sth->fetchAll() as $url){
The final code that is working:
include ('utile/db.php');
include_once('utile/simple_html_dom.php');
$dbh = new PDO("mysql:host=$servername;dbname=$dbname;charset=utf8;", $username, $password);
$sth = $dbh->query("SELECT link FROM pilots where zboruri > '101' limit 3");
foreach($sth->fetchAll() as $url){
functie ($url['link']);
}
function functie($lin){
var_dump($lin);
$linkul=file_get_html("$lin");
$paging = $linkul->find('div[class*=paging]',0);// pages number
echo $paging;
$numar=-4;
foreach($paging->find('a') as $element=>$item){$numar++;}
echo $numar;
}
Thank you for advices.
When I use PDO I use prepared statements, so the syntax on getting the result of the query is a little different... but I think that you need to fetch a row from your $sth since it would be a record set. Here's a snippit of what I do
$dbconn = new PDO('mysql:host='.$hostname.';port='.$dbPort.';dbname='.$dbName.';charset=utf8', $dbuser, $dbpass,array(PDO::MYSQL_ATTR_FOUND_ROWS => true));
$dbconn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$result=$dbconn->prepare($query);
$result->execute($arr);
if(!$result){
// do your error handling, result is either false
// for error or contains a recordset
$errorMessage=$dbconn->errorInfo();
}
$result->setFetchMode(PDO::FETCH_ASSOC);
while($row=$result->fetch()){
// do stuff here, $row is an associative array w/ the
//keys being the column titles in your db table
print_r($row);
}
I'm using bindParam to bind the return value of stored procedure once the statement is executed
But i'm getting zero , i've specified output variable of stored procedure as BIGINT
and i'm binding parameter like below
$sql = "{:retval = CALL sp_testProc()}";
$stmt->bindParam('retval', $proc_pass_val, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT, 4);
bindparam is taking Length of data type as last parameter, i'm passing 4 here, but it returns zero, don't know why
Could anybody help me on this
Thanks in Advance
This is what I've done to make it work, Hope this helps someone.
Note: Procedure defined in MSSQL server
Here I want email into a field inorder to get that in an array, you can omit this line select #myemail as student_email; and you can get the value of #myemail into $myemail
My Procedure:
Alter proc [dbo].[sp_test_success](
#Id int=1,
#myemail varchar(250)=null output
)
AS
BEGIN
select #myemail=rtrim(email) from Student where StudentId=#Id;
select #myemail as student_email;-- i put this to get myemail into array
END
Code:
$dbh = new PDO('sqlsrv:Server=Server;Database=database', 'UID', 'Pwd');
$stmt = $dbh->prepare("{CALL sp_test_success(#Id=:Id,#myemail=:myemail)}");
$Id = 4;
$stmt->bindParam('Id', $Id, PDO::PARAM_INT);
$stmt->bindParam('myemail', $myemail, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 500);
$stmt->execute();
$results = array();
do {
$rows= $stmt->fetch();// default fetch type PDO::FETCH_BOTH
$results[]= $rows;
} while ($stmt->nextRowset());
echo "<pre>"; print_r($results);
print "procedure returned $myemail\n"; exit;
I'm new to php. I am making a call to store procedure that returns multiple result sets in MYSQL.
I can't seem to get PHP PDO to get the second result set. I only get the first. Any help is appreaciated
--more info
store procedure just makes to select statements like so
select * from Product where productId = id;
select url from Images where product_id = id;
PHP Code:
$conn = new PDO('mysql:host=localhost;dbname=salamancju_HardGraft', $this->userName, $this->password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
$stmt = $conn -> prepare('call GetProductById(:id)');
$stmt->execute( array(':id' => $id));
$results = array();
do {
$results = $results + $stmt->fetchAll(PDO::FETCH_NUM);
} while ($stmt->nextRowset());
echo json_encode($results);
Your problem has nothing to do with stored procedures.
+ operator on arrays works not the way you think. Use [] instead:
do {
$results[] = $stmt->fetchAll(PDO::FETCH_NUM);
} while ($stmt->nextRowset());
will produce a nested array. If you want another format, please provide an example.
Save for this issue, your code is perfect. Most people who aren't new to PHP, won't be able to make it ever.
I am trying to run a simple SELECT query. here is the query
$sql1=$conn->prepare("SELECT q.quoteid, q.customername, q.customersurname, q.timestamp, o.name
FROM quotes as q, occasions as o
WHERE q.occasionid=o.occasionid
AND companyid=1
AND q.day=:day
AND q.month=:month
AND q.year=:year
AND staffid='-1'
AND (q.complete != 'W' OR q.complete != 'Y')
AND q.online=0");
$sql1->execute($exearray);
/* here $exearray contain following value */
Array ( [:day] => 24 [:month] => 1 [:year] => 2014 )
Its not even showing any error.
If I pass static value 1 in month it is showing data.
I run this query directly on DB its working.
So I think there is no error in query.
I am running this query locally on MAMP.
have you tried to parse your month's data to string before passing to the pdo???
$exearray = array(':day'=>24, ':month'=>(string)1, ':year'=>2014);
once i faced this situation and i did this and it worked for me.
i always have this problem while i trying to use LIMIT command in mysql. i just parse my value to string or pass it through statically.
and it doesn't relevant to your MAMP. i have this problem on LAMP and WAMP too.
apparently it's a common problem which it's in PDO libraries.
and for the record don't forget to use intval() while you pass your month's variable directly to your query.
You need to fetch your result, execute only returns a boolean (true or false) whether query execution succeeded or not.
Example:
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();
/* Fetch all of the remaining rows in the result set */
print("Fetch all of the remaining rows in the result set:\n");
$result = $sth->fetchAll();
print_r($result);
from: http://php.net/manual/en/pdostatement.fetchall.php
Perhaps doing it the "long-way" with the parameters, and/or changing the query to use a join would help.
Also, the try/catch on PDOException might provide more information.
Lastly, note the $cmd->fetch(PDO::FETCH_ASSOC) invoked for iterating through the recordset.
try {
$db = new PDO("mysql:host=localhost;charset=utf8", "root", "root");
$cmd = $db->prepare("
SELECT q.quoteid, q.customername, q.customersurname,
q.timestamp, o.name
FROM quotes q
LEFT JOIN occasions o on q.occasionid = o.occasionid
WHERE companyid=1
AND q.day = :day
AND q.month = :month
AND q.year = :year
AND staffid = '-1'
AND (q.complete != 'W' OR q.complete != 'Y')
AND q.online = 0
");
$cmd->bindParam(':day', 24, PDO::PARAM_INT);
$cmd->bindParam(':month', 1, PDO::PARAM_INT);
$cmd->bindParam(':year', 2014, PDO::PARAM_INT);
if ($cmd->execute()) {
while ($row = $cmd->fetch(PDO::FETCH_ASSOC)) {
echo $row['quoteid']."|".$row['customername']."|".$row['name']."<br/>";
}
} else {
echo "$cmd->execute() returned false.";
}
} catch (PDOException $e) { echo $e->getMessage(); return; }
In table month column type was Varchar.
I change that to integer and now it is working.
p.s. I have tried using (string) before variable and even double quotes and single quotes on variable value but it didn't work.
Thank you everyone. :)
I want to access randomly to a result sets retuned from a Stored Procedure using PDO Mysql and PHP. I found PDOStatement::nextRowset but the access to the result sets seems to be sequential.
EDIT
I'm looking for some like this:
$pdo = new PDO("mysql:host=$server;port=$port;dbname=$dbname;charset=utf8", $user, $pass, array(PDO::ATTR_PERSISTENT => false));
$statement = "CALL FooSP()";
$query = $pdo->prepare($statement);
$query->execute();
$query->resultSet[1][0]["ColumnFoo"] // Second Resultset, first row, column "ColumnFoo"
$query->resultSet[3][1]["ColumnBar"] // third Resultset, second row, columna "ColumnBar"
$query->resultSet[0][0]["Column1"] // first Resultset, first row, columna "Column1"
Can anyone help me?
If You need all resultsets - just prefetch them using next rowset like this:
<?php
$sql = 'CALL multiple_rowsets()';
$stmt = $conn->query($sql);
$fetched_rowsets = array();
do {
$rowset = $stmt->fetchAll(PDO::FETCH_NUM);
if ($rowset)
{
$fetched_rowsets[] = $rowset;
}
# This is important part.
} while ($stmt->nextRowset());
#Now You got the table with all data from all resultsets, fetched in PHP memory.
$fetched_rowsets[1][0]["ColumnFoo"];
$fetched_rowsets[3][1]["ColumnBar"];
$fetched_rowsets[0][0]["Column1"];
?>
Just remember that it can be memory consuming.