For example, say we wished to fetch the general information for 100
megalithic sites, using the name as the search field. We can write
the following SQL to do so:
SELECT name, location, mapref
FROM megaliths
WHERE name = <search_term>
By using interpolated SQL, we would actually issue 100 different SQL
statements to the database. Even though they are almost identical,
they are different enough for the database to re-parse the statement
and not use the cached information. By using a bind value, the same
piece of SQL and the same "execution plan" will be reused
over and over again, even though a different bind value is supplied
for each query.
Therefore, for databases that support it, using bind values with
prepared statement handles can quite dramatically increase the
performance of your applications and the efficiency of your database.
This is especially significant when trying to insert many records.
That said, there are good reasons to use interpolated SQL statements
instead of bind values. One of these reasons could be simply that
your database doesn't support bind values! A more complex
reason is that your database may have restrictive rules about what
parts of an SQL statement may use placeholders.
In the examples listed above, we've illustrated the use of bind
values to supply conditions for the query. For the sake of badness,
say we wanted to iterate through a list of database tables and return
the row count from each one. The following piece of code illustrates
the idea using an interpolated SQL statement:
foreach $tableName ( qw( megaliths, media, site_types ) ) {
$sth = $dbh->prepare( "
SELECT count(*)
FROM $tableName
" );
$sth->execute( );
my $count = $sth->fetchrow_array( );
print "Table $tableName has $count rows\n";
}
By using an interpolated statement, this code would actually execute
correctly and produce the desired results, albeit at the cost of
parsing and executing four different SQL statements within the
database. We could rewrite the code to use bind values, which would
be more efficient (theoretically):
$sth = $dbh->prepare( "
SELECT count(*)
FROM ?
" );
$sth->bind_param( 1, $tableName );
...
On most databases, this statement would actually fail to parse at the
prepare( ) call, because placeholders can
generally be used only for literal values. This is because the
database needs enough information to create the query execution plan,
and it can't do that with incomplete information (e.g., if it
doesn't know the name of the table).
Additionally, the following code will fail, since you are binding
more than just literal values:
$sth = $dbh->prepare( "
SELECT count(*)
FROM megaliths
?
" );
$sth->bind_param( 1, "WHERE name = 'Avebury'" );
...