准备好的语句何时失败?

Posted

技术标签:

【中文标题】准备好的语句何时失败?【英文标题】:When does a prepared statement fail? 【发布时间】:2014-01-29 17:38:12 【问题描述】:

我一直在搞乱php 中的mysqli 对象,并且习惯于在执行语句之前准备语句。

到目前为止,我大部分时间都在做以下事情:

if($stmt = $mysqli->prepare($sql) == false)
    return $mysqli->error;

当它失败时,它总是告诉我我的 SQL 基本上是错误的。

假设如下:

已进行检查以确保MySQL 连通性 SQL 是正确的,即使它返回 0 行。 所有相关表都存在。

在什么情况下准备好的语句会失败?请问,主要是想知道if($stmt = $mysqli->prepare($sql))有什么意义,还是我只是在浪费代码行数?

【问题讨论】:

接近完美的this question副本 糟糕,我很抱歉,我以为我是唯一没有得到这个的人......谢谢@kuroineko 【参考方案1】:

我想到的第一个:检查后不保证存在连接。我敢肯定还有很多。但是一个理由就足够了。

【讨论】:

避免被批评的样板。但是,好的,我删除了该建议。这里不是 OP。【参考方案2】:

有效查询失败的方式有很多:

您对这些表的权限可能会被撤销。

可以在无效上下文中使用参数占位符格式化正确的 SQL 查询。

查询可能会根据服务器设置引发错误,例如除以零返回 NULL,但有人可以在服务器上全局启用 SQL mode 以使除以零引发错误。还有其他情况,服务器设置可以改变有效 SQL 查询的含义。

您说表存在,但可以删除或重命名任何表。此外,列可能会被更改,因此您之前有效的 SQL 查询不再找到它命名的列,或者尝试以无效的方式使用它们。

连接可能会意外终止。

因此,您确实需要在准备执行查询时检测和响应错误。

想象一个简单的文件打开函数,如fopen()。如果您拼写错误的文件名,或者如果文件在您尝试打开它之前被删除,或者如果有人更改了文件权限,因此您无法使用您指定的访问模式读取它,您可能会遇到错误。这意味着您需要在 每个 fopen() 调用之后检查是否成功。

如果你配置 mysqli 抛出异常,你可以减少错误检查代码。见http://www.php.net/manual/en/mysqli-driver.report-mode.php

【讨论】:

以上是关于准备好的语句何时失败?的主要内容,如果未能解决你的问题,请参考以下文章

SQLITE JDBC 驱动程序准备好的语句失败(内部指针 0)

准备好的语句失败(带有错误消息!)

mysql准备好的语句在新机器上静默失败

调用 MySQL 函数时 PHP 准备语句失败

什么时候在 PHP Mysqli 中使用准备好的语句? - 用户表单搜索输入与选择查询

如何摆脱 MySQL 错误“需要重新准备准备好的语句”