2009-06-17 11 views
19

Così si può usare qualcosa di simile:Zend Framework DB esaminare query per un aggiornamento

$query = $db->select(); 
$query->from('pages', array('url')); 
echo $query->__toString(); 

per esaminare lo sql che il Db Framework Zend sta andando da utilizzare per tale query SELECT. C'è un modo equivoco per visualizzare l'SQL per un aggiornamento?

$data = array(
    'content'  => stripslashes(htmlspecialchars_decode($content)) 
);  
$n = $db->update('pages', $data, "url = '".$content."'"); 
?? 
+1

estranei alla soluzione ma __toString() viene chiamato automaticamente quando un oggetto viene colato in una stringa, $ query in modo eco; è più facile digitare – chris

risposta

30

Usa Zend_Db_Profiler per catturare e segnalare le istruzioni SQL:

$db->getProfiler()->setEnabled(true); 
$db->update(...); 
print $db->getProfiler()->getLastQueryProfile()->getQuery(); 
print_r($db->getProfiler()->getLastQueryProfile()->getQueryParams()); 
$db->getProfiler()->setEnabled(false); 

ricordarsi di accendere il profiler off se non ne hai bisogno! Ho parlato con un tizio che pensava di avere una perdita di memoria, ma era il profiler che istanziava alcuni oggetti PHP per ognuno dei milioni di query SQL che stava eseguendo.

PS: Si dovrebbe usare quoteInto() in quella query:

$n = $db->update('pages', $data, $db->quoteInto("url = ?", $content)); 
+0

Grazie, l'ha fatto. Indicarmi il profiler mi ha aiutato anche in altre aree. –

+0

L'ho solo tenuto acceso in dev. – joedevon

+1

La sezione "where" della funzione update() può utilizzare una matrice? Come $ db-> update ('pages', $ data, array ("url =?" => $ Content, "date>?" => $ Date); – caligoanimus

2

No, non direttamente, dal momento che Zend Framework costruisce ed esegue il codice SQL all'interno del metodo adattatore Zend_Db_Adapter_Abstract :: aggiornamento:

/** 
* Updates table rows with specified data based on a WHERE clause. 
* 
* @param mixed  $table The table to update. 
* @param array  $bind Column-value pairs. 
* @param mixed  $where UPDATE WHERE clause(s). 
* @return int   The number of affected rows. 
*/ 
public function update($table, array $bind, $where = '') 
{ 
    /** 
    * Build "col = ?" pairs for the statement, 
    * except for Zend_Db_Expr which is treated literally. 
    */ 
    $set = array(); 
    foreach ($bind as $col => $val) { 
     if ($val instanceof Zend_Db_Expr) { 
      $val = $val->__toString(); 
      unset($bind[$col]); 
     } else { 
      $val = '?'; 
     } 
     $set[] = $this->quoteIdentifier($col, true) . ' = ' . $val; 
    } 

    $where = $this->_whereExpr($where); 

    /** 
    * Build the UPDATE statement 
    */ 
    $sql = "UPDATE " 
     . $this->quoteIdentifier($table, true) 
     . ' SET ' . implode(', ', $set) 
     . (($where) ? " WHERE $where" : ''); 

    /** 
    * Execute the statement and return the number of affected rows 
    */ 
    $stmt = $this->query($sql, array_values($bind)); 
    $result = $stmt->rowCount(); 
    return $result; 
} 

È possibile, temporaneamente, inserire un var_dump ed uscire all'interno di questo metodo per ispezionare lo sql per assicurarsi che sia corretto:

0

Un altro modo è quello di registrare la query SQL effettiva, anziché modificare il codice della libreria ZF, combinando i dati del profiler.

$db->getProfiler()->setEnabled(true); 

$db->update(...); 

$query = $db->getProfiler()->getLastQueryProfile()->getQuery(); 

$queryParams = $db->getProfiler()->getLastQueryProfile()->getQueryParams(); 

$logger->log('SQL: ' . $db->quoteInto($query, $queryParams), Zend_Log::DEBUG); 

$db->getProfiler()->setEnabled(false); 
+1

Hai provato questo? Non sembra funzionare in ZF 1.9.5 Quando si assegna un array a quoteInto(), si unisce a una stringa separata da virgole e sostituisce il risultato per ogni segnaposto di parametro, anche quoteInto() non è molto intelligente riguardo ai punti interrogativi all'interno di stringhe letterali e non supporta affatto segnaposti con parametri denominati –

+0

No. I didn prova che è stata un'ipotesi basata sulle API Zend_Db_Profiler e Zend_Db. Grazie per aver verificato; D – raphaelstolt

0

Ultimamente ho trovato questo modo di eseguire il debug di uno stato zend_db_statement. Se qualcun altro lo trova con la stessa ricerca, puoi utilizzare la seguente funzione.

Basta sostituire "self :: getDefaultAdapter()" con il metodo per ottenere una connessione o un adattatore DB.

/** 
* replace any named parameters with placeholders 
* @param string $sql sql string with placeholders, e.g. :compCode 
* @param array $bind array keyed on placeholders, e.g. array('compCode', 'WHMA20') 
* 
* @return String sql statement with the placeholders replaced 
*/ 
public static function debugNamedParamsSql($sql, array $bind) { 
    $sqlDebug = $sql; 
    foreach($bind as $needle => $replace) { 
     $sqlDebug = str_replace( 
           ':' . $needle, 
           self::getDefaultAdapter()->quote($replace), 
           $sqlDebug 
     ); 
    }   
    return $sqlDebug;   
} 
Problemi correlati