packetstormer has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

I have a placeholder problem (which is most likey something silly) where the "?" is being assigned a literal string instead of the column name. A code extract is below (@reults is a list of caseids):

use strict; use Template; use CGI; use CGI::Session ( '-ip_match' ); use DBI; use Data::Dumper; use Sphinx::Search; require "lib/class.pm"; my $cgi = new CGI; my $dbh = new_dbh(); my $sph = sphinx_conn(); my $query = $cgi->param('search_index'); my $index = "cases"; my $field = $cgi->param('field'); my $col = "case_header"; my $header; .... foreach my $x(@results){ my $sth = $dbh->prepare("SELECT ?,status,DATE_FORMAT(added_date, \ +"%d/%m/%Y\") from cases where caseid = ?"); $sth->execute($col,$x); while (my @row = $sth->fetchrow_array()) { my $docs = \@row; my $bar = \%options; my $excerpts = $sph->BuildExcerpts($docs,$index, $query, $bar) +; my @deref_excerpts = @$excerpts; unshift (@deref_excerpts,$x); push (@send_to_template,\@deref_excerpts); } }
The result is "case_header" for all results in the case_header column instead of the actual results. The other columns display the correct result. If I use $col in the SQL query instead of the firs "?" I get the expected results. Can anyone spot what I have done!?

Replies are listed 'Best First'.
Re: SQL Placeholder oddity
by Eliya (Vicar) on Feb 22, 2012 at 16:57 UTC

    I think this is expected behavior.  Placeholders aren't a general text templating mechanism to substitute arbitrary components of a query.  As the docs mention:

    With most drivers, placeholders can't be used for any element of a statement that would prevent the database server from validating the statement and creating a query execution plan for it. For example:

    "SELECT name, age FROM ?" # wrong (will probably fail) "SELECT name, ? FROM people" # wrong (but may not 'fail')
Re: SQL Placeholder oddity ('column' is a string)
by tye (Sage) on Feb 22, 2012 at 17:59 UTC

    What did you expect from the equivalent of "SELECT 'case_header', ..." ?

    Ensure $index can only contain a valid and allowed column name and use prepare( "SELECT $index, ...

    - tye        

Re: SQL Placeholder oddity
by JavaFan (Canon) on Feb 22, 2012 at 21:28 UTC
    You cannot use a place holder in the selection list. What may work for you is (untested):
    my $sth = $dbh->prepare("SELECT *, DATE_FORMAT(...) as something from +cases where caseid = ?"); $sth->execute($x); while (my $hash = $sth->fetchrow_hashref()) { my @row = @$hash{$col, "status", "something"}; ... }