Class::DBI::AbstractSearch で NULL を指定

Class::DBI::AbstractSearch は、search_like とか search だけでは手が届かない時用なのですが、説明みても、not null とか null を指定する方法がかいてなかったので、 ちょっとあがいてみた(3分くらい)。

結論から言うと、

$where->{column} = {'is null' , undef}
のように書けばいい。2つめがundef だとプレースホルダが作成されないので、 そのまま通るようだ。

だが、このままでは、is not null が通らない。

$where->{column} = {'is not null' , undef}

とか書いても、うまくいかないので、おかしいなと思ったんですが、

SQL/Abstract.pm
L715 付近
# undef = null
$self->_debug("UNDEF($k) means IS NULL");
push @sqlf, $label . $self->_sqlcase(' is null');

えええええええ

と思ったんですが、コードみてたら説明に

Finally, sometimes only literal SQL will do. If you want to include
literal SQL verbatim, you can specify it as a scalar reference, namely:

my $inn = 'is Not Null';
my %where = (
   priority => { '<', 2 },
      requestor => \$inn
      );

This would create:

$stmt = "WHERE priority < ? AND requestor is Not Null";
@bind = ('2')

な ん だ と … !

しかし、is null については、コード以外に説明は見当たらず。

つまり

my $notnull = 'IS NULL';
my $isnotnull = 'IS NOT NULL';
$where->{column1} = \$notnull;
$where->{column2} = \$isnotnull;

のように書けばいいようです。

is null に関しても、多分後者の方で書くべきなのかもですが、 前者もきちんとコメントに書かれているわけですし、 間違いではないのかと思います。

まとめ:
スカラリファレンスで渡すと、何も処理しないでそのまま扱ってくれる。

ちなみに、where部分がどうなってるか見る場合は、

use SQL::Abstract;
my @wheresql = SQL::Abstract->new->where($where);
print $wheresql[0];

とすれば見ることができます。

team mukya 2009