2012-06-27 34 views
5

Tôi muốn thực hiện truy vấn được tham số hóa để thực hiện tìm kiếm theo các tham số do người dùng cung cấp. Có khá nhiều tham số và không phải tất cả các tham số đều được cung cấp mọi lúc. Làm cách nào để tạo truy vấn chuẩn chỉ định tất cả các tham số có thể, nhưng bỏ qua một số tham số này nếu người dùng không chọn giá trị tham số có ý nghĩa?Bỏ qua WHERE tiêu chí

Dưới đây là một ví dụ tưởng tượng để minh họa cho những gì tôi sẽ cho

$sql = 'SELECT * FROM people WHERE first_name = :first_name AND last_name = :last_name AND age = :age AND sex = :sex'; 
$query = $db->prepare($sql); 
$query->execute(array(':first_name' => 'John', ':age' => '27'); 

Rõ ràng, điều này sẽ không làm việc vì số lượng các thông số được cung cấp không phù hợp với số lượng các thông số mong đợi. Tôi có phải thực hiện truy vấn mỗi khi chỉ có các tham số được chỉ định được bao gồm trong mệnh đề WHERE hay có cách nào để nhận một số tham số này bị bỏ qua hoặc luôn trả về true khi được chọn không?

Trả lời

7
SELECT * FROM people 
WHERE (first_name = :first_name or :first_name is null) 
AND (last_name = :last_name or :last_name is null) 
AND (age = :age or :age is null) 
AND (sex = :sex or :sex is null) 

Khi đi qua các thông số, cung cấp null cho những người bạn không cần.

Lưu ý rằng để có thể chạy một truy vấn theo cách này, emulation mode cho PDO phải được bật ON

+0

Tôi không nghĩ rằng đó là những gì ông muốn. Điều này sẽ khớp với 'first_name' có một giá trị khớp, hoặc nếu nó là null. Nhưng từ những gì tôi hiểu, anh ta muốn 'first_name' để phù hợp với bất cứ điều gì (như thể không có mệnh đề WHERE cho cột đó). – netcoder

+0

@netcoder nó không kiểm tra nếu first_name là null, nó đang kiểm tra nếu '(first_name = @var hoặc @var là null)' –

+0

Oh, bạn nói đúng, tôi đọc quá nhanh :) – netcoder

1

Nếu bạn không thể giải quyết vấn đề của bạn bằng cách thay đổi truy vấn của bạn ... Có một số thư viện có thể trợ giúp với các truy vấn lắp ráp. Tôi đã sử dụng Zend_Db_Select trong quá khứ nhưng mỗi khuôn khổ khả năng có một cái gì đó tương tự:

$select = new Zend_Db_Select; 

$select->from('people'); 

if (!empty($lastName)) { 
    $select->where('lastname = ?', $lastname); 
} 

$select->order('lastname desc')->limit(10); 

echo $select; // SELECT * FROM people WHERE lastname = '...' ORDER BY lastname desc LIMIT 10 
2

Đầu tiên, hãy bắt đầu bằng cách thay đổi $sql chuỗi của bạn chỉ đơn giản là:

$sql = 'SELECT * FROM people WHERE 1 = 1'; 

Các WHERE 1 = 1 sẽ cho phép bạn không bao gồm bất kỳ thông số bổ sung ...

Tiếp theo, chọn lọc nối với chuỗi $sql của bạn bất kỳ thông số bổ sung nào có giá trị có ý nghĩa:

$sql .= ' AND first_name = :first_name' 
$sql .= ' AND age = :age' 

$sql chuỗi của bạn bây giờ chỉ chứa các thông số mà bạn có kế hoạch cung cấp, vì vậy bạn có thể tiến hành như trước:

$query = $db->prepare($sql); 
$query->execute(array(':first_name' => 'John', ':age' => '27'); 
0

Tôi đã thử nghiệm các giải pháp được đưa ra bởi @juergen nhưng nó mang lại một PDOException từ số biến bị ràng buộc không khớp. Sau đây (không tao nhã như vậy) Mã việc bất kể có các thông số:

function searchPeople($inputArr) 
{ 
    $allowed = array(':first_name'=>'first_name', ':last_name'=>'last_name', ':age'=>'age', ':sex'=>'sex'); 

    $sql = 'SELECT * FROM sf_guard_user WHERE 1 = 1'; 

    foreach($allowed AS $key => $val) 
    { 
     if(array_key_exists($key, $inputArr)){ 
      $sql .= ' AND '. $val .' = '. $key; 
     } 
    } 

    $query = $db->prepare($sql); 
    $query->execute($inputArr); 
    return $query->fetchAll(); 
} 

Cách sử dụng:

$result = searchPeople(array(':first_name' => 'John', ':age' => '27')); 
+0

Bạn có đang sử dụng các tham số được đặt tên và phiên bản mới nhất của PHP + PDO không? Việc này ổn với tôi. – kotekzot

+0

Có, tôi đang sử dụng các tham số có tên và PHP 5.3.5 với mysqlnd 5.0.7. Đoạn mã trên hoạt động tốt, nhưng nếu tôi chỉ thay thế chuỗi $ sql bằng chuỗi @juergen d cho PDOException. Phương pháp của anh ấy chắc chắn thanh lịch hơn và tôi thích sử dụng nó hơn. Bất cứ ý tưởng những gì có thể là sai? – qais

+0

Bạn phải cung cấp null cho các tham số không mong muốn. – kotekzot

Các vấn đề liên quan