使用MySQLi预处理语句时报错‘No tables used’,如何解决?
解决MySQLi预处理语句报错“No tables used”的问题
这个问题的根源在于MySQLi的预处理解析器对临时子查询的识别方式——你原来的SQL里(SELECT ?) AS tmp这种临时结果集,没有被解析器认定为“使用了表”,所以触发了“No tables used”的错误。我们可以通过改用MySQL的虚拟表DUAL来解决这个问题,同时保持原有的业务逻辑不变。
修改后的SQL语句
把你的查询语句改成下面这种写法:
$query1 = "INSERT INTO UsageData (MyID) SELECT ? FROM DUAL WHERE NOT EXISTS ( SELECT MyID FROM UsageData WHERE MyID = ? )";
修改后的完整PHP代码
$query1 = "INSERT INTO UsageData (MyID) SELECT ? FROM DUAL WHERE NOT EXISTS ( SELECT MyID FROM UsageData WHERE MyID = ? )"; if ($statement1 = $database->prepare($query1)) { $statement1->bind_param("ss", $inID, $inID); $statement1->execute(); $statement1->close(); } else { echo "Incorrect SQL 1\n"; echo "Query: ".$query1."\n"; echo $database->error."\n"; }
为什么这样能解决问题?
DUAL是MySQL内置的虚拟表,专门用于不需要实际表的SELECT查询,预处理解析器会明确识别到它是一个合法的表引用,不会再抛出“No tables used”的错误。- 这个写法的逻辑和你原来的完全一致:只有当
UsageData表中不存在MyID = $inID的行时,才会插入新行。
额外说明
如果你坚持想用原来的临时子查询写法,也可以尝试给临时子查询添加一个实际的表关联(比如关联一个小表),但显然用DUAL的写法更简洁高效,也更符合MySQL的规范。
内容的提问来源于stack exchange,提问作者J.Doe
相关产品推荐
相关产品推荐

