何者にもなれていない5年目のエンジニアブログ

SQL::Absract のselectのwhere句に空のリストを入れた時の挙動

SQL::Abstractは本当に便利。

http://search.cpan.org/~ribasushi/SQL-Abstract-1.77/lib/SQL/Abstract.pm

(´-`).。oO(引き数渡したら、自動的SQL文作ってくれないかな)

と、思っていても大抵のことはできちゃいます。ですが、便利だけど

魔法の箱

になりがちです。

引き数によってどういったSQL文が生成されるかについて、出力される$stmt、@bindの値を心配ならprintなりして、見ておいた方がいいです。(ソースコードも)

SQL::Abstractのselectですが、非常に便利でwhere句に指定した値で自動的SQL文を生成してくれます。

例:

# 引き数にユーザー情報(例:$users = [1,2,3]
$users = shift; 

my %where = (
       user_id => $users,  #( usersにはuser_id = 1, 2, 3 が入る)
    );

    my($stmt, @bind) = $sql->select('table', '*', \%where);

上の例は次のようになる:

    $stmt = "SELECT * FROM table WHERE
                  ( user_id = ? OR user_id = ? OR user_id = ? )";
    @bind = (1, 2, 3);

便利ですね

ですが、ここで、usersに空のリストが入ってきた時、どういったSQL文が生成されるか気になりました。というのは、whereでuser_idが指定されない場合、DBを全部参照してしまうのかも、、と不安があったからです。(例:$stmt = "SELECT * FROM table")

結果は、 "SELECT * FROM table WHERE ( 0=1 )"; となり、空振りするようになりました。 これであれば問題ないですね。参考までに

# 引き数に空のリスト(例:$users = [];
$users = shift; 

my %where = (
       user_id => $users,  #( usersには[] が入る)
    );

    my($stmt, @bind) = $sql->select('table', '*', \%where);

上の例は次のようになる:

    $stmt = "SELECT * FROM table WHERE
                  ( 0=1 )";
    @bind = ();