2015-11-20 1 views
-2

Je crée une requête SQL avec une méthode, puis la renvoie et l'utilise.SQLSTATE [42000]: Erreur de syntaxe ou violation d'accès [PHP]

$query = $this->buildSearchQuery($searchParams);    
return $this->db->query($query); 

Malheureusement, cela me jette une erreur:

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''SELECT * FROM candidates WHERE firstname = ? AND surname = ?','Dante', 'Hickman' at line 1

je cherchais parce que cela ressemble à la syntaxe SQL manquai de script précédent qui construit la requête, donc je ne chose simple que je largue cette requête $ avant Je l'ai utilisé.

retour Dump ceci:

"'SELECT * FROM candidates WHERE firstname = ? AND surname = ?','Dante', 'Hickman'" (81) 

Ce qui est bien, chaîne avec 81 caractères. Après cela, j'essaie de mettre cela à la requête d'origine au lieu de variabile et il ressemble à ceci:

return $this->db->query('SELECT * FROM candidates WHERE firstname = ? AND surname = ?','Dante', 'Hickman'); 

Ce script secod exécuté correcty il semble requête est correctement construit, mais toujours une erreur. Il me manque quelque chose?

J'espère pour tout conseil qui peut m'aider à résoudre ce problème.

p.s. La syntaxe de cette requête provient du framework net mais le système doit être le même.

EDIT: ajouter buildSearchQuery()

function buildSearchQuery($searchParams) 
    { 
     $column = ""; 
     $values = ""; 
     $col = ""; 
     $i=0; 
     // Trim to make sure user doesn't enter space there 
     if((trim($searchParams->firstname))) 
     { 
      $column .= "firstname,"; 
      $i++; 
     } 
     if((trim($searchParams->surname))) 
     { 
      $column .= "surname,"; 
      $i++; 
     } 

     if((trim($searchParams->specialization))) 
     { 
      $column .= "specialization,"; 
      $i++; 
     }   
     if($searchParams->english !== NULL) 
     { 
      $column .= "english,"; 
      $i++; 
     }   
     if($searchParams->german !== NULL) 
     { 
      $column .= "german,"; 
      $i++; 
     }   
     if($searchParams->russian !== NULL) 
     { 
      $column .= "russian,"; 
      $i++; 
     }   
     if($searchParams->french !== NULL) 
     { 
      $column .= "french,"; 
      $i++; 
     }   
     if($searchParams->school !== NULL) 
     { 
      $column .= "school,"; 
      $i++; 
     } 

     if((trim($searchParams->registrationDate))) 
     { 
      $column .= "registrationDate"; 
      $i++; 
     } 
     if($i > 0) 
     { 
      // If number of columns is bigger then 0 (if user fill atleast one input)     
      $columns = explode(",", $column);  
      // Create list of values for query (name of columns and values) 
      foreach($columns as $c) 
      {             
       if (isset($searchParams->$c)) {  
        $values .= "'".$searchParams->{$c}."', ";    
        $col .= $c." = ? AND ";     
       }      
      } 
      // Remove last "," and space 
      $values = substr_replace($values, "", -2);   
      $col = substr_replace($col, "", -5);  
      $query = $col."',".$values; 
      $query = "'SELECT * FROM candidates WHERE ".$query;   
      //$query = substr($query, 0, -1); //remove last char (' in this case) 
      return $query; 
     } 
     else 
     { 
      $query = "SELECT * FROM candidates"; 
      return $query; 
     } 
    } 
+0

'name =? ',' Dante ',' Hickman ');' c'est une syntaxe invalide. Qu'est-ce que vous essayez de faire ici? Si vous essayez de vérifier les multiples, vous avez besoin de plus de 'AND' ou' OR'. De plus, vous ne fermez pas votre requête correctement. Il s'arrête juste à 'AND nom =? '

+0

A droite, c'est la syntaxe de nette db-> query, au lieu d'écrire PDO compliqué cette syntaxe en fait un peu plus simple avec le même effet, en général ce qu'elle envoie d'abord requête (partie entre 'et') puis remplace points d'interrogation "?" avec des cordes à gauche, une par une dans l'ordre. Comme je l'ai dit, la deuxième requête va s'exécuter et retourner les résultats, donc la syntaxe est correcte mais je pense que j'ai d'autres problèmes là – Andurit

+0

vous aurez besoin de poster plus de code et ce qui concerne '$ query = $ this-> buildSearchQuery ($ searchParams); Je ne sais pas ce que vous essayez de construire/rechercher ici. –

Répondre

0

Les commentaires ci-dessus sont corrects, vous passez une chaîne comme le seul argument, au lieu de plusieurs arguments query attend.

Une solution possible consiste à créer un tableau et à appeler la méthode avec des éléments de tableau en tant qu'arguments (par exemple en utilisant call_user_func_array). Vous pouvez cependant faire mieux. Nette \ Database est quite powerful et peut construire la requête pour vous. Lorsque vous passez un tableau associatif comme ["column1" => "value1", "column2" => "value2"] comme seul argument de la méthode where, il créera la clause WHERE column1 = 'value1' AND column2 = 'value2' correspondante. Et bien sûr, il va échapper en toute sécurité aux valeurs pour empêcher l'injection SQL.

Vous pouvez donc simplifier votre code dans quelque chose comme suit:

$columns = ["firstname", "surname", "specialization", "english", "german", "russian", "french", "school", "registrationDate"]; 
$conditions = []; 
foreach ($columns as $c) { 
    if (isset($searchParams->$c) && trim($searchParams->$c) !== "") { 
     $conditions[$c] = $searchParams->{$c}; 
    } 
} 
return $this->db->table('candidates')->where($conditions); 

Aucune instruction if-else est nécessaire que lorsque le tableau est vide, NDB correctement ne rajoutez pas la clause WHERE.