【问题标题】:Why can't I call a MySQL stored function in a prepared query via PHP?为什么我不能通过 PHP 在准备好的查询中调用 MySQL 存储函数?
【发布时间】:2015-11-28 07:27:55
【问题描述】:

我在准备好的语句中有以下查询:

SELECT 
  cid, cname, cemail, count_client_locations(cid) AS loc_cnt
FROM 
  clients 
WHERE isactive = 1 ORDER BY cname ASC

我在服务器count_client_locations 上有一个存储函数。函数的查询部分如下所示:

RETURN (SELECT COUNT(lid) FROM locations WHERE linked_client = cid);

当我在 MySQL Workbench 中运行 SQL 时,它会返回所需的结果:

cid | cname       | cemail            | loc_cnt
------------------------------------------------
2   | Acme Inc    | fred@example.com  | 3
1   | Example Ind | alice@example.com | 5
3   | Foobar Inc  | joe@example.com   | 0
1   | Barfoo Ltd  | hello@example.com | 1

当我通过 PHP mysqli 准备语句运行它时,它无法准备它 (Fatal error: Call to a member function execute() on a non-object)。如果我取消对函数的调用,它工作正常。

编辑 PHP 代码:

$sql = $conn->prepare("SELECT cid, cname, cemail, count_client_locations(cid) AS loc_cnt FROM clients WHERE isactive = 1 ORDER BY cname ASC");
$sql->execute();

那么为什么这个查询可以在 MySQL 工作台中工作,而不是在 PHP 代码中,我可以做些什么来修复它?

【问题讨论】:

  • @Drew - 我不确定我是否遵循您的意思。我搞错了什么?查询?
  • 没有什么真正的革命性
  • 那么你的 php 代码在哪里?
  • 您的prepare() 似乎失败了。您的网络服务器的 error.log 说明了什么?另外,$conn->error 的内容可能很有启发性。

标签: php mysql mysqli stored-functions


【解决方案1】:

您收到一条错误消息Fatal error: Call to a member function execute() on a non-object

需要明确的是,这是一条 PHP 错误消息,而不是 MySQL 错误消息。该错误与您的查询字符串或您的数据库完全无关。

您的代码如下所示:$conn->prepare(...)

发生错误是因为 PHP 无法识别 $conn 变量。您可能认为$conn 是MySQL 连接对象,但是当您调用它并看到null(或者可能是false 或其他一些非对象值)时,PHP 正在查看$conn。这就是它给出此错误的原因。

您没有向我们展示足够的代码让我解释为什么它可能会这样做;可能您在一个函数中并且没有将$conn 传递给它,但还有其他可能的原因。因为我不能确定,所以我会让你从那里解决问题。

【讨论】:

  • 感谢斯普德利的回答。我确实提到过,如果我在查询本身中调用存储函数,则查询会正常工作(减去所选列中的count_client_locations(cid) AS loc_cnt。我还提到查询无法准备好。我的实际问题这就是为什么原始查询在 MySQL Workbench 上有效,但在 PHP 代码中无效的原因(我认为如果它在一个中有效,它在另一个中有效)。但是我刚刚解决了我的问题。
  • 是的; prepare 失败(在 MySQL 级别)并返回 false,并且因为您随后调用了 prepare() 而不是检查错误状态的返回值,所以您在 PHP 中有效地执行了 false->prepare(),这导致你实际看到的 PHP 错误。
【解决方案2】:

所以,回答我自己关于为什么查询在 MySQL Workbench 中而不是在 PHP 代码中工作的问题是因为我没有为存储的函数调用指定哪个数据库:

SELECT 
  cid, cname, cemail, DBName.count_client_locations(cid) AS loc_cnt
FROM 
  clients 
WHERE isactive = 1 ORDER BY cname ASC

【讨论】:

  • 您可能还可以为要使用的连接指定一个默认数据库,此时您不需要为每个语句指定它(它是创建新的mysqli连接时的可选参数。)
猜你喜欢
  • 1970-01-01
  • 2011-01-26
  • 2019-03-05
  • 1970-01-01
  • 2011-05-14
  • 2019-01-11
  • 1970-01-01
  • 2017-04-09
  • 2010-12-03
相关资源
最近更新 更多