> > 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 ) . " )";

I like it a lot: it would have really eased up my DBI learning curve.
Gives people an easy way to start using place-holders rather than string
interpolation.

Paul

Reply via email to