CodeIgniter活动记录调用多个存储过程的问题

4
class Registration_model extends CI_Model {

    function __construct() {
        parent::__construct();
    }   

    function check_email_availability($email)
    {
        $sql = "CALL proc_1301('$email');"; 
        $query = $this->db->query($sql) or die(mysql_error()); 
        return $query->row_array();
    }

    function check_username_availability($username)
    {
        $sqlt = "CALL proc_1303('$username');"; 
        $query = $this->db->query($sqlt) or die(mysql_error()); 
        return $query->row_array();
    }

    function process_registration($username, $email, $password)
    { 
        $sql = "CALL `proc_1302`('$username', '$email', '$password');"; 
        $query = $this->db->query($sql) or die(mysql_error()); 
        return $query->result_array();   
    }

这是我的控制器代码,依次调用了三个模型函数:

$emailCheckRes = $this->Registration_model->check_email_availability($email); 
$usernameCheckRes = $this->Registration_model->check_username_availability($username); 
$this->data['regRes'] = $this->Registration_model->process_registration($username, $email, $password);

我的问题是,当我只运行一个函数时,它成功运行,但当我运行两个或三个函数时,它显示空白页面……有什么想法吗?
解决方案:
最终,我们为我的问题找到的唯一解决方案是:
/* ADD THIS FUNCTION IN SYSTEM/DATABASE/DB_ACTIVE_REC */
/* USAGE $this->db->freeDBResource($this->db->conn_id); */
function freeDBResource($dbh){
    while(mysqli_next_result($dbh)){
            if($l_result = mysqli_store_result($dbh)){
              mysqli_free_result($l_result);
            }
        }
}

请随意在下面发布您的解决方案(并将其标记为已接受),以造福未来的访问者。 - Colin Brock
2个回答

6
这个问题与CodeIgniter的活动记录和多个数据库存储过程调用有关。
首先检查dbdriver参数(application/config/database.php)是否设置为mysqli。 然后,如"在StackOverflow上调用CodeIgniter Active Record类中的存储过程的问题" question on StackOverflow所述,在system/database/DB_active_rec.php中添加以下函数:
function freeDBResource($dbh){
    while(mysqli_next_result($dbh)){
            if($l_result = mysqli_store_result($dbh)){
              mysqli_free_result($l_result);
            }
        }
}

..并在您的控制器中使用:

$this->db->freeDBResource($this->db->conn_id);

任何存储过程调用之后。

但是在我的CI软件包中没有DB_active_rec.php文件。那么应该在哪里添加呢? - Deepa MG
1
@DeepaMG 如果您没有DB_active_rec.php文件,我假设您正在使用Codeigniter 3.x版本.. 我还没有测试过这个hack与实际的Codeigniter版本。您能否确认您是否有与CI3描述的相同问题? 在调用存储过程之前,请尝试执行$this->db->cache_off();,然后在之后执行$this->db->cache_on();。如果不起作用,您也可以尝试在任何调用之间使用$this->db->close(); $this->db->reconnect();。 让我们知道这些方法中的哪一个有效。 - deste
是的,我后来意识到了。我已经将它添加到system/database/drivers/mysqli/mysqli_results.php中。这对我起作用了。 - Deepa MG
1
@deste 在CI3中,可以使用$this->db->close(); $this->db->initialize();而不是在任何调用之间重新连接()。 - Yudhistira Bayu

0

模型和控制器看起来都没问题。 如果您尝试使用以下模型:

class Test_model extends CI_Model
{
   function __construct()
   {
      parent::__construct();
   }
   function a($a_input)
   {
      return($a_input.': a');
   }
   function b($b_input)
   {
     return($b_input.': b');
   }
}

...并且可以像这样从控制器调用它的函数:

$this->load->model('Test_model');
    $a_result = $this->Test_model->a('aaa');
    $b_result = $this->Test_model->b('bbb');
    echo($a_result.'<br />'.$b_result);

您可以看到多个函数调用正常工作。

如果您只调用一个函数,您确定您可以正确执行模型中的任何三个函数吗? 如果是的话,也许问题可以在您的存储过程中找到...您可以尝试在模型函数中执行普通查询而不是存储过程。为了调试您的问题,请检查您的/application/config/database.php文件是否将db_debug设置为TRUE。


嗨Deste,我的db_debug是TRUE,我检查了存储过程,它们都正常工作,我也单独检查了它们,它们完全正常。唯一的问题是当我像上面所述同时运行它们时,它显示空白页面并且实际上不运行任何函数... - Lonare
似乎CodeIgniter不喜欢调用多个存储过程,就好像它们之间存在冲突一样。在application/config/database.php中,dbdriver参数设置为mysql或mysqli?您可以尝试将其设置为“mysqli”。 - deste
是的,它已经设置为mysqli了。你认为这与CodeIgniter活动记录有关吗? - Lonare
也许我错了,但我认为那就是问题所在。 这个问题很有趣,因为我可能很快需要做同样的事情。 也许在StackOverflow上已经有了这个问题的答案: 从CodeIgniter的Active Record类调用存储过程 我不喜欢编辑/system内容...但如果它能正常工作,请让我知道。 - deste
我很高兴知道这件事。太好了! :-) - deste

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接