2017-12-02 9 views
0

이상한 결과가 나타납니다. mySQL 데이터베이스에서 사이트 사용자 계정을 활성화/비활성화하는 업데이트 메서드 (http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/data-retrieval-and-manipulation.html#update) 호출이 업데이트되지 않고 0을 반환하는 경우가 있습니다. 다음은 코드입니다.Symfony2 DBAL 업데이트 메서드가 0을 반환합니다.

$user_id = '198'; 
$sqlSetStmnt= [ 'activation_code' => NULL, 'active' => 0 ]; 
$conn = $this->get('database_connection'); 

try { 

    $result = $conn->update('users', $sqlSetStmnt,[ 'id' => (int)$user_id ]); 

} 
catch(Exception $e) { 

    $error = $e->getMessage(); 
    throw new \Exception('update user account data function -- ' . 
         'error: ' . $error . ' - ' . 
         'unable to update your account!'); 

} // End of catch(Exception) block. 

if(($result === FALSE) || ($result !== 1)) { 

    throw new \Exception('update user account data function -- ' . 
         'update return value: ' . $result . ' - ' . 
         'unable to update your account!'); 

} // if(($result === FALSE) || ($result !== 1)) ... 

사용자 테이블 기본 키 인 ID INT (11) 열 활성 TINYINT (1) 열 및 activation_code VARCHAR (40) NULL 컬럼을 갖는다.

$ USER_ID 변수가 '198'의 문자열 값이 포함되어 있습니다,하지만 $ sqlSetStmnt 값을 생성 할 때 그것은 int로 캐스팅.

테이블은 사용자 테이블의 행 업데이트 호출시 (198)의 ID 열 값에 있다는 것을 확인하는 사용자에게 검사 . 업데이트 호출을 실행할 때 사용

계정은 행 활성activation_code 열 값을 변경 할 수있는 충분한 권한을가집니다.

시스템에 다른 사용자가 없거나 데이터베이스에 액세스 할 수 없으므로 행에 잠금이 설정되지 않습니다.

내가 X 디버그를 사용하여 코드를 검사하고 $ USER_ID$ sqlSetStmnt 변수의 값이 적절 $가0으로 설정된주는 결과, I가 기대 값으로 설정했다 메서드를 업데이트하고 업데이트 메서드 호출에 의해 예외가 throw되지 않았 음을 나타냅니다.

그런데

상기 $ USER_ID$ sqlSetStmnt 변수 값은 사용자가 입력되지 않기 때문에 결합 변수를 사용하지 않아도되므로없이 SQL 인젝션 가능성, 또는 버퍼 오버런 없다 .

업데이트 방법이 0을 반환 한 이유에 대한 정보를 DBAL에서 얻을 수있는 방법이 있습니까?

감사합니다.

$result = $conn->update('users', $sqlSetStmnt, [ 'id' => (int)$user_id ]); 

에 :

+0

업데이트는 실제로 업데이트 된 레코드 수를 반환합니다. 실제로 레코드를 변경하고 0을 반환한다고 말하고 있습니까? – Cerad

+0

아니요, 레코드가 업데이트 된 것으로 나타나지 않습니다. 그러나 id 열 값이 일치하는 행이 있고 id 열이 테이블의 기본 키이므로 한 행이 업데이트되어 결과가 0이 아닌 한 값으로 설정되어야합니다. –

+0

activation_code가 널이 아니거나 활성 값이 0이 아닌 경우에만 행이 갱신됩니다. 기본 SQL 데이터베이스 물건. – Cerad

답변

0

이 문제를 해결하기 전에 난에서 전환

$sqlUpdateStmnt = 'UPDATE `users` SET field = value ' . 
        'WHERE `id` = ' . $user_id; 
$result = $conn->executeUpdate($sqlUpdateStmnt); 

확실히 행이에있을 때 일부 업데이트가 0 행을 반환하는 것과 같은 결과를 얻었다 $ user_id 값과 일치하는 id를 가진 사용자 테이블.

기존 절을 반입 한 다음 set 절의 필드가 테이블의 동일한 열과 다를 경우에만 행을 업데이트하여이 문제를 해결했습니다.

이는 반환 값 0이 일치하는 행이 없다는 것이 아니라 업데이트 된 행에 영향을 미치지 않는다고 알려줍니다.

그래서이 문제는 버그가 아니며 결과를 오해하는 것이 아닙니다. 그러나 행이 일치하지 않아 변경 사항이 작성되지 않았거나 변경 사항이 작성되지 않았으므로 갱신이 실패한시기를 판별하는 f}에 대한 update() 메소드를 사용할 때 여전히 문제점이 있습니다.

내가 해결 한 해결책은 업데이트가 행에 영향을 줄 수 있는지 확인하기 위해 프리 페치를 수행하면서이를 해결합니다. 필자의 경우 다중 사용자 데이터베이스 응용 프로그램을 사용하면 업데이트가 변경되기 전에 다른 사용자가 업데이트 할 행을 삭제할 수 있으므로 미리 가져 오기는 실제로 문제가되지 않습니다. 그러나 두 가지 업데이트 방법 모두를보다 명확하게 설명하고 다른 값을 반환하면 좋을 것입니다. 영향을받는 행이 없으면 0이고 발견 된 행이없는 경우에는 FALSE입니다.