> foreach ( $cgi->param() ) {
>    push @cols, $_;
>    push @vals, $cgi -> param( $_ );
> }
> my $sql = "INSERT INTO table ( " . join( ", ", @cols ) . " )\n" .
>    "   VALUES ( " . join( ", ", map { "?" } @cols ) . " )";

Seeing all that 'line noise' makes me think we need a neater way.

Personally I'd have written it more like

my $sql = qq{
        INSERT INTO table
               ( } . join( ", ",         @cols ) . qq{ )
        VALUES ( } . join( ", ", ("?") x @cols ) . qq{ )
};

but that's not really that much clearer and possibly more
'magical' to the novice who may not be familiar with 'x' as a
list replication operator.


But imagine the DBI provided these two functions:

sub comma_separated_values { join ", ", @_ }
sub comma_separated_placeholders { join ", ", ("?") x @_ }

you could then write the statement like this:
separated
my $sql = qq{
        INSERT INTO table
               ( ${\comma_separated_values(@col)} )
        VALUES ( ${\comma_separated_placeholders(@col)} )
};

The "... ${\...} ..." is a little magical but not hard to master.
It's just a cute way to evaluate expressions inside a double quoted
string. The ${...} part expects a reference to a scalar so that's
what the backslash before the function name is for. The backslash
takes a reference to the scalar value returned by the function and
the ${...} then interpolates that into the string.

Perhaps we could call the functions dbi_csv and dbi_csp then we'd have

my $sql = "INSERT INTO table ( ${\dbi_csv(@col)} ) VALUES ( ${\dbi_csp(@col)} )";

which seems rather neater than where we started:

my $sql = "INSERT INTO table ( " . join( ", ", @cols ) . " )\n" .
   "   VALUES ( " . join( ", ", map { "?" } @cols ) . " )";


Comments?

Tim.

Reply via email to