SQL so close I can paste it (YAPC::NA::2011 lightning talk)

921 views

Published on

My lightning talk from YAPC 2011 in Asheville, NC

I wanted to log prepared sql statements with their bind variables included in-line. This hack gets me there. It may be useful to you too.

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
921
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
1
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

SQL so close I can paste it (YAPC::NA::2011 lightning talk)

  1. 1. SQL so close I can paste it YAPC::NA::2011 Asheville Brad Oaks Plus Three, LP
  2. 2. printfprintf person_id %d name: %s, $person_id, $person->name;
  3. 3. printf with format as a variablemy $fmt = person_id %d name: %s;printf $fmt, $person_id, $person->name;
  4. 4. dynamically building a querymy (@conds, @binds);my $joins = ;my @uuids = $self->get_story_uuids;
  5. 5. add to your JOINsif( @uuids ) { $joins .= JOIN volunteer_form vfON(civ.volunteer_form_id =vf.volunteer_form_id);}
  6. 6. add to your conditionsif( @uuids ) { push(@conds, vf.story_uuid IN ( . join(, , (?) x scalar(@uuids)) . )); push(@binds, @uuids);}
  7. 7. assemble WHERE clausemy $where = @conds ? WHERE . join( AND , @conds) : ;
  8. 8. assemble the larger querymy $sql = qq/SELECTCOUNT(DISTINCT(civ.contact_info_id)) ASvolunteers FROM contact_info_volunteer civ JOIN contact_info ci ON (ci.contact_info_id= civ.contact_info_id) $joins $where /;
  9. 9. prepare_cachedmy $sth = $dbh->prepare_cached($sql);$sth->execute(@binds);my $data = $sth->fetchrow_hashref();$sth->finish();
  10. 10. log the querymy $sth = $dbh->prepare_cached($sql);my $sql_fmt = $sql;$sql_fmt =~ s/?/%s/g;warn sprintf $sql_fmt, @binds;
  11. 11. output in your logs (before) SELECT COUNT(DISTINCT(civ.contact_info_id)) AS volunteers FROM contact_info_volunteer civ JOIN contact_info ci ON (ci.contact_info_id = civ.contact_info_id) JOIN volunteer_form vf ON(civ.volunteer_form_id = vf.volunteer_form_id)WHERE vf.story_uuid IN ( ?, ?)$VAR1 = [1234,5678];
  12. 12. output in your logs (after)SELECT COUNT(DISTINCT(civ.contact_info_id)) AS volunteersFROM contact_info_volunteer civJOIN contact_info ci ON (ci.contact_info_id = civ.contact_info_id)JOIN volunteer_form vf ON(civ.volunteer_form_id = vf.volunteer_form_id)WHERE vf.story_uuid IN ( 1234, 5678)
  13. 13. log the querymy $sth = $dbh->prepare_cached($sql);my $sql_fmt = $sql;$sql_fmt =~ s/?/%s/g;warn sprintf $sql_fmt, @binds;

×