2016-03-19 19 views
0

versuchen, die folgende Abfrage in Zend Framework 1 zu schreiben:ZF - MySQL SUM Abfrage mit CASE WHEN

SELECT 
    SUM(CASE WHEN column2 = 'value1' THEN column3 END) AS 'mySpecialSum', 
FROM `my_table` 
WHERE column4='value2' AND column5='value3' 

zu testen, ich schreibe es so:

$select = $this->select() 
    ->from('my_table', array(
     'mySpecialSum'=>'SUM(CASE WHEN column2 = "value1" THEN column3 END)' 
    )) 
    ->where('column4=?', $value2) 
    ->where('column5=?', $value3); 
$data = $this->fetchAll($select); 

, die funktioniert - aber Ich muss wissen, wie als eine Variable - zB $value1 - vorzugsweise mit Platzhaltern, so dass die Aussage "vorbereitet" - um die Wahrscheinlichkeit der SQL-Injektion zu minimieren.

Derzeit befinden sich zwei Optionen versuchen (die nicht berufstätig sind):

$select = $this->select() 
    ->from('my_table', array(
     'mySpecialSum'=>'SUM(CASE WHEN column2 = "{$value1}" THEN column3 END)' 
    )) 
    ->where('column4=?', $value2) 
    ->where('column5=?', $value3); 
$data = $this->fetchAll($select); 

ODER

$select = $this->select() 
    ->from('my_table', array(
     'mySpecialSum'=>'SUM(CASE WHEN column2 = "{$this->_db->quote($value1)}" THEN column3 END)' 
    )) 
    ->where('column4=?', $value2) 
    ->where('column5=?', $value3); 
$data = $this->fetchAll($select); 

Antwort

1

Nach einigen Recherchen here auf vorbereitete Anweisungen, scheint es die beste Methode ist:

$sql = 'SELECT SUM(CASE WHEN column2 = ? THEN column3 END) AS "mySpecialSum", 
FROM my_table 
WHERE content_type = ? 
AND content_id = ?'; 

$preparedStatement = $this->getAdapter()->query($sql, array($value1, $value2, $value3)); 
$data = $preparedStatement->fetchAll(); 

Zwei Optionen, die sind auch arbeiten - aber beide wie Hacks fühlen (und übrigens auch etwas langsamer als die ‚vorbereitete Anweisung‘ -Methode oben) - sind:

$select = $this->select() 
    ->from('my_table', array(
     'mySpecialSum'=>'SUM(CASE WHEN column2 = "' . $value1 . '" THEN column3 END)' 
    )) 
    ->where('column4=?', $value2) 
    ->where('column5=?', $value3); 
$data = $this->fetchAll($select); 

und:

$start = microtime(); 

$select = $this->select() 
    ->from('my_table', array(
     'mySpecialSum'=>'SUM(CASE WHEN column2 = ' . $this->_db->quote($value1) . ' THEN column3 END)' 
    )) 
    ->where('column4=?', $value2) 
    ->where('column5=?', $value3); 
$data = $this->fetchAll($select); 

$end = microtime(); 
$timeTaken = $end - $start; 

die microtime() vor & nach
... zeigt vernachlässigbaren Unterschied für die Verwendung von zf $this->_db->quote() oder nicht

jedoch seltsam gibt es ein 5-fach: ein Geschwindigkeitstest die beiden Methoden vergleichen Geschwindigkeitssteigerung bei Verwendung von $this->getAdapter()->select() statt einfach $this->select():

$select = $this->getAdapter() 
    ->select() 
    ->from('my_table', array(
     'mySpecialSum'=>'SUM(CASE WHEN column2 = ' . $this->_db->quote($value1) . ' THEN column3 END)' 
    )) 
    ->where('column4=?', $value2) 
    ->where('column5=?', $value3); 
$data = $this->getAdapter()->fetchAll($select);