2012-06-27 16 views
5

Quiero ejecutar una consulta parametrizada para realizar una búsqueda por parámetros proporcionados por el usuario. Hay bastantes parámetros y no todos se suministrarán todo el tiempo. ¿Cómo puedo hacer una consulta estándar que especifique todos los parámetros posibles, pero ignore algunos de estos parámetros si el usuario no eligió un valor de parámetro significativo?Ignorar los criterios WHERE particulares

He aquí un ejemplo imaginario para ilustrar lo que voy a

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

Obviamente, esto no funcionará porque el número de parámetros proporcionados no coincide con el número de parámetros esperados. ¿Tengo que elaborar la consulta cada vez con solo los parámetros especificados que se incluyen en la cláusula WHERE, o hay alguna manera de hacer que algunos de estos parámetros sean ignorados o siempre devuelven la verdad cuando se marcan?

Respuesta

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) 

Al pasar parámetros, suministro null para los que usted no necesita.

Tenga en cuenta que para poder ejecutar una consulta de esta manera, emulation mode de DOP es necesario girar ON

+0

No creo que eso es lo que quiere. Esto coincidirá con 'first_name' tiene un valor coincidente, o si es nulo. Pero por lo que entiendo, quiere 'first_name' para coincidir en cualquier cosa (como si no hubiera ninguna cláusula WHERE para esa columna en absoluto). – netcoder

+0

@netcoder no está comprobando si first_name es nulo, está comprobando si '(first_name = @var o @var es nulo)' –

+0

Oh, tienes razón, leo demasiado rápido :) – netcoder

1

Si no puede resolver el problema cambiando su consulta ... Hay varias bibliotecas que ayudan con ensamblar consultas. He utilizado Zend_Db_Select en el pasado pero cada marco es probable que tenga algo similar:

$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

En primer lugar, empezar por cambiar la cadena de $sql simplemente:

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

El WHERE 1 = 1 le permitirá no incluye ningún parámetros adicionales ...

A continuación, concatene selectivamente a su cadena $sql cualquier parámetro adicional que tenga un valor significativo:

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

Su cadena $sql ahora sólo contiene los parámetros que tiene previsto mediante la aportación, por lo que puede proceder como antes:

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

He probado la solución dada por @juergen pero da una PDOException desde el número de variables enlazadas no coincide. La (no tan elegante) siguiente código funciona independientemente de ninguno de los parámetros:

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

Uso:

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

¿Está utilizando parámetros con nombre y la última versión de PHP + PDO? Funciona bien para mí. – kotekzot

+0

Sí, estoy usando parámetros con nombre y PHP 5.3.5 con mysqlnd 5.0.7. El código anterior funciona bien, pero si solo reemplazo la cadena $ sql por la de @juergen d da la excepción PDOException. Su método es ciertamente más elegante, y preferiría usarlo. ¿Alguna idea de lo que podría estar mal? – qais

+0

Debe proporcionar nulo para los parámetros no deseados. – kotekzot

Cuestiones relacionadas