How to combine two PDO statements in one MySQL query? - php

From what I know now about PDO statements and my own experiences on localhost and Google - there are some difficulties with using multiple PDO statements in one query. For instance this situation:
$stmt = $db_people->prepare("SELECT * FROM people WHERE online=1");
$stmt->execute();
$results_people = $stmt->fetch(PDO::FETCH_ASSOC);
On this query I can do simple PDO statement like fetch (in example). But when I want to use PDO statement like this:
$rows = $stmt->rowCount();
It is not possible and the statement will not return the right number of rows. When I do it in the other way around and filling one of the column name - rowCount works correctly like this:
$stmt = $db_people->prepare("SELECT name FROM people WHERE online=1");
$stmt->execute();
$rows = $stmt->rowCount();
And adding fetch after that like this:
$results_people = $stmt->fetch(PDO::FETCH_ASSOC);
Will not work corectly in this example. My question is - How to combine two different PDO statements in one single query? Thank you.

The answer probably depends on which operations you're trying to combine. For instance, if you're trying to combine PDOStatement::rowCount() with a SELECT SQL operation, then it's probably worthwhile to take notice of the warnings in the PDOStatement::rowCount() description which says that rowCount() is not 100% reliable for SELECT statements in all databases.
If the problem you're trying to solve is specifically limited to counting the result rows of a SELECT, then another approach would be to use PDOStatement::fetchAll() and count the rows in the returned array.

Related

Using Prepared PDO statements

I'm running queries using the PDO prepared statement, MySQL db. When I run a query, I haven't found a way to know the number of affected rows if any, I've tried rowCount() but still to no avail.
$stmt1 = $db->prepare("SELECT * FROM publications WHERE pub_journal = '$j' AND pub_issue = 'CURRENT'");
$stmt1->execute();
How can I find the number of affected rows?
rowCount should work if your database is MySQL. The fact that it hasn't worked for you indicates that your query may be failing, or that it does not return the number of rows you expect it to.
The PDO documentation suggests the following approach to find the number of rows:
For most databases, PDOStatement::rowCount() does not return the number of rows affected by a SELECT statement. Instead, use PDO::query() to issue a SELECT COUNT(*) statement with the same predicates as your intended SELECT statement, then use PDOStatement::fetchColumn() to retrieve the number of rows that will be returned.
This should work with a prepared statement as well as with PDO::query().
You can modify your original SQL to be used as a template, so that it can take either COUNT(*) or * (or even better, a list of the specific columns you need).
$sql = "SELECT %s FROM publications WHERE pub_journal = ? AND pub_issue = 'CURRENT'";
Notice the ? in the SQL. This is a placeholder to which the $j variable will be bound when the statement is executed with execute([$j]);. When you concatenate your variables into the SQL string (like ...WHERE pub_journal = '$j'...) you really aren't getting much of the benefit of prepared statements.
With this, you can prepare and execute your count query:
$count_stmt = $db->prepare(sprintf($sql, 'COUNT(*)'));
$count_stmt->execute([$j]);
Then get the count with:
$count = $count_stmt->fetchColumn();
After you do whatever you need to do with the count, you can execute the actual SELECT query by specifying which columns you want rather than COUNT(*).
$select_stmt = $db->prepare(sprintf($sql, '*'));
$select_stmt->execute([$j]);
rowcount() should only be used for DELETE, INSERT, or UPDATE statements, though it may work for SELECTs in some cases. What you can do is this, though:
$res = $stmt->fetchAll();
$count = count($res);
And $count will hold the number of rows.

Get Number of Rows from a Select Statement Efficiently

Until recently I've been using mysql_real_escape_string() to fix most of my variables before making SQL queries to my database. A friend said that I should be using PDO's prepared statements instead, so after reading a bit about them I'm now switching over to them.
I've only encountered one problem so far in switching over, and that's counting the rows to returned by a SELECT statement. On occasion in my code, I'd run an SQL query and then count the number of rows returned from the SELECT statement. Depending on whether a result set returned, I would take different actions. Sometimes I do need to use the result set from it. MySQL let me go straight to mysql_fetch_assoc() after mysql_num_rows() with no problem. However, PDO doesn't seem to have anything like mysql_num_rows().
I've been reading some responses on SO that gave me a solution, to either use COUNT() in the SQL statement or to use the PHP function count() on the result set. COUNT() would work fine in the SQL statement if I didn't need the result set in some places, however, several people have mentioned that using count() on the result set is fairly inefficient.
So my question is, how should I be doing this if I need to count the number of rows selected (if any), then run a script with the result set? Is using count() on the result set the only way in this case, or is there a more efficient way to do things?
Below is a short example of something similar to my previous SQL code:
$query=mysql_query('SELECT ID FROM Table WHERE Name='Paul' LIMIT 1);
if(mysql_num_rows($query)>0)
{
print_r(mysql_fetch_assoc($query));
}
else
{
//Other code.
}
Thanks.
EDIT
I do know that you use fetchAll() on the statement before counting the result set (which gives me what I need), but I'm just trying to figure out the most efficient way to do things.
$stmt->rowCount();
http://php.net/manual/en/pdostatement.rowcount.php
the rows must be fetched(buffered into memory, or iterated) for it to work. It's not uncommon for your pdo driver to be configured to do this automatically.
You will have to use Count(). You can run two queries like
SELECT COUNT(ID) FROM Table WHERE Name='Paul'
one you have get the count, then run the query with select clause
SELECT ID FROM Table WHERE Name='Paul' LIMIT 1
Count() function is not inefficient at all if you are using it like COUNT(ID), because most probably id is primary key and have an index. MYSQL wont even have to access the table.

Placeholder For SQLite table In PHP

I have a query I would like to use that I would like to be reused for other select queries.
Is it possible to have a select query like this:
SELECT * FROM ? WHERE id = ?;
And then bind the values like this:
$stmt->bindValue(1, $table, PDO::PARAM_STR);
$stmt->bindValue(2, $id, PDO::PARAM_INT);
The problem is when I do this I get this $database->errorInfo() from a PDOException
HY000 1 near "?" syntax error.
I have tried taking out the table placeholder and it does work. Is it possible to do it my way or do I need to have separate functions?
Short answer: NO.
Long answer:
Refer to the PDO::prepare manual. There is a statement: This must be a valid SQL statement for the target database server. This means that your DB backend have to support prepared statement syntax that you use.
As far as I know, neither mysql, nor any other DB does not allow binding variables to occur in FROM clause. The reason for that lays deep in the concept of prepared statement. Prepared statement is being prepared inside the DB when you are calling prepare. This means that DB planner builds a plan for the query, so it can be executed multiple times with different parameters without building it again and again. To build a plan, planner needs to know affected tables, functions called, opportunities to use different fetch and join strategies (index scans/nested loops/etc.) and so on.
So, you cant 'bind' table name into prepared statement at the moment you want it to run, because DB needs table names at the moment when you prepare the statement. That's why you receive that message: DB requires all table names to be present in the preparing query.

Get Number of Rows from a Select statement

I have this:
$dbh = new PDO("odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=$mdbFilename", $username, $password);
$sql = "SELECT * FROM this_table";
$stmt = $dbh->query($sql);
//num of rows?
How do I get the number of rows returned from that SELECT statement?
Thanks all
SELECT count(*) FROM this_table is an option...
Regarding rowCount:
PDOStatement::rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement executed by the corresponding PDOStatement object.
If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. **
However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications.
I have found a solution, using fetchAll and then using count on this array - which is what MySQL does anyway internally, a bit inefficient but it works for me.
$q = $db->query("SELECT ...");
$rows = $q->fetchAll();
$rowCount = count($rows);
From another question Chad provided this insight:
It seems as though the only reason
this was possible with MySQL is
because it internally fetched all the
result rows and buffered them, to be
able to give you this information. See
mysql_unbuffered_query(). If you use
that function instead of
mysql_query(), the mysql_num_rows()
function will not work. If you really
need to know the number of rows while
using PDO, you can fetch all of the
rows from PDO into an array and then
use count().
Hope this is useful to someone.

Work-around for PHP5's PDO rowCount MySQL issue

I've recently started work on a new project using PHP5 and want to use their PDO classes for it. The problem is that the MySQL PDO Driver doesn't support rowCount() so there's no way to run a query and then get the number of affected rows, or rows returned, which is a pretty big issue as far as I'm concerned. I was wondering if anyone else has dealt with this before and what you've done to work around it. Having to do a fetch() or fetchAll() to check if any rows were affected or returned seems like a hack to me, I'd rather just do $stmt->numRows() or something similar.
You can issue a SELECT FOUND_ROWS() query right after the original SELECT query to get row count.
$pdo->query("SELECT * FROM users");
$foundRows = $pdo->query("SELECT FOUND_ROWS()")->fetchColumn();
See also: MySQL Docs on FOUND_ROWS()
For those of you who are using MySQL stored procedures, this solution isn't really feasible. What I would suggest that you do is have your stored procedure create two rowsets. The first one will contain one row and one column, containing the number of records. The second will be the recordset you will use for fetching that number of rows.
The number of unlimited rows can be a SELECT COUNT(*) with the exact same WHERE clause as the second rowset without the LIMIT/OFFSET clauses.
Another idea could be to create a temporary table. Use your SELECT statement to populate the temporary table. Then you can use SELECT COUNT(*) FROM tmpTable for your first rowset and SELECT * FROM tmpTable for your second.
This question is based on several false assumptions and one outdated statement.
First of all, do not confuse number of affected and selected rows. PDO supported the former even back in '09.
Speaking of number of rows returned by SELECT statement - you just don't need that number. The data you have is enough.
And yeah, nowadays rowCount() supports number of rows selected from mysql as well. But again - you don't need that number in an average web-application anyway.

Categories