in reply to Re: Stringified hash
in thread Stringified hash

You'll want to rewrite that code, so that it's not obfuscated.
my @clauses; my @params; while (my ($k, $v) = each %hash) { push @clauses, "$k = ?"; push @params, $v; } my $query = "SELECT row_id FROM Table WHERE " . join(" AND ", @clauses +);

Then, when you execute that query using DBI, you pass @params to the execute() call. This will close a few security holes you currently have, as well as a few potential bugs. And, it's easier to read. :-)

------
We are the carpenters and bricklayers of the Information Age.

Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

Replies are listed 'Best First'.
Re: Re: Re: Stringified hash
by Anonymous Monk on Apr 12, 2004 at 16:53 UTC
    This way worked out nicely for me. I guess I immediately thought of hash when an array would do. I'm not too worried about security. There is no interface, I'm processing files and loading them into a dB and I'm using ODBC. Thanks for the hand.
    use strict; use warnings; my @array = ( "A = 'a'", "B = 'b'", "C = 'c'", "D = 'd'", "E = 'e'", "F = 'f'" ); print "@array\n"; my $query = 'SELECT row_id FROM Table WHERE '.join(' AND ', @array); print "\n\n$query\n";
      You just lost the whole point of my rewrite. The idea was to use placeholders, which ODBC supports, and allow the driver to do the quoting for you.

      ------
      We are the carpenters and bricklayers of the Information Age.

      Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

Re: Re: Re: Stringified hash
by fizbin (Chaplain) on Apr 12, 2004 at 15:24 UTC
    See, I personally find this much easier to read, but I tend to find each loops generally hard to read. (I recognize that they're sometimes necessary for efficiency reasons, but still consider them ugly) Maybe it's just me.
    my @fields = keys(%hash); my @params = @hash{@fields}; my $query = "SELECT row_id FROM Table WHERE " . join(" AND ", map {"$_ = ?"} @fields);
    If for some reason the interface you have won't accomodate the extra separate @params parameter, you could also do this, though this depends on having the DBI handle available when you're forming the query:
    my @fields = keys(%hash); my $query = "SELECT row_id FROM Table WHERE " . join(" AND ", map {"$_ = " . $dbh->quote($hash{$_})} @fields);
    However, I'd still go with the first, assuming that passing along the @params list is doable.