刚开始用 php 编写,我正在使用 $mysqli->prepare() 函数来准备执行语句,但它一直失败,我不知道为什么。 $mysqli->error 中的错误是“没有使用表”,我似乎也找不到太多相关文档...如果有人可以提供帮助,我将不胜感激。代码如下:
$datasqli=new mysqli(HOST, USERNAME, PASSWORD, DATABASE); // defined elsewhere
if ($datasqli->connect_errno) {
printf("Connect failed: %s\n", $datasqli->connect_error);
exit();
}
if ($usertest = $datasqli->prepare("INSERT INTO eeg (Identifier)
SELECT * FROM (SELECT ? ) AS tmp WHERE NOT EXISTS (
SELECT Identifier FROM eeg WHERE Identifier = ?
) LIMIT 1")) {
// this stuff never gets executed...
} else {
echo $datasqli->error; // "no table used"
}
我尝试直接在 mysql 环境中执行该代码块,它工作得很好。
最佳答案
显然,
SELECT * FROM (SELECT ? )
...未被识别为有效的 MySQL 语法。缺少表名。
编辑,关于您的评论:
首先,请注意,通过用常量替换 ?
在控制台中执行此语句并不能模拟您的情况,因此我认为结果无法进行比较。
但是话又说回来,执行它而不替换?
自然会给出错误。
那是因为仅执行选择与您的情况无关。在您的 php 代码中,失败的不是执行,而是准备。因此,使用控制台模拟此操作的正确方法是 PREPARE
声明。
所以做一个
PREPARE myStmt
FROM 'SELECT * FROM (SELECT ? ) AS tmp WHERE NOT EXISTS (
SELECT Identifier FROM eeg WHERE Identifier = ?
) LIMIT 1'
会更准确地重现您的问题。
现在,PREPARE
似乎很难理解出现在 FROM
子句中的参数化嵌套查询。看看这些例子:
PREPARE myStmt FROM "select * from (select ? from eeg) tmp";
(不起作用)
PREPARE myStmt FROM "select *,? from (select * from eeg) tmp";
(有效)
PREPARE myStmt FROM "select *,? from (select 'asdf') tmp";
(有效)
PREPARE myStmt FROM "select * from eeg where Identifier in (select ?)";
(有效)
奇怪的行为,但我只能猜测当FROM
子句中的嵌套SELECT
具有参数时,MySQL缺少准备语句的线索。
至于我的建议,如果我理解您想要做什么,那么您不需要在嵌套选择中使用参数。为了 FROM
,您可以将其移到外部并在嵌套选择中硬编码一个常量。代码如下
if ($usertest = $datasqli->prepare("INSERT INTO eeg (Identifier)
SELECT ? from (select 1) tmp WHERE ? NOT IN
(SELECT Identifier FROM eeg WHERE Identifier = ?)")) {
...应该可以解决问题。
关于php - mysqli-准备语句失败,错误为 "no table used",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19258448/