mysqli--准备语句失败,错误“没有使用表”

时间:2013-10-08 21:08:02

标签: php mysql sql mysqli prepare

在php中编写新内容,我正在使用$ mysqli-> prepare()函数来准备执行语句,但它仍然失败,我不知道为什么。 $ mysqli->错误中的错误是“没有使用表格”,我似乎无法找到很多文档...如果有人可以提供帮助,那将非常感激。代码如下:

$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环境中执行该代码块,它运行正常。

1 个答案:

答案 0 :(得分:2)

显然,

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 ?)"; 

(作品)

好奇的行为,但我只能猜测SELECT子句中的嵌套FROM有参数时,MySQL为了准备语句而缺少线索。 / p>

至于我的建议,如果我理解你要做什么,你就不需要嵌套选择中的参数。为了FROM,您可以将其移到外部并在嵌套选择中对常量进行硬编码。以下代码

if ($usertest = $datasqli->prepare("INSERT INTO eeg (Identifier) 
    SELECT ? from (select 1) tmp WHERE ? NOT IN
      (SELECT Identifier FROM eeg WHERE Identifier = ?)")) {

......应该这样做。