Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I select rows that are null using bound queries in Perl's DBI?

Tags:

sql

perl

dbi

I want to be able to pass something into an SQL query to determine if I want to select only the ones where a certain column is null. If I was just building a query string instead of using bound variables, I'd do something like:

if ($search_undeleted_only)
{
    $sqlString .= " AND deleted_on IS NULL";
}

but I want to use bound queries. Would this be the best way?

my $stmt = $dbh->prepare(...
    "AND (? = 0 OR deleted_on IS NULL) ");
$stmt->execute($search_undeleted_only);
like image 555
Paul Tomblin Avatar asked Jan 11 '09 20:01

Paul Tomblin


3 Answers

Yes; a related trick is if you have X potential filters, some of them optional, is to have the template say " AND ( ?=-1 OR some_field = ? ) ", and create a special function that wraps the execute call and binds all the second ?s. (in this case, -1 is a special value meaning 'ignore this filter').

Update from Paul Tomblin: I edited the answer to include a suggestion from the comments.

like image 63
SquareCog Avatar answered Oct 28 '22 11:10

SquareCog


So you're relying on short-circuiting semantics of boolean expressions to invoke your IS NULL condition? That seems to work.

One interesting point is that a constant expression like 1 = 0 that did not have parameters should be factored out by the query optimizer. In this case, since the optimizer doesn't know if the expression is a constant true or false until execute time, that means it can't factor it out. It must evaluate the expression for every row.

So one can assume this add a minor cost to the query, relative to what it would cost if you had used a non-parameterized constant expression.

Then combining with OR with the IS NULL expression may also have implications for the optimizer. It might decide it can't benefit from an index on deleted_on, whereas in a simpler expression it would have. This depends on the RDBMS implementation you're using, and the distribution of values in your database.

like image 43
Bill Karwin Avatar answered Oct 28 '22 11:10

Bill Karwin


I think that's a reasonable approach. It follows the normal filter pattern nicely and should give good performance.

like image 28
Michael Haren Avatar answered Oct 28 '22 10:10

Michael Haren