2013-04-16 74 views
3

我使用MySQL和PHP,笨。我這是在後hereMySQL錯誤 - 命令不同步;你不能運行這個命令現在

我創建了一個存儲過程由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; 
    } 

回答

14

已得到的答案!似乎codeigniter的mysql驅動程序有處理存儲過程的錯誤。

我改變了驅動程序從MySQL在配置/數據庫文件的mysqli通過改變

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

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

後,我修改了系統/數據庫/驅動器/庫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; 
} 

這個問題解決了!

+2

如果使用mysqli, mysqli_next_result($ this-> db-> conn_id);在過程調用之後,從模型本身,而不必修改mysqli庫 – idok

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

+0

這是行不通的!它曾經工作過一次,但再次收到錯誤消息! ( – Guns

+1

)你應該在** ANY **'SQL procedure'調用並獲得它的結果之後執行它,我不知道在使用'database wrapper'時它應該如何看待。這裏:'$ db-> close(); $ db = $ this-> load-> database('mailbox',TRUE);'。我不認爲它需要那裏 – BlitZ

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; 
} 
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(); 

} 

現在執行的是完美的

相關問題