联合选择变量,在PHP中使用PDO。怎么做对了?

时间:2013-12-20 11:48:15

标签: php mysql sql pdo

我正在尝试运行一个返回随机行的查询,并且该行周围有两行(上一行和下一行)。

我已将随机结果值保存在变量中,以便所有以下查询都可以使用它。

我的查询如下:

SET @rand := (SELECT CEIL(RAND() * MAX(id)) FROM data); 
(SELECT * FROM `data` where `id` < @rand AND safe = 1 ORDER BY ID DESC LIMIT 1) UNION 
(SELECT * FROM `data` where `id` = @rand AND safe = 1 ORDER BY ID DESC LIMIT 1) UNION
(SELECT * FROM `data` where `id` > @rand AND safe = 1 ORDER BY ID ASC LIMIT 1);

@rand确实包含有效的随机ID。

事实证明,这是我在大学电脑上使用的phpmyadmin界面上的显示问题。

查询正确执行,并在mysql命令行界面中正确显示行。但是在PHP / pdo中它现在返回

PDOStatement::fetchAll(): SQLSTATE[HY000]: General error

而在查询中没有@rand且使用静态id进行测试的相同代码,它会按预期返回3行。

3 个答案:

答案 0 :(得分:0)

您已设置该查询,使其最多返回3行,因为您为每3次查询使用了LIMIT 1

另一方面,尽管如此,您还使用

对这些查询应用了过滤
where id > @rand

那么,你怎么能期望超过3行?

可能是以前的&amp;下一行,你可以使用这个逻辑,

SELECT * FROM `data` where `id` < @rand ORDER BY ID DESC LIMIT 1
UNION
SELECT * FROM `data` where `id` = @rand LIMIT 1
UNION
SELECT * FROM `data` where `id` > @rand ORDER BY ID ASC LIMIT 1

会更好一点。

答案 1 :(得分:0)

您可以通过这种方式获得结果

SELECT * 
FROM `data` 
where `id` between @rand-1 and @rand+

确定。然后你可以试试这个

SET @rand := (SELECT CEIL(RAND() * MAX(id)) FROM data);

 SELECT top 1 * FROM `data` where `id` < @rand AND safe = 1 ORDER BY ID DESC
 UNION 
 SELECT top 1 * FROM `data` where `id` = @rand AND safe = 1 
 UNION 
 SELECT top 1 * FROM `data` where `id` > @rand AND safe = 1 ORDER BY ID ASC

答案 2 :(得分:0)

我怀疑PDO在运行两个SQL语句时遇到问题。我将创建一个存储过程来运行语句并使用PDO来调用存储的proc:

CREATE PROCEDURE spGetThreeRandomRows()
BEGIN
    @rand := (SELECT CEIL(RAND() * MAX(id)) FROM data); 
    (SELECT * FROM `data` where `id` < @rand AND safe = 1 ORDER BY ID DESC LIMIT 1) UNION 
    (SELECT * FROM `data` where `id` = @rand AND safe = 1 ORDER BY ID DESC LIMIT 1) UNION
    (SELECT * FROM `data` where `id` > @rand AND safe = 1 ORDER BY ID ASC LIMIT 1);
END; 

然后这样称呼:

$stmt = $dbh->prepare("CALL spGetThreeRandomRows()");
$stmt->execute();