Às vezes temos de procurar um único valor através de várias colunas ao criar instruções SQL.
Suponha a tabela abaixo
- [ENTITY_ONE]
- ID
- COLUMN_A
- COLUMN_B
- COLUMN_C
- COLUMN_D
- COLUMN_E
Se precisamos procurar um único valor nas colunas B,D e o campo E Vamos precisar usar a seguinte instrução
1 2 |
SELECT ID, COLUMN_A,(...COLUMNS..), COLUMN_E FROM ENTITY_ONE WHERE COLUMN_B LIKE '%search_value%' OR COLUMN_D LIKE '%search_value%' OR COLUMN_E LIKE '%search_value%'; |
No código PHP podemos fazer
1 2 3 4 |
$q = '%search_value%'; $sql = "SELECT * FROM ENTITY_ONE WHERE COLUMN_B LIKE '$q' OR COLUMN_D LIKE '$q' OR COLUMN_E LIKE '$q'; $pdo = new PDO($dsn, $user, $pass); $stmt = $pdo->query($sql); |
Bem, this can work but we know that isn’;a melhor abordagem. Nós precisamos usar valores de ligação para evitar a injeção SQL e outras coisas maliciosas.
Então, o código pode ser modificado para
1 2 3 4 5 6 |
$q = '%search_value%'; $sql = "SELECT * FROM ENTITY_ONE WHERE COLUMN_B LIKE ? OR COLUMN_D LIKE ? OR COLUMN_E LIKE ?; $args = [$q, $q, $q]; // We need one entry for each "?" on instruction $pdo = new PDO($dsn, $user, $pass); $stmt = $pdo->prepare($sql); $stmt->execute($args); |
Muito melhor, Mas, Quando estiver criando instruções de SQL complexas, things can be confusing with lots of arguments and don’;esqueça: A ORDEM IMPORTA.
Felizmente PDO pode vincular os valores em ordem diferente quando usando ligações nomeadas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$q = '%search_value%'; $sql = "SELECT * FROM ENTITY_ONE WHERE COLUMN_B LIKE :first_arg OR COLUMN_D LIKE :second_arg OR COLUMN_E LIKE :third_arg; $pdo = new PDO($dsn, $user, $pass); $stmt = $pdo->prepare($sql); // One way $args = [':first_arg' => $q, ':third_arg' =>$q, ':second_arg' => $q]; // We need one entry for each ":name" on instruction $stmt->execute($args); // Another way $stmt->bindValue(':third_arg'. $q); $stmt->bindValue(':first_arg', $q); $stmt->bindValue(':second_arg', $q); $stmt->execute(); |
Hmm, seems that this isn’;bom o suficiente. Só mudamos o uso de 1-espaço reservado indexado para um :espaço reservado nomeado. There’;ganho além do código ficar mais legível e a possibilidade de ligar em qualquer ordem.
Sim, Mas agora podemos fazer a melhor abordagem possível ao usar um termo de pesquisa único em várias colunas. Podemos usar apenas um bind para um ou mais :named placeholders ‘;porque o PDO é esperto e inteligente. Olha nosso código final aqui.
1 2 3 4 5 6 7 8 9 10 |
$q = '%search_value%'; $sql = "SELECT * FROM ENTITY_ONE WHERE COLUMN_B LIKE :unique_arg OR COLUMN_D LIKE :unique_arg OR COLUMN_E LIKE :unique_arg; $pdo = new PDO($dsn, $user, $pass); $stmt = $pdo->prepare($sql); // One way $args = [':unique_arg' => $q]; // We can bind all :name with only one term $stmt->execute($args); // Another way $stmt->bindValue(':unique_arg', $q); $stmt->execute(); |
Pode economizar um monte de digitação quando escrevendo muitas instruções SQL, usando o mesmo argumento.