首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用MySQLi从PHP调用MySQL存储函数时出现致命错误

问使用MySQLi从PHP调用MySQL存储函数时出现致命错误
EN

Stack Overflow用户
提问于 2011-03-13 05:09:47
回答 2查看 2.4K关注 0票数 1

服务器详细信息:

PHP v5.3.5

使用MySQLi库客户端api版本:mysqlnd5.0.7-dev- 091210 - $Revision: 304625 $

MySQL服务器v5.5.9

我在MySQL中有一个名为f_get_owner_locations( _in int )的存储函数。它构造了一个文本变量,用于保存特定所有者拥有的任何公寓的位置。如果我运行一个

代码语言:javascript
复制
SELECT f_get_owner_locations( 3 );  

在MySQL命令行中,它完成了它应该做的事情,并返回一行:

代码语言:javascript
复制
+----------------------------+
| f_get_owner_locations( 3 ) |
+----------------------------+
| A-01                       |
+----------------------------+

但是,每当我尝试使用MySQLi库通过PHP运行它时:

代码语言:javascript
复制
$sql = "SELECT f_get_owner_locations( 3 )";
$location = $GLOBALS['db']->fetch( $sql );

我得到了这个错误:

代码语言:javascript
复制
Fatal error: Call to a member function fetch_field() on a non-object 
in ~/kernel/Database.php on line 328

这行代码是这样的:

代码语言:javascript
复制
/**
 * Binds results from a returning SQL statement to an array we can 
 * loop through.
 * 
 * @param   $statement  Statement object we're binding from.
 * @return  Array of values being returned.
 * @since   0.1
 */
private final function _bindResult( $statement )
{
    $results = NULL;
    $bind = array( );

    //Get the result set, so we can loop through the fields.
    $result = $statement->result_metadata( );
    //Loop through the fields and get a reference to each.
    while( $column = $result->fetch_field() ) //<=<=<=LINE 328
        $bind[] = &$results[$column->name];
    //Do the actual binding.
    call_user_func_array( array( $statement, 'bind_result'), $bind );

    //Free the memory since we already have the result.
    $result->free_result();

    return $results;
} //_bindResult

请记住,当SQL语句不涉及函数调用时,它不会失败。也就是说,这是可行的:

代码语言:javascript
复制
$sql = "SELECT `id` FROM `owners`";
$owners = $GLOBALS['db']->fetch( $sql );

但是,一旦我添加了将他们拥有的公寓放入其中的需要(此语句也可以通过MySQL命令行工作):

代码语言:javascript
复制
$sql = "SELECT `id`, f_get_owner_locations(`id`) FROM `owners`";
$owners = $GLOBALS['db']->fetch( $sql );

它给我一个关于调用非对象上成员函数的错误。

我被难住了。在while循环之前对$result执行var_dump,在我的_bindResults方法中会给出1个正确的转储,然后停止,错误就出现了。

代码语言:javascript
复制
object(mysqli_result)#11 (5) {
  ["current_field"]=>
  int(1)
  ["field_count"]=>
  int(1)
  ["lengths"]=>
  NULL
  ["num_rows"]=>
  int(0)
  ["type"]=>
  int(1)
}

注意:对f_get_owner_locations的调用是选择列表中的第二个字段,所以它没有存储正确的字段计数,尽管它需要循环到正确数量的字段。

如果有任何建议来解决这个小障碍,或者确认这是MySQLi库中的一个bug,或者是我的绑定代码有问题,我们将不胜感激。

更新:以下代码:

代码语言:javascript
复制
mysql_connect( ... );
mysql_query( "select f_get_owner_locations(3)" );
die( mysql_error() );

给了我这个输出:

代码语言:javascript
复制
FUNCTION f_get_owner_locations does not exist.

我更想知道这是不是PHP/MySQLi方面的失败?

更新2:

根据请求,用于创建函数的代码如下:

代码语言:javascript
复制
drop function if exists f_get_owner_locations;
delimiter |
create function f_get_owner_locations( _in int )
returns text deterministic
begin
    declare _output text default "";
    declare _location varchar(255);
    declare _count int default 0;
    declare _done int default 0;
    declare _cursor cursor for 
        select
            condos.location
        from
            owners left join
            condo_owners on owners.id = condo_owners.owner left join
            condos on condo_owners.condo = condos.id
        where
            owners.id = _in;
    declare continue handler for not found set _done = 1;

    open _cursor;

    repeat
        fetch _cursor into _location;
        set_count = _count + 1;
        set_output = concat( _output, ", ", _location );
    until _done end repeat;

    set _count = _count - 1;

    close _cursor;

    set _output = trim( leading ", " from _output );
    set _output = substring( _output from 1 for (_count * 6) );
    set _output = trim( trailing ", " from _output );
    return _output;
end;|
delimiter ;

允许进行一点重构,这可能会更干净一些,但这就是我所使用的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-16 02:22:06

因此,经过更多的测试之后,我发现这实际上不是MySQLi库或我的代码中的错误。

解决方案是什么?在MySQL中为数据库用户提供"Execute“权限。我以root身份登录,而不是以脚本使用的实际用户身份登录,编写并测试了SQL语句和函数。

哦,它的乐趣。

票数 0
EN

Stack Overflow用户

发布于 2011-03-13 05:24:44

MySQL存储过程可以返回多个结果集,其中最后一个结果集是您感兴趣的实际数据。mysqli正确执行的为数不多的事情之一就是支持多个结果集。

尝试检查mysqli::more_results。另外,请查看mysqli::store_result手册页面上的免责声明,了解mysqli如何处理可能没有数据的多个结果集。您最终将使用mysqli_result类而不是mysqli_stmt。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5285512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档