PDO equivalent of pg-result-seek - php

Anybody knows the PDO equivalent of pg-result-seek? I want to rewind a dataset using Postgre.

PDO's query() method will return a PDOStatement Object. There is no equivalent to seek to a specific record like you are asking. One alternative might be to use the fetchAll() method and then grab the Nth record you are looking for.
<?php
$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);
$result[N] would contain the row you are looking for.

If Database Permits, Use PDO::FETCH_ORI_ABS or PDO::FETCH_ORI_REL,
Eg.
$result = $sth->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_ABS, 671);

This is a part of the fetch function:
http://www.php.net/manual/en/pdostatement.fetch.php
But I don't see the need to do that, if you select the rows, you need it (all)...

Related

Can't call PHP function multiple times

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

PHP PDO Select Query Results

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

What is the point of fetchAll?

To get the result from the database, you can do this:
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();
$result = $sth->fetchAll();
foreach($result as $r) {
echo "<pre>";
print_r($r);
echo "</pre>";
}
but it seem to work without using fetchAll, example:
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$result = $sth->execute();
foreach($result as $r) {
echo "<pre>";
print_r($r);
echo "</pre>";
}
so what is the difference?
fetchAll will read in all rows from the database resultset and make an array out of them, keeping it all in memory. Iterating over the resultset will fetch one row at a time from the server which will save resources on the PHP side (but may use more resources on the database server, depending on the database implementation).
Firstly I assume that you are using php PDO
With fetchAll you can specify Fetch mode as an argument and fetchall provides more flexibility over the returned rows and fetchall will read all rows from database and translate into an array.
fetchall is lot more efficient in resource management compared to simple executes i guess. also the resource returned by execute is bool

Retrieving PHP Prepared Statement field data

I am using the Mysqli extension and a PHP Prepared Statement SELECT; I don't know how many fields I have in the SELECT until I after I do the
$stmt->execute();
$fieldcnt = $stmt->field_count;
Because this, I am having problems doing a
$stmt->bind_result(list of parms);
Namely, since I don't know how many fields have been returned, I don't know how to contruct the "list of parms."
So, I need some advice on how I access the fields returned;
Don't use bind_result, and use fetch_assoc().
This will return an associated array for each row:
while ($row = $stmt->fech_assoc()) {
print_r($row);
}
You can leverage call_user_func_array() to accomplish this task -- if you absolutely must use bind_result().
// create an array the size of the number of parameters
$params = array_fill(0, $fieldcnt, null);
// call bind_result, resulting in every column of the result to be
// bound to a value in $params
call_user_func_array(array($stmt, 'bind_result'), $params);
// take a look at all the params
print_r($params);

Why doesn't this prepare statement work in MYSQLI?

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.

Categories