2009-06-17 25 views
19

Więc można użyć czegoś takiego:DB zbadać zapytanie o aktualizację

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

zbadać sql, że Zend Framework Db zamierza użyć do tego zapytania SELECT. Czy istnieje odpowiednia metoda wyświetlania kodu SQL dla aktualizacji?

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

niezwiązane z rozwiązaniem, ale __toString() jest wywoływana automatycznie, gdy obiekt jest odlewana na sznurku, więc echo $ query; jest łatwiejsze do wpisania – chris

Odpowiedz

30

Zastosowanie Zend_Db_Profiler do przechwytywania i raportowania SQL:

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

Pamiętaj, aby włączyć profilera off, jeśli nie jest to potrzebne! Rozmawiałem z jednym gościem, który myślał, że miał wyciek pamięci, ale to był profiler tworzący kilka obiektów PHP dla każdego z milionów zapytań SQL, z których korzystał.

PS: Należy użyć quoteInto() w tym zapytaniu:

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

Dzięki, że to się udało. Wskazywanie mnie na profilera pomogło mi również w innych obszarach. –

+0

Utrzymuję to tylko w dev. – joedevon

+1

Czy funkcja "where" funkcji update() może przyjmować tablicę? Takich jak $ db-> update ('pages', $ data, array ("url =?" => $ Content, "date>?" => $ Date); – caligoanimus

2

Nie, nie bezpośrednio, ponieważ Zend Framework buduje i wykonuje SQL wewnątrz metody adapter Zend_Db_Adapter_Abstract :: zmiana:

/** 
* 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; 
} 

Możesz tymczasowo wstawić plik var_dump i zamknąć tę metodę, aby sprawdzić sql, aby upewnić się, że jest poprawny:

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

Innym sposobem jest rejestrowanie rzeczywistych zapytań SQL, zamiast zmieniania kodu biblioteki ZF, poprzez łączenie danych profilera.

$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

Czy próbowałeś tego? Wydaje się, że nie działa on w ZF 1.9.5 Kiedy podasz tablicę do cytowaniaInto(), łączy się z łańcuchem oddzielonym przecinkami i zastępuje wynik dla każdego symbolu zastępczego, również quoteInto() nie jest bardzo inteligentny w odniesieniu do znaków zapytania w literałach łańcuchów i nie obsługuje w ogóle obiektów zastępczych o nazwanych parametrach –

+0

Nie. nie próbuj, to było dzikie domysły oparte na API Zend_Db_Profiler i Zend_Db. Dzięki za weryfikację; D – raphaelstolt

0

Ostatnio natknąłem się na to, szukając sposobu debugowania zend_db_statement. Jeśli ktoś inny natknie się na to z tym samym wyszukiwaniem, możesz skorzystać z poniższej funkcji.

Po prostu zastąp "self :: getDefaultAdapter()" metodą uzyskania połączenia lub adaptera 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;   
} 
Powiązane problemy