我有PDO的问题,我真的很想被它困扰了相当长的一段时间后得到一个答案。
就拿这个例子:
我绑定ID的数组的PDO语句在MySQL在语句中。
所述阵列将被说:$值=阵列(1,2,3,4,5,6,7,8);
数据库安全变量将是$产品=破灭(“” $值);
所以,$产品将被用的值的字符串 :“1,2,3,4,5,6,7,8”
该语句将如下所示:
SELECT users.id
FROM users
JOIN products
ON products.user_id = users.id
WHERE products IN (:products)
当然,$产品将被绑定到该语句为:产品 。
然而,当语句被编译和价值观念的约束,它实际上是这样的:
SELECT users.id
FROM users
JOIN products
ON products.user_id = users.id
WHERE products IN ('1,2,3,4,5,6,7,8')
问题是,它是在报表内因为我已经准备了它作为逗号分隔值绑定到语句执行的一切作为一个字符串。
我实际上需要的是:
SELECT users.id
FROM users
JOIN products
ON products.user_id = users.id
WHERE products IN (1,2,3,4,5,6,7,8)
实际上,我可以做到这一点的唯一方法是通过将字符串本身内的值没有结合他们,但我知道肯定必须有这样做的更简单的方法。
Answer 1:
这是同样的事情,有人问这样一个问题: 我能否数组绑定到IN()条件?
答案有,对于在一个可变大小的列表in
条款,你需要自己构造查询。
但是,您可以通过使用引号,逗号分隔的列表find_in_set
,但对于大数据集,这将有相当大的性能影响,因为表中的每个值必须转换为char类型。
例如:
select users.id
from users
join products
on products.user_id = users.id
where find_in_set(cast(products.id as char), :products)
或者,作为第三个选择,你可以创建一个用户定义函数分割为你的逗号分隔的列表(参见http://www.slickdev.com/2008/09/15/mysql-query-real-values-从分隔符分隔的字符串的IDS / )。 这可能是三者的最佳选择,尤其是如果你有很多依赖于查询in(...)
的条款。
Answer 2:
处理这种情况的一个好方法是使用str_pad
放置?
在SQL查询中的每个值。 然后,你可以通过值(在你的案件的数组$values
)作为执行参数:
$sql = '
SELECT users.id
FROM users
JOIN products
ON products.user_id = users.id
WHERE products.id IN ('.str_pad('',count($values)*2-1,'?,').')
';
$sth = $dbh->prepare($sql);
$sth->execute($values);
$user_ids = $sth->fetchAll();
这样,您使用预处理语句,而不是直接插入值到SQL得到更多的好处。
PS - 结果将返回重复的用户ID,如果给定的IDS产品分享用户ID。 如果你只是想唯一的用户ID,我建议更改查询的第一行SELECT DISTINCT users.id
Answer 3:
最好准备的语句你也许可以想出在这样的情况是类似下面:
SELECT users.id
FROM users
JOIN products
ON products.user_id = users.id
WHERE products IN (?,?,?,?,?,?,?,?)
那么您需要通过你的价值观循环并将其绑定到准备好的语句确保有相同数量的问号作为值要绑定。
Answer 4:
你需要在请在 $值阵列提供相同数量的?S作为值的数量
这可以很容易地通过创建的阵列做什么?S作为
$in = join(',', array_fill(0, count($values), '?'));
和你的IN子句中使用$阵列
这将动态地为您提供量身定制的阵列?的 ,按您的changiing $值数组
Answer 5:
你可以这样做很容易。 如果您有值的数组,你的IN()语句EG:
$test = array(1,2,3);
你可以简单地做
$test = array(1,2,3);
$values = count($test);
$criteria = sprintf("?%s", str_repeat(",?", ($values ? $values-1 : 0)));
//Returns ?,?,?
$sql = sprintf("DELETE FROM table where column NOT IN(%s)", $criteria);
//Returns DELETE FROM table where column NOT IN(?,?,?)
$pdo->sth = prepare($sql);
$pdo->sth->execute($test);
Answer 6:
如果表达式是基于用户输入而不结合与bindValue()的值,实验SQL可能不是一个很好的选择。 但是 ,你可以把它安全通过检查输入与MySQL的REGEXP的语法。
例如:
SELECT *
FROM table
WHERE id IN (3,156)
AND '3,156' REGEXP '^([[:digit:]]+,?)+$'
Answer 7:
下面是一个未知的号码记录列的结合值的插入件的例子。
public function insert($table, array $data)
{
$sql = "INSERT INTO $table (" . join(',', array_keys($data)) . ') VALUES ('
. str_repeat('?,', count($data) - 1). '?)';
if($sth = $this->db->prepare($sql))
{
$sth->execute(array_values($data));
return $this->db->lastInsertId();
}
}
$id = $db->insert('user', array('name' => 'Bob', 'email' => 'foo@example.com'));
Answer 8:
请尝试这样的:
WHERE products IN(REPLACE(:products, '\'', ''))
问候
文章来源: PDO binding values for MySQL IN statement