【问题标题】:Zend DB Framework examine query for an updateZend DB 框架检查更新的查询
【发布时间】:2009-06-17 21:36:44
【问题描述】:

所以你可以使用这样的东西:

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

检查 Zend Db 框架将用于该 SELECT 查询的 sql。是否有一种等效的方式来查看 SQL 以进行更新?

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

【问题讨论】:

  • 与解决方案无关,但是当对象转换为字符串时会自动调用 __toString(),所以 echo $query;更容易输入

标签: zend-framework zend-db


【解决方案1】:

使用Zend_Db_Profiler捕获和报告SQL语句:

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

如果不需要,请记得关闭分析器!我与一位认为他有内存泄漏的人交谈过,但分析器为他正在运行的数百万个 SQL 查询中的每一个实例化了几个 PHP 对象。

PS:您应该在该查询中使用quoteInto()

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

【讨论】:

  • 谢谢,成功了。将我指向分析器也对我在其他方面有所帮助。
  • 我只在开发中保持开启状态。
  • update() 函数的“where”部分可以带一个数组吗?如 $db->update('pages', $data, array("url = ?" => $content, "date > ?" => $date);
  • @caligoanimus:老实说,我不确定,我已经忘记了 ZF 项目。最好在 ZF 邮件列表上询问或自己阅读代码。
【解决方案2】:

不,不是直接的,因为 Zend Framework 在适配器方法 Zend_Db_Adapter_Abstract::update: 中构建并执行 SQL:

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

您可以暂时插入一个 var_dump 并在此方法中退出以检查 sql 以确保其正确:

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

【讨论】:

    【解决方案3】:

    我想另一种方法是通过组合探查器数据来记录实际的 SQL 查询,而不是更改 ZF 库代码。

    $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);
    

    【讨论】:

    • 你试过了吗?它似乎不适用于 ZF 1.9.5。当您将数组提供给 quoteInto() 时,它会将其连接到以逗号分隔的字符串,并将结果替换为每个参数占位符。另外 quoteInto() 对字符串文字中的问号不是很聪明,它根本不支持命名参数占位符。
    • 没有。我没有尝试这是基于 Zend_Db_Profiler 和 Zend_Db API 的疯狂猜测。感谢您验证 ;D
    【解决方案4】:

    最近在寻找调试 zend_db_statement 的方法时遇到了这个问题。如果其他人在相同的搜索中遇到此问题,您可以使用以下功能。

    只需将“self::getDefaultAdapter()”替换为您获取数据库连接或适配器的方法即可。

    /**
     * replace any named parameters with placeholders
     * @param string $sql sql string with placeholders, e.g. :theKey
     * @param array $bind array keyed on placeholders, e.g. array('theKey', 'THEVALUE')
     * 
     * @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;        
    }
    

    【讨论】:

      猜你喜欢
      • 2017-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多