这是代码:
<?PHP
$dbh = new \PDO('sqlite:');
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$goodsql = 'SELECT number FROM (SELECT 1 number UNION SELECT 2) numbers WHERE number not in (2)';
echo json_encode($dbh->query($goodsql)->fetchAll(PDO::FETCH_NUM));
$badsql = 'SELECT number FROM (SELECT 1 number UNION SELECT 2) numbers WHERE number not in (?)';
$binds = ['2'];
$statement = $dbh->prepare($badsql);
$statement->execute($binds);
echo json_encode($statement->fetchAll(PDO::FETCH_NUM));
?>
第一条语句成功地从结果中排除了2.排除由内联sql条件NOT IN(2)指定.
第二条语句未能从结果中排除2.通过条件NOT IN(?)中参数2的PDO绑定指定排除.
在PDO / MysqL中,这两个语句产生相同的结果.
怎么了?这是错误还是已记录了结果?
附言我已经在所有使用https://3v4l.org/otfDj的PHP版本上对此进行了测试,并获得了与5.6.0-5.6.30、7.0.0-7.2.0alpha2相同的结果.
解决方法:
这是因为execute
将传递的参数视为字符串.
因此,您的查询变为
$badsql = 'SELECT number FROM (SELECT 1 number UNION SELECT 2) numbers WHERE number not in ("2")';
绝对没有结果等于“ 2”.
$badsql = 'SELECT number FROM (SELECT 1 number UNION SELECT 2) numbers WHERE number not in (?)';
$binds = ['2'];
$statement = $dbh->prepare($badsql);
$statement->bindValue(1, '2', PDO::ParaM_INT); // this is it
$statement->execute();
echo json_encode($statement->fetchAll(PDO::FETCH_NUM));