我想从表中随机选择行,并从这里的其他问题中获得了以下代码,但我有点困惑于将表名和列名放在哪里,因为我以前从未用mysqli做过这样的选择。有人能帮帮我吗?我的表名是products
,列名是title
。
我得到:
Fatal error: Call to a member function execute() on a non-object
这是代码:
SELECT name
FROM random AS r1 JOIN
(SELECT (RAND() *
(SELECT MAX(id)
FROM random)) AS id)
AS r2
WHERE r1.id >= r2.id
ORDER BY r1.id ASC
LIMIT 1
我试过的:
$mydb = new mysqli('localhost', 'root', '', 'db');
$stmt = $mydb->prepare("SELECT title
FROM products AS r1 JOIN
(SELECT (RAND() *
(SELECT MAX(id)
FROM random)) AS id)
AS r2
WHERE r1.id >= r2.id
ORDER BY r1.id ASC
LIMIT 1 ");
$stmt->execute();
查看准备后是否有任何错误:
$mydb = new mysqli('localhost', 'root', '', 'db');
$stmt = $mydb->prepare("SELECT title
FROM products AS r1 JOIN
(SELECT (RAND() *
(SELECT MAX(id)
FROM random)) AS id)
AS r2
WHERE r1.id >= r2.id
ORDER BY r1.id ASC
LIMIT 1 ");
if ( false===$stmt ) {
die('prepare() failed: ' . htmlspecialchars($mydb ->error));
}
我最近为我的所有sql函数制作了一个sql驱动程序,获得随机记录就是其中之一。
在阅读评论后,我从这个博客中修改了解决方案#3,这就是我想到的:
<?php
class MyDatabaseDriver {
protected $DBC;
protected $SEL_RANDOM_OFFSET;
protected $SEL_RANDOM_IMAGE;
function __construct($uname, $password, $table="my_table") {
$this->DBC = new mysqli('localhost', $uname, $password, $table);
if ($this->DBC->connect_errno) {
printf("Connect failed: %s'n", $this->DBC->connect_error);
exit;
}
$this->initialize();
}
function __destruct() { $this->close(); }
protected function initialize() {
$this->SEL_RANDOM_OFFSET = $this->DBC->prepare("SELECT ROUND(RAND() * COUNT(*), 0) AS `offset` FROM `images` WHERE `albumid` = ?");
$this->SEL_RANDOM_IMAGE = $this->DBC->prepare("SELECT `filename` FROM `images` LIMIT ?, 1");
}
function close() {
if (!$this->DBC) return;
$this->SEL_RANDOM_OFFSET->close();
$this->SEL_RANDOM_IMAGE->close();
$this->DBC->close();
$this->DBC = false;
}
function SelectRandomImage($gid) {
$result = false;
$this->SEL_RANDOM_OFFSET->bind_param("i", $gid);
$this->SEL_RANDOM_OFFSET->execute();
$this->SEL_RANDOM_OFFSET->bind_result($result);
if (!$this->SEL_RANDOM_OFFSET->fetch()) {
printf("Select random offset failed: %s'n", $this->SEL_RANDOM_OFFSET->error);
$result = false;
$this->SEL_RANDOM_OFFSET->reset();
return $result;
}
$this->SEL_RANDOM_OFFSET->reset();
$this->SEL_RANDOM_IMAGE->bind_param("i", $result);
$this->SEL_RANDOM_IMAGE->execute();
$this->SEL_RANDOM_IMAGE->bind_result($result);
if (!$this->SEL_RANDOM_IMAGE->fetch()) {
printf("Select random image failed: %s'n", $this->SEL_RANDOM_IMAGE->error);
$result = false;
$this->SEL_RANDOM_IMAGE->reset();
return $result;
}
$this->SEL_RANDOM_IMAGE->reset();
return $result;
}
} ?>
afaik,这是目前不同网络主机之间兼容性最好的解决方案(从本地主机迁移到远程主机时,我在使用"get_result"等时遇到了一些问题)。它还考虑到,准备好的语句可以以更好的效率重复多次(关于#3的抱怨之一是必须重复才能得到多个结果),因此对象会被重置并保持活动状态,直到类超出范围或直接调用close。
编辑:在我的OFFSET选择中,我使用"ROUND",因为我的数据库ID列以1开头,如果您的ID列以0开头,您可能需要使用"FLOOR"