简体   繁体   English

如何在Zend Framework 2中设置sql_mode?

[英]How to set sql_mode in Zend Framework 2?

I'm currently having an issue with pagination in Zend Framework 2. 我目前在Zend Framework 2中存在分页问题。

This code 这段代码

public function findAllByCriteria(CourseSearchInput $input) {
    $concatDelimiter = self::CONCAT_DELIMITER;
    $select = new Select();
    $where = new Where();
    $having = new Having();
    $select->columns(array(
        'id', 'title', 'description'
    ));
    $select->from($this->tableGateway->getTable());
    $select
        ->join('coursedata', 'courses.id = coursedata.id', array(
            'relevance' => $this->buildRelevanceExpressionFromCriteria($input)
        ))
    ;
    $having
        ->greaterThanOrEqualTo('relevance', self::RELEVANCE_MIN);
    ;
    $select->where($where, Predicate::OP_AND);
    $select->having($having);
    $select->group(array('courses.id'));

    $dbAdapter = $this->tableGateway->getAdapter();
    // $dbAdapter->getDriver()->getConnection()->execute('SET sql_mode = "";');
    $adapter = new \Zend\Paginator\Adapter\DbSelect($select, $dbAdapter);
    $paginator = new \Zend\Paginator\Paginator($adapter);
    return $paginator;
}

create this SQL: 创建此SQL:

SELECT
    `courses`.`id` AS `id`,
    `courses`.`title` AS `title`,
    `courses`.`description` AS `description`,
    MATCH (coursedata.title) AGAINST ('Salsa') * 5 + MATCH (coursedata.description) AGAINST ('Salsa') * 2 AS `relevance`
FROM `courses`
INNER JOIN `coursedata` ON `courses`.`id` = `coursedata`.`id`
GROUP BY `courses`.`id`
HAVING `relevance` >= '3'

It ueses the MySQL Extensions to GROUP BY and cannot be executed, if the sql_mode is set to ONLY_FULL_GROUP_BY . 如果sql_mode设置为ONLY_FULL_GROUP_BY ,它将使用MySQL Extensions to GROUP BY ,并且无法执行。 So, I tried to reset the sql_mode before the statement is executed (see the commented out line above: $dbAdapter->getDriver()->getConnection()->execute('SET sql_mode = "";'); ). 因此,我试图在执行该语句之前重置sql_mode (请参见上面的注释行: $dbAdapter->getDriver()->getConnection()->execute('SET sql_mode = "";'); )。 But it didn't worked. 但这没有用。 So, how can I set the sql_mode in order to execute my non-standard SQL? 因此,如何设置sql_mode以便执行我的非标准SQL?

This may not be the answer to the question you are asking, but I can see you are going to have an issue with your query regardless when using Paginator. 这可能不是您所问问题的答案,但是无论使用Paginator还是什么,我都能看到您的查询会出现问题。

The DbSelect Adapter for the Paginator doesn't like the aggregate function in there (Group By) 用于分页器的DbSelect适配器不喜欢其中的聚合功能(分组​​依据)

The Paginator will try and use your query to build it's own query to calculate the "count" for items in the collection. 分页器将尝试使用您的查询来构建自己的查询,以计算集合中项目的“计数”。 This is broken due to you using an aggregate in your query, any groups etc will break the adapter. 由于您在查询中使用了聚合,因此该字段已损坏,任何组等都将破坏适配器。

if you check the default implementation you will see: 如果检查默认实现,您将看到:

/**
 * Returns the total number of rows in the result set.
 *
 * @return integer
 */
public function count()
{
    if ($this->rowCount !== null) {
        return $this->rowCount;
    }

    $select = clone $this->select;
    $select->reset(Select::COLUMNS);
    $select->reset(Select::LIMIT);
    $select->reset(Select::OFFSET);

    // This won't work if you've got a Group By in your query
    $select->columns(array('c' => new Expression('COUNT(1)')));

    $statement = $this->sql->prepareStatementForSqlObject($select);
    $result    = $statement->execute();
    $row       = $result->current();

    $this->rowCount = $row['c'];

    return $this->rowCount;
}

this doesn't like when you are using Group BY and will give back incorrect results. 这与您使用Group BY时不一样,并且会返回错误的结果。

You can create your own adataper, and extend the existing DbSelect and override the count method when you are planning to use Group BY; 您可以创建自己的数据器,并在计划使用Group BY时扩展现有的DbSelect并覆盖count方法。

Off the top of my head something like this should work, but may not be the most efficient way of doing it 像这样的事情应该可以解决,但可能不是最有效的方法

/**
 * Returns the total number of rows in the result set.
 * 
 * @return integer
 */
public function count()
{
    if ($this->rowCount !== null) {
        return $this->rowCount;
    }

    /**
     * If the query hasn't got 'GROUP BY' just try and use the old method
     */
    $stateGroup = $this->select->getRawState('group');
    if( ! isset($stateGroup) || empty($stateGroup)) {
        return parent::count();
    }

    $select = clone $this->select;
    $select->reset(Select::LIMIT);
    $select->reset(Select::OFFSET);

    $statement = $this->sql->prepareStatementForSqlObject($select);
    $result    = $statement->execute();

    $this->rowCount = $result->count();

    return $this->rowCount;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM