注意:我认为这个问题可能是PDO驱动程序中的严重问题。我几乎可以理解数组和字符串之间的区别。因此,请在删除或 duplicate 之前考虑在沙盒上对此进行测试。
$pdo = db()->getInstance();
$sql = "SELECT * FROM clients WHERE client_id IN :clients";
$params = [ ":clients" => "(223,224,225)" ];
$stmt = $pdo->prepare($sql);
try{
$stmt->execute($params);
} catch( \Exception $e){
die("Query Execution Failed" . $e->getMessage());
}
查询执行失败SQLSTATE [42000]:语法错误或访问 违规:1064您的SQL语法有错误;检查手册 对应于您的MySQL服务器版本,以获得正确的语法 在第1行''(223,224,225)'附近使用
这里的问题不是转换为:
SELECT * FROM clients WHERE client_id IN (223,224,225)
它正在翻译为:
SELECT * FROM clients WHERE client_id IN '(223,224,225)'
这里没有数组。我只是提供一个参数客户端来替换:clients
。 为什么要添加quotes
?
答案 0 :(得分:0)
首先,我(有点)同意你的看法。这是一个问题,不是很严重的问题。也许他们故意保留它。或者,也许你的愚蠢问题有一些争论的潜力。
每个PDO参数都包含引号。 (我个人认为不应该这样)。当您一次传递
IN
字符串时,它会在其周围放置引号,但查询失败。但是,您可以使用单个项目(放置引号)。因此,将参数传递给每个项目,而不是之前准备字符串。
现在,解决方案:
$pdo = db()->getInstance();
$sql = "SELECT * FROM clients WHERE client_id IN :clients";
$clients = [223,224,225];
/* You could use bind with ? here. I am just making this with named parameters so that you could echo SQL */
$params = [];
$replacement = [];
foreach ($clients as $key => $value){
$replacement[] = ":client$key";
$params[":client" . $key] = $value;
}
$sql = str_replace(":clients", "(" . implode(",",$replacement) . ")", $sql);
echo $sql;
/* SELECT * FROM clients WHERE client_id IN (:client0,:client1,:client2) */
$stmt = $pdo->prepare($sql);
try{
$stmt->execute($params);
print_pre($stmt->fetchAll(PDO::FETCH_ASSOC));
} catch( \Exception $e){
die("Query Execution Failed" . $e->getMessage());
}
这就像一个魅力。我尝试创建一个虚拟客户端表。但问题是你的实际SQL现在变成了:
SELECT * FROM clients WHERE client_id IN ('223','224','225')
大多数人可能不会对此大肆宣传,但您可能会失去一些性能,因为查询将id转换为带引号的字符串,尤其是您拥有大型数据库,复杂查询和首选整数。