Fetching single row, single column with PDO - php

I have a mysql query that targets a single column in a single row
"SELECT some_col_name FROM table_name WHERE user=:user"
After I execute the statement $stmt->execute(); how do I get this single cell directly placed into a variable with no loops? In other words how to get
from $stmt->execute();
to $col_value = 100;
I tried the 2 below, but neither worked.. The column is number 4 in the original table, but I'm assuming since in my select statement I'm selecting it only, it should be 1 when I specify the parameter for fetchColumn.
$col_value = $stmt->fetchColumn();
$col_value = $stmt->fetchColumn(0);
As you can see, I'm trying to do it in as few lines as possible.

Are you sure it's returning any rows?
$stmt->fetchColumn()
is correct way to fetch a single value, so either you probably didn't bind the :user parameter or it simply returned no rows.

$sql='SELECT some_col_name FROM table_name WHERE user=?';
$sth=$pdo_dbh->prepare($sql);
$data=array($user);
$sth->execute($data);
$result=$sth->fetchColumn();

I'm not sure why so many people mess this up:
$stmt = $dbh->prepare("SELECT `column` FROM `table` WHERE `where`=:where");
$stmt->bindValue(':where', $MyWhere);
$stmt->execute();
$SingleVar = $stmt->fetchColumn();
Make sure that you are selecting a specific column in the query and not * or you will need to specify the column order number in fetchColumn(), example: $stmt->fetchColumn(2); That usually isn't a good idea because the columns in the database may be reorganized by, someone...
This will only work properly with unique 'wheres'; fetchColumn() will not return an array.

When you want to get the last insert you add the DESC Limit 1 to the sql statement.
$sql = "SELECT `some_col_name` FROM table_name\n"
. "ORDER BY `some_col_name` DESC\n"
. "LIMIT 1";
$stmt = $conn->prepare($sql);
$result = $stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
//convert the array content to string and store in variable
$col = implode(" ", $row);
echo $col;

Have you prepared the statement first? (Before $stmt->execute())
$stmt = $db->prepare("SELECT some_col_name FROM table_name WHERE user=:user");

You could use this:
$stmt->fetch(PDO::FETCH_COLUMN, $number_of_column);

Related

Query after query in pdo? Binding problems [duplicate]

This question already has an answer here:
PDO pagination with LIKE
(1 answer)
Closed 2 years ago.
I have one doubt about PDO.
I have a method in the class that returns data from the database for sent filters.
I want to get a number of rows for that query, but there are LIMIT and STAR in the query.
So because of that, I am using two queries to get a number of rows and data but to work, I need to bind the same value two times. Is there any more elegant way to achieve not have repeated code?
The method that I use is below.
$db = $this->openConnection();
$sql = " SELECT * FROM contacts";
// Filter data by main search input
if(!empty($search_query)){
$sql .= " WHERE ( location LIKE :search_query_location OR address LIKE :search_query_address ) ";
}
$sql .=" ORDER BY ".$order;
$stmt = $db->prepare($sql);
if(!empty($search_query)){
$stmt->bindValue(':search_query_location', (string) $search_query.'%');
$stmt->bindValue(':search_query_address', (string) $search_query.'%');
}
// Get number of rows after filter
$stmt->execute();
$total = $stmt->rowCount();
$sql .=" LIMIT :start, :limit_num";
$stmt = $db->prepare($sql);
if(!empty($search_query)){
$stmt->bindValue(':search_query_location', (string) $search_query.'%');
$stmt->bindValue(':search_query_address', (string) $search_query.'%');
}
// Bind start and limit value
$stmt->bindValue(':start', (int) $start, PDO::PARAM_INT);
$stmt->bindValue(':limit_num', (int) $limit, PDO::PARAM_INT);
// Get filtered data
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
return array($total,$data);
WHY I NEED TO REPEAT BINDING FOR TWO SAME QUERIES ONE WITHOUT LIMITS TO WORK IS THERE ANY ELEGANT SOLUTION
Problem
The reason that you have to bind twice is that $pdo->prepare($sql) returns a PDOStatement which isn't editable after it's been set. So when you update it you have to overwrite it and start again... Obviously the new statement doesn't retain the old bound parameters.
If you think of it as an array that you add some data to and then overwrite with a new, blank, array... You then can't read the information from the original array because it doesn't exist in the new one:
$array = [];
$array[] = 1;
$array[] = 2;
$array[] = 3;
var_dump($array);
/*
Output...
Array
(
[0] => 1
[1] => 2
[2] => 3
)
*/
$array = [];
print_r($array);
/*
Output...
Array
(
)
*/
The difference is that PDOStatement is an object not an array. But it's functionally the same thing!
N.B.
While $pdo->rowCount() may return the number of results from a SELECT query it isn't guaranteed so usually it's best practice not to use it.
I wouldn't overwrite the variable with a new query anyway... Better to use a different variable name e.g. $countQuery and $dataQuery
Solutions
So, if the only reason is that you're trying to reduce the amount of code then there are a bunch of solutions that you could use. However, this doesn't appear to be code golf, so why does it matter?
Solution 1
Assuming you don't have an unreasonable amount of unneeded results returned by the query then you could just return the array from the first query and use array_slice to take the place of the second query...
$pdo = $this->openConnection();
$sql = "SELECT * FROM contacts";
if($search_query){
$sql .= " WHERE ( location LIKE :search_query_location OR address LIKE :search_query_address ) ";
}
$sql .= " ORDER BY :order";
$query = $pdo->prepare($sql);
if($search_query){
$query->bindValue(':search_query_location', $search_query.'%');
$query->bindValue(':search_query_address', $search_query.'%');
}
$query->bindValue(':order', $order);
$query->execute();
$result = $query->fetchAll(PDO::FETCH_ASSOC);
$count = count($result);
return [$count, array_slice($result, $start, $limit)];
Solution 2
If you're worried about readability and code maintenance then you should remember that: it's usual for a method/function to have a reasonably specific function, for example...
Return the number of rows which match a query
Return the data which matches a query
Implementing this would mean you have each of your queries in separate functions:
function countContacts(...)
{
$sql = 'SELECT count(*) FROM contacts WHERE ...';
$query = $pdo->prepare($sql);
$query->bindValue(...);
$query->execute();
return $query->fetchColumn();
}
function getContacts(...)
{
$sql = 'SELECT * FROM contacts WHERE ... ORDER BY ... LIMIT ...';
$query = $pdo->prepare($sql);
$query->bindValue(...);
$query->execute();
return $result->fetchAll(PDO::FETCH_ASSOC);
}
Solution 3
I wouldn't use this, but it technically solves the issue
You could use a union and run two queries in one, then you could use emulated prepared statements (as per #Straberry's answer) to bind once...
Although, again, emulated prepared statements are not something that anyone on here is likely to suggest you should use without good reason. Of course you could use normal prepares and use different bind parameter names.
Either way, this isn't a great solution. I wouldn't use it.
$sql = "
SELECT COUNT(*) as col1, null as col2, null as col3, null as col4, null as col5 FROM contacts WHERE ...
UNTION
SELECT col1, col2, col3, col4, col5 FROM contacts WHERE ... ORDER BY ... LIMIT ...
";
$query = $pdo->prepare($sql);
$query->bindValue(...);
$query->execute();
$result = $query->fetchAll(PDO::FETCH_ASSOC);
return [$result[0]["col1"], array_slice($result, 1)];

What can be problem in this line with PDO? [duplicate]

I have a mysql query that targets a single column in a single row
"SELECT some_col_name FROM table_name WHERE user=:user"
After I execute the statement $stmt->execute(); how do I get this single cell directly placed into a variable with no loops? In other words how to get
from $stmt->execute();
to $col_value = 100;
I tried the 2 below, but neither worked.. The column is number 4 in the original table, but I'm assuming since in my select statement I'm selecting it only, it should be 1 when I specify the parameter for fetchColumn.
$col_value = $stmt->fetchColumn();
$col_value = $stmt->fetchColumn(0);
As you can see, I'm trying to do it in as few lines as possible.
Are you sure it's returning any rows?
$stmt->fetchColumn()
is correct way to fetch a single value, so either you probably didn't bind the :user parameter or it simply returned no rows.
$sql='SELECT some_col_name FROM table_name WHERE user=?';
$sth=$pdo_dbh->prepare($sql);
$data=array($user);
$sth->execute($data);
$result=$sth->fetchColumn();
I'm not sure why so many people mess this up:
$stmt = $dbh->prepare("SELECT `column` FROM `table` WHERE `where`=:where");
$stmt->bindValue(':where', $MyWhere);
$stmt->execute();
$SingleVar = $stmt->fetchColumn();
Make sure that you are selecting a specific column in the query and not * or you will need to specify the column order number in fetchColumn(), example: $stmt->fetchColumn(2); That usually isn't a good idea because the columns in the database may be reorganized by, someone...
This will only work properly with unique 'wheres'; fetchColumn() will not return an array.
When you want to get the last insert you add the DESC Limit 1 to the sql statement.
$sql = "SELECT `some_col_name` FROM table_name\n"
. "ORDER BY `some_col_name` DESC\n"
. "LIMIT 1";
$stmt = $conn->prepare($sql);
$result = $stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
//convert the array content to string and store in variable
$col = implode(" ", $row);
echo $col;
Have you prepared the statement first? (Before $stmt->execute())
$stmt = $db->prepare("SELECT some_col_name FROM table_name WHERE user=:user");
You could use this:
$stmt->fetch(PDO::FETCH_COLUMN, $number_of_column);

Why do i need to execute the statement twice?

$sql = "SELECT firstName , lastName FROM People WHERE born='1934'" ;
$stmt = $db->prepare($sql);
echo "<p>Execute the SQL-statement:<br><code>$sql</code><p>";
$stmt->execute();
// Get the results as an array with column names as array keys
$res = $stmt->fetchColumn();
$stmt->execute();
$res2 = $stmt->fetchColumn(1);
$ANSWER = $res." ".$res2;
If i remove the second execute(); statement the $res2 variable is empty.
Why is that? When i already have retrieved the results once/executed the statement.
if i input 1 as the parameter in the first fetchColumn(); i get the lastName DB column, so the results are there already.
The reason i'm using fetchColumn(); is that i need the result as string and not an array. I just cant understand why it doesnt work without the second execute, it seems like the result set gets destroyed or something after the first fetch and i need to execute it again? That sounds weird.

mysqli counting results and fetching them

Hello I have a prepared statement and I need to count the number of results I get. In order to do this I use store_result and num_rows
$query = 'SELECT userId, promo, email FROM users WHERE active = ?';
$rsActivation = $db->prepare($query);
$rsActivation->bind_param('s', $actv);
$rsActivation->execute();
$rsActivation->store_result();
$totalRows = $rsActivation->num_rows;
This code manages to get me the number of rows. The problem is that if I do this I cannot use fetch() on $rsActivation. If I use fetch and not use store_result I cannot get the number of rows.
How can I accomplish both things?
Thanks
SOLVED:
Turns out my problem was I was trying to fetch the results as an associative array. Instead I used bind_result to assign values to variables. Then I was able to use store_result and num_rows to get the count and after that I used fetch() together with the variables I assigned in bind_result.
$query = 'SELECT userId, promo, email FROM users WHERE active = ?';
$rsActivation = $db->prepare($query);
$rsActivation->bind_param('s', $actv);
$rsActivation->execute();
$rsActivation->bind_result($userId, $promo, $email);
$rsActivation->store_result();
$totalRows = $rsActivation->num_rows;
while($rsActivation->fetch()){
echo "<p>". $userId ."</p>";
...
}
You can try using
...
$rsActivation->execute();
$results = $rsActivation->get_results();
$totalRows = $results->num_rows;
and you should be able to fetch using something like
$results->fetch_assoc(), $results->fetch_row(), etc.
Here's the doc for it: http://php.net/manual/en/class.mysqli-result.php

Short code to get 2 values from one row with php pdo

Possibly stupid question, but can not find answer.
I need to get values from two columns of the same row.
And then set variables with each value.
Here I get one value from column Number and then define variable $NumberPostRegister1
$stmt = $db->prepare("SELECT Number FROM 2_1_journal WHERE Number = :Number1");
$stmt->bindParam(':Number1', $row_id1);
$stmt->execute();
$NumberPostRegister1 = $stmt->fetchColumn();
echo $NumberPostRegister1 .' NumberPostRegister1<br>';
Here I get second value from column IfDraft and then define variable $IfDraft1
$stmt = $db->prepare("SELECT IfDraft FROM 2_1_journal WHERE Number = :Number1");
$stmt->bindParam(':Number1', $row_id1);
$stmt->execute();
$IfDraft1 = $stmt->fetchColumn();
echo $IfDraft1 .' NumberPostRegister1<br>';
Two queries and rather long code.
How to do the same using one query and shorter/simpler code?
$stmt = $db->prepare("SELECT IfDraft, Number FROM 2_1_journal WHERE Number = ?");
$stmt->execute(array($row_id1));
list($IfDraft, $Numer) = $stmt->fetch();

Categories