2012-07-05 6 views
28

Tôi đang cố gắng lấy một hàng đơn lẻ được trả về từ truy vấn gốc với Doctrine. Đây là mã của tôi:Nhận kết quả hàng đơn với Doctrine NativeQuery

$rsm = new ResultSetMapping; 
$rsm->addEntityResult('VNNCoreBundle:Player', 'p'); 
$rsm->addFieldResult('p', 'player_id', 'id'); 

$sql = " 
    SELECT player_id 
     FROM players p 
    WHERE CONCAT(p.first_name, ' ', p.last_name) = ? 
"; 

$query = $this->getEntityManager()->createNativeQuery($sql, $rsm); 
$query->setParameter(1, $name); 
$players = $query->getResult(); 

Dòng cuối cùng trả về danh sách người chơi nhưng tôi chỉ muốn một kết quả. Làm thế nào để làm điều đó?

Trả lời

77

Bạn có thể sử dụng $query->getSingleResult(), điều này sẽ ném một ngoại lệ nếu có nhiều hơn một kết quả được tìm thấy hoặc nếu không tìm thấy kết quả nào. (xem phpdoc có liên quan tại đây https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/AbstractQuery.php#L791)

Còn ít nổi tiếng hơn $query->getOneOrNullResult() sẽ ném ngoại lệ nếu có nhiều hơn một kết quả được tìm thấy và trả về null nếu không tìm thấy kết quả. (Xem PHPDoc liên quan ở đây https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/AbstractQuery.php#L752)

+5

Tốt, thậm chí không biết về getOneOrNullResult, nhưng điều đó khá hữu ích! –

2

Tôi chỉ muốn một kết quả

ngụ ý rằng bạn mong đợi chỉ có một hàng để được trả lại. Do đó, hãy điều chỉnh truy vấn của bạn, ví dụ:

SELECT player_id 
FROM players p 
WHERE CONCAT(p.first_name, ' ', p.last_name) = ? 
LIMIT 0, 1 

(và sau đó sử dụng getSingleResult() theo khuyến cáo của AdrienBrault) hoặc lấy hàng như một mảng và truy cập vào mục đầu tiên:

// ... 
$players = $query->getArrayResult(); 
$myPlayer = $players[0]; 
37

Cả getSingleResult()getOneOrNullResult() sẽ ném một ngoại lệ nếu có nhiều hơn một kết quả. Để khắc phục sự cố này, bạn có thể thêm setMaxResults(1) vào trình tạo truy vấn của mình.

$firstSubscriber = $entity->createQueryBuilder()->select('sub') 
     ->from("\Application\Entity\Subscriber", 'sub') 
     ->where('sub.subscribe=:isSubscribe') 
     ->setParameter('isSubscribe', 1) 
     ->setMaxResults(1) 
     ->getQuery() 
     ->getOneOrNullResult(); 
+0

Đối với bất kỳ ai cố gắng sử dụng 'SetMaxResults (1)' với NativeQuery, phương thức đó không được hỗ trợ [docs for version 2.3] (http://www.doctrine-project.org/api/orm/2.3/class-Doctrine. ORM.NativeQuery.html). –

+0

Một mối quan tâm tôi có cho giải pháp này - nếu cả hai đều khẳng định rằng phải có 0 hoặc 1 kết quả, nhưng sau đó nuốt ngoại lệ (thông qua 'setMaxResults (1)') sẽ dẫn đến xác nhận đó là sai, thì bạn có thể được che giấu một vấn đề ngấm ngầm hơn với mô hình dữ liệu hoặc ứng dụng của bạn. Chỉ là FYI. – MSC

9

-> getSingleScalarResult() sẽ trả về một giá trị duy nhất thay vì một mảng.

+1

Đây là những gì tôi đang tìm kiếm cho truy vấn SELECT MIN (ngày) ... của tôi. Trả về ngày không có mảng. Cảm ơn. – Strabek

0

Để lấy hàng duy nhất

$result = $this->getEntityManager()->getConnection()->fetchAssoc($sql) 

Để lấy tất cả hồ sơ

$result = $this->getEntityManager()->getConnection()->fetchAll($sql) 

Ở đây bạn có thể sử dụng truy vấn nguồn gốc sql, tất cả sẽ làm việc mà không cần bất kỳ vấn đề.