데이터베이스 개발에 PHP의 PDO (PHP Data Objects)를 사용하는 경우 Pdostatement :: RowCount ()는 종종 쿼리의 영향 을받는 행의 수를 얻는 데 사용됩니다. 그러나 일부 시나리오에서는 반환 결과가 "오해의 소지가있는"또는 버기를 느낄 수 있습니다.
이 기사는 RowCount ()가 때때로 우리가 예상 한대로가 아닌 이유에 대해 더 깊이 파고들 것입니다.
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
$stmt = $pdo->prepare("DELETE FROM users WHERE id = :id");
$stmt->execute([':id' => 123]);
echo $stmt->rowCount(); // 삭제 된 라인의 수를 출력하십시오
이 코드에서는 레코드를 삭제했으며 여러 레코드가 영향을받는 RowCount () 를 통해 알기를 희망합니다. 이것은 일반적으로 삭제 및 업데이트 문을 위해 잘 작동합니다. 그러나 일단 선택한 진술이나 일부 특별한 상황이 관련되면 문제가 발생합니다.
RowCount ()는 PostgreSQL과 같은 일부 데이터베이스에서 Select Queries에 대해 지원되지만 MySQL에서 선택한 후 RowCount () 호출은 일반적으로 0을 반환합니다 . 그 이유는 PDO가 MySQL에서 기본적으로 mysql_attr_use_buffered_query를 사용하기 때문입니다. 행은 지연으로 추출되며 RowCount는 행의 수를 정확하게 알 수 없습니다.
$stmt = $pdo->query("SELECT * FROM users");
echo $stmt->rowCount(); // 존재하다 MySQL 가능한 출력 0
데이터베이스에 실제 변경이없는 한 문이 법적으로 실행 되더라도 RowCount ()는 0을 반환합니다.
$stmt = $pdo->prepare("UPDATE users SET name = :name WHERE id = :id");
$stmt->execute([':name' => 'Alice', ':id' => 123]);
echo $stmt->rowCount(); // 만약에 name 이미 Alice,그런 다음 돌아옵니다 0
이것은 오류가 아니라 SQL의 특징입니다. 실제 변경이 없으면 선의 "영향"으로 간주되지 않습니다.
다른 데이터베이스 드라이버 구현은 rowCount ()를 일관성있게 지원합니다. 예를 들어:
MySQL : Select는 올바른 값을 반환하지 않으며 업데이트/삭제가 지원합니다.
Postgresql : 대부분의 진술은 그것을 뒷받침합니다.
SQLITE : 대부분의 진술은 그것을 뒷받침합니다.
Oracle : 행동이 더 복잡하며주의해서 사용해야합니다.
$stmt = $pdo->query("SELECT * FROM users WHERE status = 'active'");
$rows = $stmt->fetchAll();
echo count($rows);
또는 Traversal 사용 :
$count = 0;
foreach ($stmt as $row) {
$count++;
}
echo $count;
$stmt = $pdo->prepare("UPDATE users SET name = :name WHERE id = :id AND name != :name");
$stmt->execute([':name' => 'Alice', ':id' => 123]);
echo $stmt->rowCount(); // 언제에 name 실제 변화로 돌아갑니다 1
많은 경우, 특히 쿼리 또는 배치 작업에서 SQL이 직접 영향을받는 행 수를 반환하는 것이 좋습니다.
$stmt = $pdo->query("SELECT COUNT(*) FROM users WHERE status = 'active'");
$count = $stmt->fetchColumn();
echo $count;
모든 운전자가 일관되게 행동한다고 가정하지 마십시오. PDO를 초기화 할 때 다음 방법을 사용하여 호환성을 감지하거나 설정할 수 있습니다.
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password', [
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
]);
pdostatement :: rowCount () 는 일반적으로 사용되는 인터페이스이지만 항상 다른 데이터베이스와 다른 SQL 유형에서 원하는대로 작동하는 것은 아닙니다. 개발자로서 그 범위와 한계를 이해하는 것이 함정을 피하는 핵심입니다.
가장 안전한 전략은 다음과 같습니다.
Select Queries에서 RowCount () 에 의존하지 마십시오.
업데이트/삭제 와 같은 작업의 경우 "행에 영향을 미치는 행"은 "행 찾기"가 아니라는 것이 이해됩니다.
정확한 제어 또는 교차-다이타베이스 호환성의 경우 SQL 레벨 계산 로직 사용을 고려하십시오.