> 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.