I have called a MySQL stored procedure from PHP using mysqli. This has one out parameter.
$rs = $mysqli->query("CALL addNewUser($name,$age,#id)");
Here, #id is the out parameter. Next, I fire the following query to get the value of the out parameter:
$rs2 = $mysqli->query("SELECT #id");
while($row = $rs->fetch_object()){
echo var_dump($row);
}
The output of var_dump is as follows.
object(stdClass)#5 (1) { ["#id"]=> string(6) "100026" }
So, now I want to retrieve the value of #id, which I am unable to. I tried $row[0]->{#id} but this gave following error:
PHP Fatal error: Cannot use object of type stdClass as array
Or even just do a "SELECT #id AS id" then $row->id will work fine. I always rename select columns to keep the name meaningful when necessary :-)
BTW, you can simply concatenate the call and select #... (with a ; statement delimiter) and the RS will be the returned value. Unfortunately this returns a mutli-resultset and you need to flush the full set otherwise the subsequent queries will stall. See following examples:
$db->multi_query( "CALL addNewUser($name,$age,#id);SELECT #id as id" );
$db->next_result(); // flush the null RS from the call
$rs=$db->store_result(); // get the RS containing the id
echo $rs->fetch_object()->id, "\n";
$rs->free();
Alternatively add the select into the addNewUser and return a RS instead of out param
$rs = $db->query( "CALL addNewUser($name,$age)" );
echo $rs->fetch_object()->id, "\n";
$rs->close();
$db->next_result(); // flush the null RS from the call
The first returns a multiquery (NULL, RS) set and the second a (RS, NULL) set, hence you can use a simple query() call which embeds the first fetch_object(), but you still need to flush the RS stack.
Just $row->{"#id"} would work here. You can't use an stdClass as an array ($row[0]...).
Alternatively, you can just fetch the data as an array using mysqli::fetch_assoc() and access the data using $row['#id'].
Another correct methods its working fine: Cheers!!
$procedureName = 'VALIDATE_USER';
$procedure = "CALL $procedureName('$username','$pwd',#p_userid)";
$results1 = $dbconnection->query($procedure);
$results2 = $dbconnection->query("SELECT #p_userid");
$num_rows = $results2->num_rows;
if ($num_rows > 0) {
while($row = $results2->fetch_object())
{
echo $row->{"#p_userid"};
}
}
Here is the working solution:
enter code $res = $conn->multi_query( "CALL PROCNAME(#x);SELECT #x" );
if( $res ) {
$results = 0;
do {
if ($result = $conn->store_result()) {
printf( "<b>Result #%u</b>:<br/>", ++$results );
while( $row = $result->fetch_row() ) {
foreach( $row as $cell ) echo $cell, " ";
}
$result->close();
if( $conn->more_results() ) echo "<br/>";
}
} while( $conn->next_result() );
}
$conn->close();
Related
I have a PDO object with the following code:
$query = "SELECT DISTINCT SUBSTR( Date(Date), 1, 4) AS YEAR from Events ORDER BY YEAR DESC;";
$sth = $dbh->query( $query );
while( $row = $sth->fetch( PDO::FETCH_ASSOC )['YEAR'] ) {
print $row
}
The code executes, but I get
Trying to access array offset on value of type bool
What is the explanation, and is there a solution?
The way that a while loop works is that it will keep on iterating as long as the condition evaluates to a boolean true.
PDOStatement::fetch() will return an array containing the data of the current row and move an internal pointer to the next row in the result. If there are no more rows, it returns false.
This means that once you reach the end of the PDO result, fetch() returns false and you can't access array offset on false. This is why you get an error.
There are a couple of ways to solve this problem.
Don't use while loop. There's no reason to use it in your example.
foreach ($sth as $row) {
echo $row['YEAR'];
}
If all you want is a single column then there's no reason to fetch an array.
while( $year = $sth->fetchColumn() ) {
echo $year;
}
Set the fetch mode when you execute the query or using setFetchMode().
$sth = $dbh->query( $query, PDO::FETCH_COLUMN, 0 );
foreach ($sth as $year) {
echo $year;
}
This seems to work too:
$sth = $dbh->query( $query );
while( $row = $sth->fetch( PDO::FETCH_ASSOC ))
print $row['YEAR']
I agree that foreach is more appropriate
I need to fetch data from my db. I've done it but when I say fetch array [1], the output is the all second letters in all rows. Here is the code:
include "baglan2.php";
$query = $db->query("SELECT * FROM diziler", PDO::FETCH_ASSOC);
if ( $query->rowCount() ){
foreach( $query as $row ){
echo ($row['link']. "<br />");
}
I tried it with msqli but saw the same result; here is the mysqli code:
$query = mysqli_query($baglanti, "SELECT * FROM diziler");
if ( mysqli_affected_rows($baglanti) ){
while ( $row = mysqli_fetch_assoc($query) ){
print $row['link'][1]."<br />";
}
}
For instance all my data are links. When I run print $row['link'][1], it gives "t" letter from "http:" in all rows. I need to fetch my data by row not column. I have tried every method possible. However I couldn't find any method that worked.
for instance I want to make this codes output "http://**.com" in each element.
I am giving solution based on second attempt:-
$query = mysqli_query($baglanti, "SELECT link FROM diziler");
$link_array = array();
if ( $query){
while ( $row = mysqli_fetch_assoc($query) ){
$link_array[] = $row['link'];
}
}
echo "<pre/>";print_r($link_array); // it have all the links
Reason:- https://eval.in/649070
It's specification is given here:- https://stackoverflow.com/a/17193651/4248328
That is:- $string[int] is syntactic sugar for substr($string, int, 1)
I want to create a function that returns all results from a mysqli query in an array.
function Get(){
// verification... verification...
$res = $this -> link -> query("SELECT " . $select . " FROM " . $from);
while ($res->fetch_assoc())
{
$row[] = $res->fetch_assoc();
}
return $row;
}
i = 0;
var_dump(Get());
the while returns only the 1,3,5,7,9 results
Can someone explain the result?
You do twice $ref->fetch_assoc();
while ($result = $res->fetch_assoc())
{
$row[] = $result;
}
You should change your code and run:
while ($result = $res->fetch_assoc())
{
$row[] = $result;
}
Explanation:
In your code in your loop you have while ($res->fetch_assoc()) what makes that 1st record is taken from your results and it's being checked if this record is in database (it there are no records fetch_assoc return false and loop isn't executed anymore. However you don't assign this result to any variable so this result simple disappear. Then inside your loop you use $row[] = $res->fetch_assoc(); so you take the second record from database. Now the loop is being executed again. This is how this works.
The $res->fetch_assoc() call returns a single row from the result set and increments the internal pointer of the result set by one. Since you are calling fetch_assoc several times per Get() call, your results are not what you expect. If you'd like to get a single row of results, call fetch_assoc once. If you'd like to return all the rows from the result set, do something like this:
function Get(){
// verification... verification...
$res = $this -> link -> query("SELECT " . $select . " FROM " . $from);
$rows = array();
while( $row = $res->fetch_assoc() ) {
$rows[] = $row;
}
return $rows;
}
var_dump(Get());
If I do this in PHP, it works fine and loops as expected:
$rs = mysql_query($sql);
while ($row = mysql_fetch_assoc($rs)){
writeme("UserID: " . $row["UserID"]);
}
But I keep wanting to abstract this out into a function I have called ExecuteQuery:
function ExecuteQuery($sql){
$result = mysql_query($sql);
if ($result) {
if($result != 1){
return mysql_fetch_assoc($result); // return recordset
}
}else{
$message = 'Invalid query: ' . mysql_error() . "<br>";
$message .= 'Whole query: ' . $sql;
echo $message;
die();
}
}
This function works great in 2 out of 3 scenarios:
1- Works great for a query that returns 1 row, and I can access like this:
$rs = ExecuteQuery($sql);
$foo = $rs["UserID"];
2- Works great for a sql statement that returns no records, like an UPDATE or DELETE.
3- But when I try to get back a recordset that returns multiple records, and then loop through it, I get an infinite loop and my browser crashes. Like this:
$rs = ExecuteQuery($sql);
while ($row = $rs){
writeme("UserID: " . $row["UserID"]);
}
How can I modify my while loop so it advances to each new record in the recordset and stops after the last record? I'm sure it's a dumb little thing, but I'm not expert with PHP yet. I'd really like my ExecuteQuery function to be able to handle all 3 scenarios, it's very handy.
try foreach($rs as $row){ instead of while ($row = $rs){
mysql_fetch_assoc() only returns one row of the result. To get the next row, you need to call mysql_fetch_assoc() again. One thing you could do is have your ExecuteQuery function return an array of arrays:
$rows = array();
while ($row = mysql_fetch_assoc($result) !== false) {
$rows[] = $row;
}
return $rows;
Also, you should not use the mysql_* functions as they are deprecated. Try using PDO or mysqli_* instead.
Don't use while, use foreach:
$rs = ExecuteQuery($sql);
foreach ($rs as $row){
writeme("UserID: " . $row["UserID"]);
}
I am unable to get the following working. I want to use prepared statements in the example below, but I am getting an error. The function defnitily gets passed the correct value in $array:
private function getInfoFromSystem($array) {
try {
$sql = "
SELECT
PCO_AGENT.NAME,
PCO_INBOUNDLOG.LOGIN AS LOGINID,
PCO_INBOUNDLOG.PHONE AS CALLERID,
PCO_INBOUNDLOG.STATION AS EXTEN,
PCO_INBOUNDLOG.TALKTIME AS CALLLENGTH,
PCO_INBOUNDLOG.CHANNELRECORDID AS RECORDINGID,
PCO_SOFTPHONECALLLOG.RDATE,
PCO_INBOUNDLOG.RDATE AS INBOUNDDATE
FROM
PCO_INBOUNDLOG
INNER JOIN
PCO_LOGINAGENT ON PCO_INBOUNDLOG.LOGIN = PCO_LOGINAGENT.LOGIN
INNER JOIN
PCO_SOFTPHONECALLLOG ON PCO_INBOUNDLOG.ID = PCO_SOFTPHONECALLLOG.CONTACTID
INNER JOIN
PCO_AGENT ON PCO_LOGINAGENT.AGENTID = PCO_AGENT.ID
WHERE
LOGINID = :extension
";
$arr = array(":extension" => $array['extension']);
$query = $this->mssql->prepare($sql);
$query->execute($arr);
// $sql = "select * from sys.messages where message_id = 229";
foreach($this->mssql->query($sql) as $row) {
echo "<pre>";
print_r($row);
echo "</pre>";
}
}
catch(PDOException $e) {
echo $e->getMessage();
}
}
You should not be calling query() after execute(). Instead you need to fetch() your rows:
$query = $this->mssql->prepare($sql);
$query->execute($arr);
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
echo "<pre>";
print_r($row);
echo "</pre>";
}
// OR rather than the fetch loop above, use fetchAll()
$rowset = $query->fetchAll(PDO::FETCH_ASSOC);
print_r($rowset);
In my experience with PDO + MSSQL, attempting to call a regular query immediately after calling execute() on a statement that returns rows will fail unless you have called $query->closeCursor() first. However, in this case, you should not be calling query() at all. You've already executed your statement with bound params, and just need to fetch rows from it.