DapperDan has asked for the wisdom of the Perl Monks concerning the following question:
This code is supposed to do a SQL insert using the contents of the hash %$c.
In the values section of the SQL statement, I need a string of the form "?,?,?" where there is a ? for each field, and all the ?s are delimited by commas. However, there can not be a trailing comma at the end or syntax errors in the database (PostgreSQL) result.
I tried my $sth = $dbh->prepare(
'INSERT INTO table('
. join(',', keys %$c)
. ") VALUES ("
. chop(join('', map {'?,'} keys %$c))
. ")"
);
I managed to make the code work by taking it out and explicitly assigning the value of the expression to a scalar, $placeholderstr. I would like to inline the rvalue of the first line of this code in the $dbh->prepare() statement. Any ideas?
code: my $placeholderstr = join('', map {'?,'} keys %$c);
chop $placeholderstr;
my $sth = $dbh->prepare(
'INSERT INTO table('
. join(',', keys %$c)
. ") VALUES ($placeholderstr)"
);
$sth->execute(values %$c) or die $dbh->errstr;
Re: Can't I chop the lvalue of join?
by japhy (Canon) on Sep 28, 2002 at 14:19 UTC
|
Can I ask why you're using join(',', keys %$c) in your code, but you're not using join(',', map '?', keys %$c)?
Anyway, since chop() modifies its argument, it must be a variable. But do what I said above.
_____________________________________________________
Jeff[japhy]Pinyan:
Perl,
regex,
and perl
hacker, who'd like a job (NYC-area)
s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??; | [reply] |
|
| [reply] |
|
It does work on lvalues. But the return value of join() is not an lvalue. You can't assign to it.
join('x', qw( a b c )) = "foo";
is a syntax error, whereas
substr($x, 2, 4) = "ouch";
is not, so you can say chop(substr($x, 2, 4)).
_____________________________________________________
Jeff[japhy]Pinyan:
Perl,
regex,
and perl
hacker, who'd like a job (NYC-area)
s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;
| [reply] [d/l] [select] |
|
Re: Can't I chop the lvalue of join?
by broquaint (Abbot) on Sep 28, 2002 at 14:29 UTC
|
Here's another way of building up your query string
my $c = { qw/a bunch of values in a hash here/ };
my @fields = keys %$c;
print 'INSERT INTO table(' . join(',', @fields)
. ') VALUES (?' . ',?' x $#fields . ')';
__output__
INSERT INTO table(of,a,hash,in) VALUES (?,?,?,?)
HTH
_________ broquaint | [reply] [d/l] |
Re: Can't I chop the lvalue of join?
by Aristotle (Chancellor) on Sep 28, 2002 at 18:23 UTC
|
This is very close to broquaint's, but a bit more orthogonal:
print
'INSERT INTO table(' . join(',', @fields)
. ') VALUES (' . join(',', ('?') x @fields)
. ')';
However that's too many parens and single quotes to grok for my taste. Here's what I'd do:
{
local $" = ',';
print "INSERT INTO table(@fields) VALUES (@{[ map '?', @fields]})"
+;
}
Update: or of course, even better
{
local $" = ',';
print "INSERT INTO table(@fields) VALUES (@{[('?') x @fields]})";
}
Update 2002 09 30: it has to be $" of course, not $, -- doh.
Makeshifts last the longest. | [reply] [d/l] [select] |
Re: Can't I chop the lvalue of join?
by chromatic (Archbishop) on Sep 28, 2002 at 16:26 UTC
|
| [reply] |
Re: Can't I chop the lvalue of join?
by bart (Canon) on Sep 29, 2002 at 11:45 UTC
|
In the values section of the SQL statement, I need a string of the form "?,?,?" where there is a ? for each field, and all the ?s are delimited by commas.
Just do
join ',', map "?", keys %$c
or
join ',', ("?") x keys %$c
(preferably the latter.)
And no, you can't chop the result of join directly, though your code (at least, the first two lines) works fine, as does this slightly more compacted version:
chop(my $placeholderstr = join '', map {'?,'} keys %$c);
Your immediate problem must lie elsewhere.
p.s. A combination of your and my ideas resulted in
chop(my $placeholderstr = '?,' x keys %$c);
and it works just fine. | [reply] [d/l] [select] |
|
|