2013-04-16 2 views
3

PHP와 함께 MySQL을 사용하고 있습니다. Codeigniter. 게시물에 bluefeet이 대답 한 질문이 있습니다. hereMySQL 오류 - 동기화되지 않은 명령입니다.

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 드라이버가 저장 프로 시저를 처리하는 버그를 가지고있는 것처럼 보입니다.

나는 내가 시스템/데이터베이스/드라이버/mysqli를 수정

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

포스트에

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

을 변경하여 설정/데이터베이스 파일에 mysqli MySQL에서 드라이버를 변경 /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' 호출 후 그 결과를 얻은 후에해야합니다. '데이터베이스 래퍼'를 사용하는 동안 어떻게 보일지 모르겠지만, 여전히 DB 연결을 닫았을 것입니다. – BlitZ

0

system/database/drivers/mysqli/mysqli_result.php 

추가 :

내가 루프에서 저장 프로 시저를 실행 할 때 내가 similary 문제에 직면
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(); 

} 

이제 실행이 작동하지 않습니다

관련 문제