- 2012/11/24 Sat
-
SQLiteのプレースホルダ展開でちょっと悩んだのでメモ。
環境は perl-5.12.3。最初の状態
use strict; use warnings; use DBI; my $dbh = DBI->connect("dbi:SQLite:dbname=foo.db"); my $q =<<EOS; select foo from foo --where foo & 2 = 2 --OK 直接だと選択される。 where foo & ? = ? --NG プレースホルダにすると選択されなくなる。 EOS my $sth = $dbh->prepare($q); #$sth->execute(); $sth->execute(2, 2); print $_->[0], "\n" while $_ = $sth->fetch;
あれこれ試す
where foo & 2 = ? --NG 右辺だけにしてもだめ。 where (foo & 2) = ? --NG 評価順の問題でもない。 where foo & ? = 2 --OK 左辺だけなら問題ない。 where ? = foo & 2 --NG 左右を入れ替えてもだめ。
右辺の評価に問題がある気がしたのでキャスト
where foo & ? = cast(? as int) --OK where foo & ? = abs(?) --OK ついでに試してみる。 where foo & ? = round(?) --OK 同上。
左辺は演算で暗黙に型変換されているのに対して、右辺が数値として評価されていないと。追加検証
where foo & '2' = 2 --OK where foo & '2' = '2' --NG where foo & '2' = cast('2' as int) --OK