This type of trick is good for when you are just writing out sql files for
some other process to apply. I'd like something that would take a number of
columns that you are going to insert, then return insert statements nicely
formatted and properly quoted for printing. Maybe it could even check for
non-nullable fields in your insert statement, and things like that. But
maybe that's beyond the scope of DBI. For example:
my $table = 'people';
my $printer = $dbh->sql_printer($table);
# so now $printer knows about the columns and types of the target table
# it will quote things properly, complain about missing non-nullable
columns,
# complain about addition columns, etc. Maybe even some type checking?
# you can do the sql directly:
$dbh->do($printer->insert({
age => 11,
first => 'mitch',
last => undef
}));
# or print it out for later:
print $printer->insert({
age => 11,
first => 'mitch',
last => undef
});
# or do placeholders
my $sth = $dbh->do($printer->insert_placeholder({
qw(first last age)
});
# prints something like:
insert people (
first,
last,
age
)
values (
'mitch', -- first
NULL, -- last
11, -- age
)
print $printer->delete({
age => 11,
first => 'mitch',
last => undef
});
# prints something like:
delete people
where first = 'mitch'
and last is null
and age = 11
Or maybe an interface like this would be better:
$printer->sql('insert', {
age => 11,
first => 'mitch',
last => undef
});
# prints this:
#insert people (age, first,last) values(11, 'mitch', NULL)
$printer->placeholder_sql('insert', {
age => 1,
first => 1,
last => 1
});
# prints this:
# insert people (age, first, last) values (?, ?, ?)
> -----Original Message-----
> From: Keith Jackson [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, March 11, 2003 8:40 AM
> To: Tim Bunce
> Cc: [EMAIL PROTECTED]
> Subject: Re: shortcuts for common placeholder idioms...
>
>
> my 2 cents... You can't just blindly take form names from the query
> object and try to stuff them in a table. I have function that I call
> first that determines the common fields between the form and my table.
> Then I create the insert/update statement. Thanks Tim for the "x @cols"
> clause. Going to change my code to use it.
>
>
>
> sub commonFields{
> my $table = shift;
> my $query = shift;
> my $dbh = shift;
> my %mark;
>
> my $sth=$dbh->prepare("select * from $table where 1=0")|| die
> $dbh->errstr;
> $sth->execute || die $dbh->errstr;
>
> grep($mark{$_}++,@{$sth->{NAME_lc}});
>
> return grep($mark{lc $_},$query->param);
> }
>
>
> On Mon, 2003-03-10 at 17:15, Tim Bunce wrote:
> > > 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.
> --
> Keith Jackson <[EMAIL PROTECTED]>
>
>