2017-03-13 6 views
1

Ich bin ein Problem mit einer SQL-Anweisung vorbereiten:Mehrere Variablen in vorbereitete Anweisung PHP

$statement = $conexion->prepare(
    'SELECT * FROM celulares 
    WHERE (MARCA = :marca) 

    AND 

    (CATEGORIA = :categoria1 OR CATEGORIA = :categoria2 OR CATEGORIA = :categoria3) 

    AND 

    (CATEGORIA2 = :categoria1 OR CATEGORIA2 = :categoria2 OR CATEGORIA2= :categoria3) 

    AND 

    (CATEGORIA3 = :categoria1 OR CATEGORIA3 = :categoria2 OR CATEGORIA3 = :categoria3)'); 

Geben Platzhalter Werte mit diesem:

$statement->execute(array(':categoria1' => $categoria1, 
         ':categoria2' => $categoria2, 
         ':categoria3' => $categoria3, 
         ':marca' => $query 
       )); 

$ query Wert variate kann, wenn meine Anwendung abhängig beginnt bei einigen Ergebnissen:

Ich habe eine Menge Dinge ausprobiert, aber keiner von denen ausgearbeitet es gibt eine leere ein rray, der einzige, der arbeitet, wurde diese Linie meiner vorbereiteten Aussage zu ändern:

WHERE (MARCA = :marca OR MARCA = :marca2 OR MARCA = :marca3) 

Und wie viele „MARCA“, wie Ergebnisse, ich denke, es ist nicht der beste Weg, es zu tun

AKTUALISIERT:

Jetzt mit iN Statement in meiner Abfrage (Danke Du mir geholfen)

Jetzt sieht es aus wie der Versuch:

$marcas = array("LG", "HUAWEI"); (Static values for test) 
$inQuery = implode(',', array_fill(0, count($marcas), '?')); 

$statement = $conexion->prepare(
'SELECT * FROM celulares 
WHERE (MARCA = IN (' . $inQuery . ')) 

AND 

(CATEGORIA = :categoria1 OR CATEGORIA = :categoria2 OR CATEGORIA = :categoria3) 

AND 

(CATEGORIA2 = :categoria1 OR CATEGORIA2 = :categoria2 OR CATEGORIA2= :categoria3) 

AND 

(CATEGORIA3 = :categoria1 OR CATEGORIA3 = :categoria2 OR CATEGORIA3 =  :categoria3)'); 


foreach ($marcas as $k => $marca) { 
$statement->bindValue(($k+1), $marca); 

} 

$statement->bindValue(':categoria1', $categoria1); 
$statement->bindValue(':categoria2', $categoria2); 
$statement->bindValue(':categoria3', $categoria3); 

$statement->execute(); 

Erste: Achtung: PDOStatement :: execute(): SQLSTATE [HY093]: Ungültige Parameternummer: gemischt Namen und Positionsparameter

Der Versuch, es zu beheben

+0

Werfen Sie einen Blick auf (http [Kann ich ein Array zu einem iN() Zustand binden?]: // stac koverflow.com/questions/920353/can-i-bind-an-array-to-an-in-condition) und [FIND_IN_SET() vs IN()] (http://stackoverflow.com/questions/4155873/find -in-set-vs-in) – mrun

+0

Ich denke, Sie müssen IN-Anweisung in Ihrer Abfrage und switch-case in PHP-Code verwenden. –

+0

ich glaube nicht, dass Sie einen Parameterwert in einer preparedStatement setzen können, wenn dieser Wert tatsächlich eine SQL-Anweisung ist, wie diese $ query = $ query. 'ODER MARCA = "APPLE"' ', das sieht wie sql-injection aus und das ist ein Grund, warum PS erstellt wurde. to protected/escape ... so könnte der Abfragewert als Text eingefügt werden (escaped) Ich schlage vor, Sie übergeben ein Array als '$ query' Liste von' MARCA's, dann verwenden Sie es um Ihr SQL zu erstellen: '" MARCA =: val1 ODER MARCA =: val2 "' .. .etc basierend auf der marca Array-Länge, und setze dann die Parameter ': val1,: val2 ...' und führe aus. – Yazan

Antwort

0

Nun, ich es beheben, wahrscheinlich es ist nicht der beste Weg, um es zu lösen, aber ich habe das jetzt:

Ich fülle Array mit Einträgen aus POST

$query = array(); 
$index = 0; 

foreach ($_POST as $entrada) { 
switch($entrada) { 
case "SAMSUNG": 
$query[] = "SAMSUNG"; 
break; 

case "LG": 
$query[] = "LG"; 
break; 

case "APPLE": 
$query[] = "APPLE"; 
break; 

case "HUAWEI": 
$query[] = "HUAWEI"; 
break; 
} 


} 
$inQuery = str_repeat('?,', count($query) - 1) . '?'; 

Hier ist meine neue Abfrage ist : Problem war, dass ich mixte "?"Mit Platzhalter (:), die

nicht empfohlen
 $statement = $conexion->prepare(
    "SELECT * FROM celulares 
    WHERE (MARCA IN($inQuery)) 

    AND 

    (CATEGORIA = ? OR CATEGORIA = ? OR CATEGORIA = ?) 

    AND 

    (CATEGORIA2 = ? OR CATEGORIA2 = ? OR CATEGORIA2= ?) 

    AND 

    (CATEGORIA3 = ? OR CATEGORIA3 = ? OR CATEGORIA3 = ?)"); 

Dann i bindValues ​​wie die

$c = 0; 
foreach ($query as $q => $queries) { 
     $c++; 
     $statement->bindValue(($q+1), $queries); 

} 


$statement->bindValue($c+1, $categoria1); 
$statement->bindValue($c+2, $categoria2); 
$statement->bindValue($c+3, $categoria3); 
$statement->bindValue($c+4, $categoria1); 
$statement->bindValue($c+5, $categoria2); 
$statement->bindValue($c+6, $categoria3); 
$statement->bindValue($c+7, $categoria1); 
$statement->bindValue($c+8, $categoria2); 
$statement->bindValue($c+9, $categoria3); 

$statement->execute(); 

$resultados = $statement->fetchAll(); 

ich viele Test mit viel querys tat und es funktioniert gut, es ist wahrscheinlich ein" dirty "Lösung, aber ich werde weiter zu lernen

Dank u alle mir geholfen

0

Sie können Ihre Abfrage vereinfachen:

SELECT * FROM celulares 
WHERE (MARCA = :marca) 
AND (:categoria1,:categoria2,:categoria3) 
    IN (
    (CATEGORIA,CATEGORIA2,CATEGORIA3), 
    (CATEGORIA,CATEGORIA3,CATEGORIA2), 
    (CATEGORIA2,CATEGORIA,CATEGORIA3), 
    (CATEGORIA2,CATEGORIA3,CATEGORIA), 
    (CATEGORIA3,CATEGORIA,CATEGORIA2), 
    (CATEGORIA3,CATEGORIA2,CATEGORIA) 
) 

Auf diese Weise geben Sie nur einmal die Kategorien ein und vergleichen sie mit den sechs möglichen Permutationen von drei Kategorien.

Das heißt, dies ist ein Zeichen, dass Ihre Datenbank in sehr schlechter Form ist. Im Allgemeinen ist jede Art von "column2", "column3" -System ein Zeichen dafür, dass Sie Ihre Datenbank umstrukturieren müssen - die Art von Abfragen, mit denen Sie enden, wie oben beschrieben, wird nur noch schlimmer werden.

Speziell in diesem Fall würde nur CATEGORIEA4 hinzufügen die Anzahl der Permutationen, die Sie definieren müssen von 6 bis 24 !!

EDIT: Ich vermisste vollständig den Teil über :marca und IN - ich auch auf den schlechten Zustand der Datenbank in Bezug auf Kategorien fokussiert wurde, sorry!

+0

Danke dir Niet, ich bin neu in dieser Welt, wie du sehen kannst, Kategorien werden vom Benutzer ausgewählt und er kann nur drei auswählen, also wird es keine anderen Möglichkeiten geben, ich bin mir sicher, dass es einen anderen Weg gibt, es besser zu machen, Ich werde herausfinden, was ich dagegen tun kann –

Verwandte Themen