2014-08-29 5 views
1

This question without an accepted answer은 Windows의 MySQL 버전 5.6.16에서 수정 된 형식으로 발생하는 MySQL에 치명적인 문제를 발생시킵니다.Windows의 MySQL 5.6.16에서 PDOStatement :: nextRowSet()이 작동하지 않습니다.

문제는 쉽게 재현 할 수 있습니다 : 여기

$pdo = /* connection stuff here */ 
$sql = "call test();"; // call stored procedure - see below 
$statement = $connection->query($sql); 
do { 
    $rowset = $statement->fetchAll(PDO::FETCH_ASSOC); 
    if($rowset) { 
     // Do stuff with $rowset 
    } 
} while($statement->nextRowset()); 

저장 프로 시저 test의 정의입니다 : 내가 (위의 링크 된 질문에서 복사,하지만 내 코드에 적용되는 변경) 여기에 포함

DELIMITER $$ 
DROP PROCEDURE IF EXISTS `test`$$ 
CREATE PROCEDURE `test`() 
BEGIN  
    SELECT 1; SELECT 2; SELECT 3; SELECT 4; 
END$$ 
DELIMITER ; 

내 코드와 위의 링크 된 코드의 유일한 차이점은 SQL 쿼리를 저장 프로 시저에 압축한다는 것입니다.

필자의 경우 while 문은 true 번을 세 번이 아닌 네 번 (단지 세 번이어야 함)으로 반환합니다. 네 번째 시간 후에 fetchAll(...)SQLSTATE[HY000]: General error 오류를 발생시킵니다.

불행히도이 문제는 재앙입니다. nextRowSet() 함수를 사용하는 것 이외의 다른 행 집합을 반복하는 PDO를 사용하는 다른 방법은 없습니다. 따라서이 문제를 해결하기 위해 이전 버전의 MySQL로 되돌릴 수 있습니다.

나는이 문제를 표시하는 것 두 개의 링크를 발견

은 여기에 나열 : https://bugs.php.net/bug.php?id=67130http://permalink.gmane.org/gmane.comp.php.devel/81518

이 참이라고 나는 확인을 부탁드립니다, Windows에서의 MySQL 버전 5.6.16 버그를 . 더 나아가, 나는 해결 방법을 고맙게 생각한다. 감사.

+0

['mysqli' (http://php.net/mysqli) "수"([I 기억으로 (http://php.net/manual/en/ mysqli.multi-query.php))는 결과 집합간에 전환하지만, 전체 애플리케이션을 다른 데이터베이스 상호 작용 계층으로 이동해야한다. – BlitZ

+1

4 개의 개별 쿼리로 모든 문자열을 실행할 수없는 이유는 무엇입니까? – silkfire

+0

@silkfire 중요한 질문을 추가하기 위해 제 질문을 업데이트했습니다 (처음 질문을 올렸을 때 사과하지 않으신 것에 사과드립니다). 코드는 현재 실행중인 코드와 100 % 동일합니다. 사실 SQL은 저장 프로 시저에 내장되어 있습니다. 실제 응용 프로그램의 경우 쿼리가 훨씬 복잡하고 쉽게 리팩터링되지 않습니다. –

답변

-1

여러 개의 결과 집합으로 인해 문제가 발생하는 경우 단일 쿼리에서 여러 결과 집합을 피할 수있는 방법을 찾는 것이 가장 좋습니다.

예를 들어, 예상 결과가 동일한 형식 (예상되는 결과가 동일한 코드를 사용하여 모든 것을 처리하려고하기 때문에 예상 한 결과) 인 경우 UNION을 사용하여 4 개의 쿼리를 함께 복합 할 수 있습니다 .

SELECT 1 
UNION ALL 
SELECT 2 
UNION ALL 
SELECT 3 
UNION ALL 
SELECT 4; 

각 SELECT에 대해 별도의 쿼리를 실행하고 결과를 처리 할 함수에 전달할 수 있습니다.

2

PDO :: nextRowset()에서도 동일한 문제가 있었지만 사용 가능한 행 집합이 없어도 true를 반환하므로 fetchAll()을 호출 할 때 예외 HY000이 발생합니다. (PHP 5.5.12 윈도우, Mysql 5.5.17 리눅스에서 테스트 됨)

이 문제의 해결 방법은 행 집합을 페치하기 전에 PDO :: columnCount() 메소드를 사용하여 컬럼 수를 확인하는 것입니다. 0이 아니면 유효한 행 집합이 있으므로 PDO :: fetchAll()을 호출 할 수 있습니다.

PDO :: nextRowset()이 true를보고하더라도 columnCount()는 다음 행 집합으로 이동하기 전에 열 수를보고합니다.

예 :

while ($objQuery->columnCount()) { 
    $tab[] = $objQuery->fetchAll(\PDO::FETCH_ASSOC); 
    $objQuery->nextRowset(); 
} 
관련 문제