Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: Module for substituting complex criteria into hand-written SQL queries

by 1nickt (Abbot)
on Apr 16, 2017 at 17:31 UTC ( #1188055=note: print w/replies, xml ) Need Help??


in reply to Module for substituting complex criteria into hand-written SQL queries

Check out SQL::Abstract::More, which extends the parent class with more flexible functionality (and uses named params, Blessed Be!)

So you can do something like:

my $sqla = SQL::Abstract::More->new; my $time = time; my $status = 'active'; my ( $sql, @bind ) = $sqla->select( # new users yesterday -columns => 'id, name', -from => 'users', -where => { status => $status, first_seen_time => { '>' => $time - 86400, '<=' => $time, }, }, );
Output:
$sql: 'SELECT id, name FROM users WHERE ( ( ( first_seen_time <= ? AND + first_seen_time > ? ) AND status = ? ) )'; \@bind: [ 1492373509, 1492287109, 'active' ];
As you can see this SQL builder often adds unnecessary parentheses; I don't worry about these since any decent RDBMS will optimize them away.

update: added example and then example output

Hope this helps!


The way forward always starts with a minimal test.

Replies are listed 'Best First'.
Re^2: Module for substituting complex criteria into hand-written SQL queries
by Dallaylaen (Chaplain) on Apr 16, 2017 at 20:32 UTC

    Thanks for your reply! SQL::Abstract::More looks powerful, but that is a slightly different approach from what I would like. It seems like it's about generating complex SQL queries from a data structure.

    I'm fine with using SQL itself as a DSL to describe SQL. However, sometimes a condition more complex than just parameter = ? is not known beforehand. E.g. we don't know whether user wants dates after, before, or between certain point(s), but the rest of the query is still the same. In such cases pre-written SQL is not enough. I usually end up concatenating generated and pre-written parts of query by hand. Possibly not the most efficient way, but that's what I'm comfortable with.

    So I think there may be a tool that automates it by patching a pre-written query with some condition group(s). Hard to figure out what I'm really looking for... If I knew for sure, I'd just google instead of asking...

      There is no reason you can't build your parameters based on runtime conditions:

      my $cutoff = time - 86400; my $first_seen_time = {}; if ( $user_wants_dates_before_today ) { $first_seen_time = { '<' => $cutoff, }; } else { $first_seen_time = { '>=' => $cutoff, }; ); my ( $sql, @bind ) = $sqla->select( -columns => 'id, name', -from => 'users', -where => { status => $status, first_seen_time => $first_seen_time, }, );

      Also, for another approach, remember that you can insert actual SQL into the parameters to a SQLA call, and you could generate *that* SQL snippet based on your run-time conditions.

      Hope this helps!


      The way forward always starts with a minimal test.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1188055]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (6)
As of 2022-01-28 17:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    In 2022, my preferred method to securely store passwords is:












    Results (73 votes). Check out past polls.

    Notices?