MySQL错误 - 命令不同步;你现在不能运行这个命令

时间:2013-04-16 05:55:05

标签: php mysql codeigniter stored-procedures pivot

我在PHP中使用MySQL,Codeigniter。我在帖子here

中有一个由bluefeet回答的问题

我为bluefeet创建了第二个解决方案的存储过程。然而,它工作得很完美,而在生产环境中调用该过程时,所有其他用户都会收到错误

  

命令不同步;你现在不能运行这个命令

不确定如何克服此错误。我还尝试在调用过程后关闭连接,但是,在关闭连接之前,将执行来自其他用户的查询。有没有解决这个问题?

以下是我使用过的存储过程

DROP PROCEDURE IF EXISTS mailbox.circle_pending_p;
CREATE PROCEDURE mailbox.`circle_pending_p`()
BEGIN
SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'sum(CASE WHEN maildate = ''',
      date_format(mailtime, '%e-%b'),
      ''' THEN 1 else 0 END) AS `',
      date_format(mailtime, '%e-%b'), '`'
    )
  ) INTO @sql
FROM circle_pending_temp
WHERE mailtime >= (select date_sub(max(mailtime), interval 8 DAY)
                   from circle_pending_temp);

SET @sql 
  = CONCAT('SELECT coalesce(email_Circle, ''Grand Total'') Circle,
              max(`< 9 days`) `< 9 days`, ', @sql, ' ,
              count(*) GrandTotal
            from
            (
              select c.email_Circle,
                date_format(c.mailtime, ''%e-%b'') maildate,
                coalesce(o.`< 9 days`, 0) `< 9 days`
              from circle_pending_temp c
              left join
              (
                select email_Circle,
                  count(*) `< 9 days`
                from circle_pending_temp
                where mailtime <= (select date_sub(max(mailtime), interval 8 DAY)
                                    from circle_pending_temp)
              ) o
                on c.email_Circle = o.email_Circle
              where c.mailtime >= (select date_sub(max(mailtime), interval 8 DAY)
                                      from circle_pending_temp)
            ) d
            group by email_Circle with rollup ');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;

我用来调用此过程的PHP是

    $db = $this->load->database('mailbox',TRUE);
    $res = $db->query('Call circle_pending_p()');
    echo $db->_error_message();
    $db->close();
    $db = $this->load->database('mailbox',TRUE);
    if ($res->num_rows() > 0) {
        return $res->result_array();
    } else {
        return 0;
    }

4 个答案:

答案 0 :(得分:14)

得到了答案!看起来codeigniter的mysql驱动程序有处理存储过程的错误。

我通过更改

将驱动程序从mysql更改为 config / database 文件中的mysqli
$db['default']['dbdriver'] = 'mysql';

$db['default']['dbdriver'] = 'mysqli';

发布我修改 system / database / drivers / mysqli / mysqli_result.php 文件并添加以下功能

function next_result()
{
  if (is_object($this->conn_id))
  {
      return mysqli_next_result($this->conn_id);
  }
}

并修改模型如下

$db = $this->load->database('mailbox',TRUE);
$qry_res = $db->query('Call circle_pending_p()');

echo $db->_error_message();
$res = $qry_res->result_array();

$qry_res->next_result();
$qry_res->free_result();

if (count($res) > 0) {
      return $res;
} else {
      return 0;
}

这解决了这个问题!

答案 1 :(得分:2)

尝试:

<?php
while($dbms->more_results() && $dbms->next_result())
    {
        $result = $dbms->store_result();

        if(is_object($result)){ $result->free(); }

        unset($result);
    }
?>

程序调用后。 MySQLi无法调用其他过程,而以前的结果。 在进行任何进一步的过程调用或查询执行之前,您应该为每个使用free()

来源:http://php.net/manual/en/mysqli.query.php

答案 2 :(得分:0)

在档案

system/database/drivers/mysqli/mysqli_result.php

添加:

function next_result()
{
    if (is_object($this->conn_id))
    {
        return mysqli_next_result($this->conn_id);
    }
}

function result($type = 'object')
{
    $result = array();

    if ($type == 'array') $result = $this->result_array();
    else if ($type == 'object') $result = $this->result_object();
    else $result = $this->custom_result_object($type);

    $this->next_result();

    return $result;
}

答案 3 :(得分:0)

当我在循环中运行存储过程时,我遇到了类似的问题。我正在使用以下代码:

foreach ($month_list as $month_row) 
{

  $start_date = $month_row->adate;
  $end_date = date("Y-m-d", strtotime("last day of " . date("F", strtotime($start_date)) . " " . date("Y", strtotime($start_date))));

  $qry_res = $this->db->query("call staff_attendance('$start_date', '$end_date')");

  $res = $qry_res->result();

  $qry_res->next_result();
  $qry_res->free_result();

  $compiled_months[] = $res;

}

在这种情况下,我创建的临时表被抱怨,因为表已经存在。

所以,改用这种方法:

foreach ($month_list as $month_row) 
{

  $start_date = $month_row->adate;
  $end_date = date("Y-m-d", strtotime("last day of " . date("F", strtotime($start_date)) . " " . date("Y", strtotime($start_date))));

  $compiled_months[] = $this->db->query("call staff_attendance('$start_date', '$end_date')")->result();
  $this->db->close();
  $this->db->initialize();

}

现在执行是完美的