使用 MySql、PHP 和 ADODB 在准备好的语句中参数化 IN 子句

Posted

技术标签:

【中文标题】使用 MySql、PHP 和 ADODB 在准备好的语句中参数化 IN 子句【英文标题】:Parameterised IN Clause in prepared statement using MySql,PHP and ADODB 【发布时间】:2012-05-28 17:41:20 【问题描述】:

我正在编写一些 SQL 并使用 AdoDb 连接到我的数据库并运行查询等。我正在使用参数化查询并遇到了障碍。

他们是一种将值数组传递给 AdoDb/mysql 中的 in_clause 以进行参数化的方法。

我的问题是,如果我将准备好的字符串作为参数传递,即 'test','test2','test3' 它不起作用,因为库或数据库会自动转义它并添加外部开头和结尾的引号,因此所有内部引号都会自动转义,因此查询在查找 '\'test\',\'test2\',\'test3\'' 时不返回任何内容而不是我喂它的。

更新了另一种可能的方法来完成此操作

<?php
$in_clause = implode(",", $first_names);

$query = "
SELECT    
    mytable_id_pk
FROM 
    mytable
WHERE
FIND_IN_SET(mytable_fname," . $DB->Param('first_names') . ")"

$stmt = $DB->Prepare($query);

$result = $DB->Execute($stmt,array($in_clause));
?>

【问题讨论】:

【参考方案1】:

我会这样做(因为我在谷歌上搜索了一段时间,谷歌没有找到任何有用的东西):

$count = count($first_names);
$in_params = trim(str_repeat('?, ', $count), ', ');

$query = "
SELECT    
    mytable_id_pk
FROM 
    mytable
WHERE
    mytable_fname IN ($in_params);";

$stmt = $DB->Prepare($query);
$result = $DB->Execute($stmt, $first_names);

应该这样做...

【讨论】:

谢谢你,我自己一直在想这样的事情。我还遇到了另一个效果很好的解决方案,我将用它更新上面的问题。再次感谢,我很感激。 谢谢我用这种方式【参考方案2】:

首先有几点提示:

    请仔细阅读有关准备好的语句的 AdoDB 文档。 从不包括 ;在 SQL 查询字符串中。

你可以试试这样的:

$question_marks = substr(str_repeat('?,', count($first_names)), 0, -1);

$query = "SELECT mytable_id_pk FROM mytable WHERE mytable_fname IN (" . $question_marks . ")";
$stmt = $DB->Prepare($query);
$result = $DB->Execute($stmt,$first_names);

警告:我没有对此进行测试(这里没有安装 mySQL)。

【讨论】:

为什么不包括分号?我很好奇原因,因为我在每个查询末尾使用分号对 mysql 使用了一年...我知道当移动到其他 DBMS 时我必须修复每个查询,但是还有其他明智的理由吗? @shadyyx 好吧,mysqli_multi_query 你当然可以包含分号。另一方面,mysql_query doc 明确表示:'查询字符串不应以分号结尾。' 这种禁止的确切原因尚不清楚(不仅对我而言,正如我从最近的谷歌搜索)。然而,它完全没用,并且对可读性产生负面影响(好吧,这很主观......) 感谢您的意见。我确实已经阅读了 adodb 文档,实际上我已经搜索过它以获取有关这一点的信息并且没有,所以我问这个问题是否有任何其他创新方法。

以上是关于使用 MySql、PHP 和 ADODB 在准备好的语句中参数化 IN 子句的主要内容,如果未能解决你的问题,请参考以下文章

从 PHP ADODB MySQL 循环中获取最后一行值

MySQL & PHP 更新问题,使用准备好的语句

如何在 php 中创建安全的 mysql 准备语句?

MySQL准备好的语句在PHP中抛出错误

不使用ADODB php库代码以数字方式填充表

运行准备好的语句 (MySQL/PHP)