This seems like it should be a very easy task, but I'm not sure it is.
I would like to use PDO to do a SELECT query, and then immediately after find out if there are any results (rows), and if so how many.
I'd like to fetch the result as an object not an array, as I like the $obj->col_name syntax, and it just feels a bit wrong to return an array just to find the above out.
$qryh = $conn->query("SELECT ...");
Then use $qryh to first find out if there are any rows, and if so how many.
Can this be done without falling back to using arrays..?
UPDATE:
I know about rowCount(), but I think it only works on UPDATE, INSERT and DELETE - my question relates to SELECT.
UPDATE 2:
I'm using SQL Server and MS Access, not MySQL, and rocount() does not work.
SOLUTION FOUND
The accepted answer lead to the solution. Here is what I found:
I was setting the PDO::ATTR_CURSOR option to PDO::CURSOR_SCROLL when creating the PDO object (new PDO(...), which returned -1 on a rowCount(). However if I set the cursor within ->prepare(... using an array (array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL)) it works and returns the row count.
http://technet.microsoft.com/en-us/library/ff628154(v=sql.105).aspx
So, the example on the above link works, setting the cursor when you create the PDO object doesn't work. Also note that in the 'remarks' section on the above link, it mentions PDO::CURSOR_SCROLLABLE which doesn't for me (I get Undefined class constant 'CURSOR_SCROLLABLE').
Try this way:
$query = "select * from ...";
$stmt = $conn->prepare( $query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$stmt->execute();
print $stmt->rowCount()
Should work
$stmt = $conn->query('SELECT ...');
// number of rows:
$rows = $stmt->rowCount();
// get an array with objects:
$objects = $stmt->fetchAll();
// another way to count the results:
$rows = count($objects);
This is what I do in my database class:
$stmt = $conn->prepare('SELECT ...');
$stmt->execute();
$arrayOfObjects = $stmt->fetchALL(PDO::FETCH_OBJ);
$numberOfRows = count($arrayOfObjects);
print $numberOfRows;
By passing PDO::FETCH_OBJ each object is an stdClass meaning you can use the -> syntax.
I believe this is what you are looking for, and it just uses the PHP count() function instead of mySQL rowCount().
If you want more context, here is the DB class I use in all of my projects: https://gist.github.com/pxlsqre/9f6471220ef187343f54
You're right, PDO::rowCount does not work properly with SELECT
One workaround is to Add the count to your query
$qryh = $conn->query("SELECT COUNT(*) as numRows FROM Table");
$result = $qryh->(PDO::FETCH_OBJ);;
$count = $result->numRows;
$qryh->fetchColumn()
Returns the number of rows selected through a SELECT query
Related
I am trying to fix my previous problem with an extra query.
However, when I am trying to make multiple calls to my PHP function it just shows the first one and not both.
Code:
<?php function test($colour)
{
$pdo = new PDO("pgsql:host=localhost;dbname=testdb","teun",""); // or use a global one
//$pdo = $GLOBALS['pdo'];
$sth = $pdo->prepare("SELECT * FROM threads WHERE cat_id = :cat_id AND thread_date=(
SELECT max(thread_date) FROM threads
)");
$sth->bindParam(':cat_id', $colour, PDO::PARAM_STR, 12);
$sth->execute();
$result = $sth->fetch();
echo $result ["thread_name"];
}
?>
(yes, I know this is unsafe but I want to achieve my thing first before I work on the safe part).
I call it using test ($row['extra_cat_id'])
Thanks!
fetch() only fetches 1 row, see PDOStatement::fetch.
Either iterate using fetch() to fetch 1 by 1, or use the fetchAll() method to fetch all results, see PDOStatement::fetchAll
The following code returns 0, even though there are 5 entries in the table categories with cat = 1.
$sql = "SELECT name FROM categories WHERE cat = ?";
$stmt = $db->prepare($sql);
$cat = 1;
$stmt->bind_param("i", $cat);
$stmt->execute();
$stmt->get_result();
echo $stmt->num_rows;
However, when I change $stmt->get_result(); to $stmt->store_result(); the output is 5. Why does get_result() not work here?
I found for instance on this answer: https://stackoverflow.com/a/8722329/2311074 that get_result() should also work.
Looks like the other answer is wrong and get_result doesn't change the state of a statement (which is quite logical, as you are asking for mysqli_result and therefore supposedly going to work with it from now on).
You see, the way you are using get_result is quite pointless. To make any point of it, you have to assign the result to a variable, which will give you the desired outcome:
$res = $stmt->get_result();
echo $res->num_rows;
Note that the num_rows property is quite useless in general. If you want to know whether your query returned any data or not, just collect the rows into array and then you use this array for the purpose.
$data = $stmt->get_result()->fetch_all();
if ($data) {
// whatever
} else {
// oops!
}
And of course you shouldn't use such a query only to count the goods available in a category. For such a purpose a count(*) query have to be used.
I am using PDO to access my data base and am looping using two while loops with fetch at the same time, seen below:
$DBH = new PDO('mysql:host=localhost;dbname=database;charset=utf8',$dblogin,$dbpass);
$sql = 'SELECT * FROM table';
$STH = $DBH->prepare($sql);
$STH->execute();
while ($bm_table = $STH->fetch(PDO::FETCH_ASSOC))
{
// SQL Query
$sql1 = 'QUERY HERE';
$STH1 = $DBH->prepare($sql1);
$STH1->execute();
// Loops through using different handle, but what if I used STH again?
while ($row = $STH1->fetch(PDO::FETCH_ASSOC))
{
SomeFunction($bm_table,$row);
}
}
As you can see above I am using a different statement handle ($STH, $STH1 etc.) Is this necessary? Or can I use just one statement handle for everything. The reason I have used multiple handles is as the $bm_table value that uses $STH, will still be in use while I am fetching $row wouldn't that change the value of $bm_table or stop the fetch from working? How does the handles with PDO work? Especially when in this case I have two simultaneous fetch loops running at the same time using the same PDO connection.
So the main thing I am looking for here is if I have two statements that are running simultaneously is it important that I use different handles when I continue to use the same connection?
$STH and STH1 are not statement handles, they're just PHP variables. You can reassign a variable if you no longer need its old value. But in the case of this code, you still need the old value.
If you assign $STH inside the outer loop to the handle returned by the second prepare() call, then when it gets back to the top of the loop and re-executes the $STH->fetch() test, it will try to fetch from the second query, not the first one. This will immediately end the outer loop because all those rows have been read.
You can reuse a statement handle for repetitions of the same query. This is very useful when the query has parameters:
$stmt = $DBH->prepare("SELECT * FROM tablename WHERE id = :id");
$stmt->bindParam(':id', $id);
foreach ($id_array as $id) {
$stmt->execute();
$row = $stmt->fetch();
// do stuff with $row
}
If I understand you correctly what you want is dynamic query?... just put a parameter on your method then...
something like this. call it as much as you want with difference parameters though.
Class SampleClass{
public function GetAll($tablename)
{
$sth = $this->prepare("SELECT * FROM $tablename");
$sth->execute();
return $sth->fetchAll();
}
}
I have a database that I am trying to query to get information to display to my user. I have used
fetch(PDO::FETCH_ASSOC)
before when retrieving a single row or
$row = mysql_fetch_array($result)
with good results. However, it is my understanding that it is better practice to use PDO so that is what I am trying to do.
The problem I am running into is that my results are only showing me the first row of the data I need. In this instance it is displaying the column header over and over and never giving me the data.
$stmt = $conn->prepare("SELECT ? FROM application");
$stmt->bindparam(1, $application_ID);
$stmt->execute();
$results = $stmt->fetchall(PDO::FETCH_ASSOC);
foreach($results as $row){
echo $row['application_ID'];
}
Here are the results
application_IDapplication_IDapplication_IDapplication_ID
It is good that you are aware that MySQL has been oficially deprecated and now we are supposed to used MySQLi or better yet, PDO.
Since you are not accepting any user input, there is no need of using a prepared statement.
Simply do this:
$stmt = $conn->query("SELECT * FROM application");
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($results as $row){
echo $row['application_ID'];
//output other rows here
}
As per the php documentation pdo::fetchAll
you have to use fetchAll, instead of fetchall.
I created this code:
$statement = $db->prepare("SELECT * FROM phptech_contact");
$statement->execute();
$result = $statement->result_metadata();
$object = $result->fetch_object();
print_r( $object );
When I run it, it doesn't work. Can anybody tell me why it doesn't work?
I have 20 rows in this table so data should be returned.
From http://ch.php.net/manual/en/mysqli-stmt.result-metadata.php
Note: The result set returned by mysqli_stmt_result_metadata() contains only metadata. It does not contain any row results. The rows are obtained by using the statement handle with mysqli_stmt_fetch().
As long as you don't need this meta data you don't need to call this method.
$statement = $db->prepare("SELECT fld1, fld2 FROM phptech_contact");
$statement->execute();
$stmt->bind_result($fld1, $fld2);
while ($stmt->fetch()) {
echo "$fld1 and $fld2<br />";
}
But I really dislike the mysqli extension. PDO is much cooler ... ;-)
$db = new PDO('...');
$stmt = $db->prepare("SELECT fld1, fld2 FROM phptech_contact");
$stmt->execute();
while ($obj = $stmt->fetchObject()) {
// ...
}
or
$objs = stmt->fetchAll(PDO::FETCH_OBJ);
if you're trying to get the rows from the database, the function you need is mysqli_stmt::fetch(), not mysqli_stmt::fetch_metadata()
You're also missing a few steps. When using prepared statements, you must specify the fields you would like to return instead of using the star wildcard, and then use mysqli_stmt::bind_result() to specify which variables the database fields should be placed in.
If you're more familiar with the original MySQL extension, prepared statements have a different process to use. If your select statement has a parameter (eg., "WHERE value=?") prepared statements are definitely recommended, but for your simple query, mysqli:query() would be sufficient, and not very different from the process of mysql_query()
I believe the problem is that mysqli_stmt::result_metadata() returns a mysqli_result object without any of the actual results — it only holds metadata.
So what you want to do is use $result = $statement->bind_result(...) and then call $result->fetch() repeatedly to get the results.
One of the comments under the bind-result() article shows how to do this for a query like yours, where you don't necessarily know all of the columns being returned.