php - 使用 PDO 进行动态列表查询

标签 php mysql pdo

我一直在研究这个问题,但我似乎无法独自解决它。我遇到了 PDO 和 MYSQL 的已知问题/功能,导致我使用以下代码。

我正在数据库中搜索符合多个条件的标记 ID。我遇到了一个 MYSQL 错误,它似乎迫使我使用一个临时表来存放我的一些结果,然后再进行第二次处理。 PDO 不会让我在第一次执行后引用临时表(我可能做错了)或者让我准备多条语句,所以它会引导我为这个调用创建一个存储过程。在最近的一些测试之后,我发现 PDO 的另一个问题/功能不允许我以我正在寻找的方式调用存储过程。

这是SP:

DELIMITER $$
CREATE PROCEDURE sp_searchPrevArticles(IN tagList VARCHAR(255), IN firstArticle INT(10))
BEGIN

CREATE TEMPORARY TABLE at_results (
id INTEGER(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
article_id INTEGER(10) NOT NULL,
datetime DATETIME NOT NULL,
common_tags INTEGER NOT NULL)
SELECT at.article_id, art.datetime, Count(at.article_id) AS common_tags
FROM article_tags AS at 
INNER JOIN articles AS art ON at.article_id = art.article_id
WHERE at.tag_id IN (tagList)
GROUP BY at.article_id
ORDER BY common_tags DESC, art.datetime DESC;

CREATE TEMPORARY TABLE at_article
SELECT id
FROM at_results
WHERE article_id = firstArticle;

SELECT article_id
FROM at_results, at_article
WHERE at_results.id < at_article.id
ORDER BY at_results.id DESC;

END $$
DELIMITER ;

无法正常工作的参数是 tagList。我用

创建 tagList
foreach ($tag_ids as $tag) {
    $tag_list = ($tag_list . $tag . ",");
}
$tag_list = rtrim($tag_list, ',');

这为我提供了标签 ID 的动态列表。为此,我们可以说“4,3,2,1”。当我在没有 PDO 的情况下运行此 SP 时,它会返回正确的数据集。每当我使用 PDO 运行它时,它只会给我列表中的第一个标签。在这种情况下,它只会返回“4”的结果。

我的 PDO 调用是:

$sql = "CALL sp_searchPrevArticles(:tag_list, :first_article)";
$tag_sth = $this->db->prepare($sql);
$tag_sth->execute(array(':tag_list' => $tag_list, ':first_article' => $first_article));
$tag_sth->setFetchMode(PDO::FETCH_ASSOC);
$data = $tag_sth->fetchAll();

当我继续以这种方式编写它们时,我不禁认为我正在让自己变得更加困难。我还在学习,这是迄今为止我想出的最好的解决方案。任何人都知道如何使其正常运行吗?

感谢任何帮助。

谢谢!

最佳答案

PDO 很简单地不能正确处理列表,除非它们是静态长度并且定义为 IN(?,?,?,?)。我通过以下方式绕过它:

<?php
$list = '1,2,3,4';
$params = array('a', 'b');

$query = "SELECT * FROM TABLE WHERE thing = ? AND other = ? AND more IN (%s)";
$query = sprintf($query, $list);

$rs = $dbh->doQuery($query, $params);

这很杂乱,但我还没有看到 PHP 关于动态长度列表的真正解决方案。

我只是想到了一种更丑陋但更合规的写法:

<?php
$list = array(1,2,3,4); //pretend this is dynamic, and always has at least one member
$params = array('a','b');
$query = "SELECT * FROM TABLE WHERE thing = ? AND other = ? AND more IN (%s)";

$placeholders = '?';
for($i=0; $i<count($list); $i++) {
    $placeholders .= ',?';
}
$query = sprintf($query, $placeholders);
$params = array_merge($params, $list);

$rs = $dbh->doQuery($query, $params);

这是粗略而笼统的,但你明白了。除非您真的致力于绝对参数化我更喜欢第一个片段的所有内容。

关于php - 使用 PDO 进行动态列表查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13732622/

相关文章:

php - 使用 dbDelta 函数在 Wordpress 中创建表

mysql - Insert ... on duplicate key update nothing 使用MySQL

php - 使用 PDO 和 OOP 的 MySQL 查询问题

Php PDO Mysql插入错误1064

php - 将参数传递给来自 url 的 select 语句

php - PIN 支付错误 - 找不到供应商/autoload.php

php - AJAX 调用后在完成的重定向页面上加载事件

php - 是否可以使用 XMLHttpRequest 评估 JavaScript 代码

mysql - 理解EXPLAIN创建列索引的依据

mysql - 将 MySQL XML 输出字段名转换为可用的标签名称