わいえむねっと

Contents
Categories
Calendar
2012/11
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30
Monthly Archives
~2000/01
Recent Entries
RSS1.0
Templates
Information
Processed: 0.018 sec
Chashed: -
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