【问题标题】:WHERE IN sql query using Zend_DbWHERE IN 使用 Zend_Db 的 sql 查询
【发布时间】:2012-02-29 02:04:11
【问题描述】:

Zend 框架初学者在这里。我正在尝试获取视频游戏数据库的所有 Xbox 标题。一张桌子包含游戏。另一个表包含游戏类型(即 Xbox、Xbox Live Arcade、...)。我通常使用以下查询来获取 Xbox 游戏。

如何使用 Zend_Db 执行相同的查询?

谢谢,

SELECT titleGame
FROM Game 
WHERE idGameType IN (
    SELECT idGameType 
    FROM GameType 
    WHERE nameGameType = 'Xbox')

【问题讨论】:

    标签: zend-framework zend-db


    【解决方案1】:

    这可以在 Zend Framework 中以几种方式重写。这是我通常使用Zend_Db_Table_Select 编写选择的方式。

    <?php
    
    // For brevity, $dbTable = a Zend_Db_Table object
    
    // first construct the subquery/join for the IN clause
    // SELECT idGameType FROM GameType HERE nameGameType = 'Xbox'
    $subselect = $dbTable->select()
                         ->from('GameType', array('idGameType'))
                         ->where('nameGameType = ?', 'Xbox'); // quotes Xbox appropriately, prevents SQL injection and errors
    
    // construct the primary select
    // SELECT titleGame FROM Game WHERE idGameType IN (subquery)
    $select = $dbTable->select()
                      ->setIntegrityCheck(false) // allows us to select from another table
                      ->from($dbTable, array('titleGame'))
                      ->where('idGameType IN (?)', $subselect);
    
    $results = $select->query()->fetchAll(); // will throw an exception if the query fails
    if(0 === count($results)) {
        echo "No Results";
    }else{
        foreach($results as $result){
            echo $result['titleGame'] . '<br />';
        }
    }
    

    您也可以将 SQL 编写为字符串,但在可能的情况下,面向对象的方法是理想的,因为它使查询更具可移植性,最重要的是可以很容易地保护您的查询。

    例子:

    $db = Zend_Db_Table::getDefaultAdapter();  // get the default Db connection
    $db->select("select * from table where id = 3"); // doable, but not recommended
    

    您还可以创建一个prepared statementZend_Db_Statement 到PHP 的PDO 扩展。

    $sql = 'SELECT * FROM bugs WHERE reported_by = ? AND bug_status = ?';
    $stmt = new Zend_Db_Statement_Mysqli($db, $sql);
    $stmt->execute(array('goofy', 'FIXED'));
    

    第一种方法,面向对象的流畅界面是您看到最多的方法,也是我推荐开始使用和使用的方法。

    通读Zend_Db Manual Pages,尤其是Zend_Db_Table_SelectZend_Db_TableZend_Db_Adapter,了解更多信息。即使是快速阅读 ZF Quickstart 并特别注意 Db 部分也是有帮助的。它将展示如何将表类设置为应用程序和数据库之间的网关。

    【讨论】:

    • 我试了一下没有成功(见我的控制器here的初始化函数)。我收到应用程序错误。例外是“选择查询不能与另一个表连接”。如果我对嵌入式选择返回的结果进行硬编码,那很好(参见here)。
    • 因为您正在使用Games DbTable 作为查询GameType 的子查询,请尝试在该查询的select() 部分之后添加setIntegrityCheck(false)。或者您可以使用Application_Model_DbTable_GameType 进行子选择,然后您只需要像现在这样在第二个查询中使用setIntegrityCheck(false)
    【解决方案2】:
    SELECT titleGame FROM Game
    LEFT JOIN GameType ON GameType.idGameType = Game.idGameType
    WHERE GameType.nameGameType = 'Xbox'
    

    为什么不使用连接呢?根据我的经验,IN 内部的子选择在 MySQL 中非常慢。

    $select = $db->select();
    $select->from('Game', array('titleGame'));
    $select->joinLeft('GameType', 'GameType.idGameType = Game.idGameType', array());
    $select->where("GameType.nameGameType = 'Xbox'");
    

    【讨论】:

    • 我会考虑你的回答。桌面开发人员在这里。我已经有一段时间没有使用数据库了。
    猜你喜欢
    • 2016-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-17
    • 1970-01-01
    • 2012-06-21
    • 2022-01-21
    • 2013-02-14
    相关资源
    最近更新 更多