2012-06-27 11 views
5

Chcę wykonać sparametryzowaną kwerendę, aby wykonać wyszukiwanie według parametrów dostarczonych przez użytkownika. Istnieje kilka parametrów i nie wszystkie z nich będą dostarczane przez cały czas. Jak utworzyć standardowe zapytanie, które określa wszystkie możliwe parametry, ale zignorować niektóre z tych parametrów, jeśli użytkownik nie wybrał znaczącej wartości parametru?Ignoruj ​​określone kryteria WHERE

Oto wyimaginowany przykład, aby zilustrować, co mam zamiar za

$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'); 

Oczywiście, to nie będzie działać, ponieważ liczba przewidzianych parametrów nie pasuje do liczby oczekiwanych parametrów. Czy muszę za każdym razem wywoływać kwerendę z tylko określonymi parametrami zawartymi w klauzuli WHERE, czy jest jakiś sposób, aby niektóre z tych parametrów były ignorowane lub zawsze zwracają wartość true, gdy są zaznaczone?

Odpowiedz

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) 

Podczas przekazywania parametrów, należy dostarczyć null dla tych, których nie potrzebujesz.

Należy pamiętać, że aby móc uruchomić kwerendę w ten sposób, emulation mode dla PDO muszą być włączone ON

+0

Nie sądzę, że to, co chce. Dopasuje to wartość "first_name" ma pasującą wartość lub ma wartość null. Ale z tego co rozumiem, chce, żeby 'first_name' pasowało do czegokolwiek (tak jakby w ogóle nie było klauzuli WHERE dla tej kolumny). – netcoder

+0

@netcoder nie sprawdza, czy first_name ma wartość null, sprawdza, czy '(first_name = @var lub @var ma wartość null)' –

+0

Och, masz rację, czytam zbyt szybko :) – netcoder

1

Jeśli nie można rozwiązać problemu poprzez zmianę zapytanie ... Istnieje kilka bibliotek, które pomagają z składanie zapytań. Użyłem Zend_Db_Select w przeszłości, ale każdy ramy prawdopodobnie ma coś podobnego:

$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

pierwsze, zacząć zmieniając ciąg $sql po prostu:

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

WHERE 1 = 1 pozwoli Ci nie obejmują dodatkowe parametry ...

Następnie, selektywnie połącz ze swoim ciągiem $sql każdy dodatkowy parametr o znaczącej wartości:

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

$sql Twój ciąg zawiera teraz tylko parametry, które planują zapewnienie, dzięki czemu można kontynuować jak przedtem:

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

Przetestowałem rozwiązanie podane przez @juergen ale daje PDOException od liczba powiązanych zmiennych nie pasuje. Poniższy (nie tak elegancki) kod działa niezależnie od bez parametrów:

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(); 
} 

Zastosowanie:

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

Czy używasz nazwanych parametrów i najnowszej wersji PHP + PDO? Działa to dobrze dla mnie. – kotekzot

+0

Tak, używam nazwanych parametrów i PHP 5.3.5 z mysqlnd 5.0.7. Powyższy kod działa dobrze, ale jeśli tylko zastąpię ciąg $ sql tym z @juergen d daje PDOException. Jego metoda jest z pewnością bardziej elegancka i wolałbym ją wykorzystać. Masz pojęcie, co może być nie tak? – qais

+0

Musisz podać wartość zerową dla niepożądanych parametrów. – kotekzot