Mysql 如何在Zend Framework 2中设置sql_模式?
我目前在Zend Framework 2中遇到分页问题 此代码Mysql 如何在Zend Framework 2中设置sql_模式?,mysql,sql,zend-framework2,zend-db,sql-mode,Mysql,Sql,Zend Framework2,Zend Db,Sql Mode,我目前在Zend Framework 2中遇到分页问题 此代码 public function findAllByCriteria(CourseSearchInput $input) { $concatDelimiter = self::CONCAT_DELIMITER; $select = new Select(); $where = new Where(); $having = new Having(); $select->columns(arr
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;
}
创建此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'
如果将
sql\u模式设置为ONLY\u FULL\u GROUP\u BY
,则会使用,并且无法执行。因此,我尝试在执行语句之前重置sql_模式
(请参阅上面注释掉的行:$dbAdapter->getDriver()->getConnection()->execute('SET sql_mode=“”;);
)。但它不起作用。那么,如何设置sql\u模式
以执行我的非标准sql?这可能不是您所问问题的答案,但我可以看出,无论使用Paginator时,您的查询都会有问题
分页器的DbSelect适配器不喜欢其中的聚合函数(Group By)
分页器将尝试使用您的查询构建自己的查询,以计算集合中项目的“计数”。这是由于您在查询中使用了聚合而中断的,任何组等都将中断适配器
如果选中默认实现,您将看到:
/**
* 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;
}
这与使用Group BY时不同,会返回不正确的结果
当您计划使用Group BY时,您可以创建自己的ADACTAPE,并扩展现有的DbSelect和覆盖count方法
在我脑子里,像这样的事情应该是可行的,但可能不是最有效的方式
/**
* 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;
}
这可能不是您要问的问题的答案,但我可以看出,无论何时使用Paginator,您的查询都会有问题
分页器的DbSelect适配器不喜欢其中的聚合函数(Group By)
分页器将尝试使用您的查询构建自己的查询,以计算集合中项目的“计数”。这是由于您在查询中使用了聚合而中断的,任何组等都将中断适配器
如果选中默认实现,您将看到:
/**
* 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;
}
这与使用Group BY时不同,会返回不正确的结果
当您计划使用Group BY时,您可以创建自己的ADACTAPE,并扩展现有的DbSelect和覆盖count方法
在我脑子里,像这样的事情应该是可行的,但可能不是最有效的方式
/**
* 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;
}
这只是一个假设,因为我对sql的了解很少,但也许您可以在启动时执行该命令?在driver\u选项中
addPDO::MYSQL\u ATTR\u INIT\u COMMAND=>“set sql\u mode=”“”
。应该有(另外)另一种方法来实现这一点,因为我可以使用set NAMES
或set sql\u mode
。无论如何我已经尝试过这两种方法:'driver\u options'=>array(PDO::MYSQL\u ATTR\u INIT\u COMMAND=>'SET NAMES'UTF8\','SET SESSION sql\u mode=\'''\'''''',
和'driver\u options'=>array(PDO::MYSQL\u ATTR\u INIT\u COMMAND=>'SET SESSION sql\u mode='\'''''>,
。我打算用SQL\u mode=''
消除SQL错误,它仍然存在。但可能模式没有设置?我如何检查当前的PDO设置/sql\u模式
?这只是一个假设,因为我对sql的了解很少,但也许您可以在启动时执行该命令?在driver\u选项中
addPDO::MYSQL\u ATTR\u INIT\u COMMAND=>“set sql\u mode=”“”
。应该有(另外)另一种方法来实现这一点,因为我可以使用set NAMES
或set sql\u mode
。无论如何我已经尝试过这两种方法:'driver\u options'=>array(PDO::MYSQL\u ATTR\u INIT\u COMMAND=>'SET NAMES'UTF8\','SET SESSION sql\u mode=\'''\'''''',
和'driver\u options'=>array(PDO::MYSQL\u ATTR\u INIT\u COMMAND=>'SET SESSION sql\u mode='\'''''>,
。我打算用SQL\u mode=''
消除SQL错误,它仍然存在。但可能模式没有设置?如何检查当前的PDO设置/sql\u模式
?非常感谢!它(对我来说)起作用了!但是,groupby
有时会影响/减少所选行的总数。这意味着,当我们从语句中删除它时,我们可能会得到一个大于实际选择的计数。对吗?或者我误解了/忽略了什么?这就是为什么这里有一个检查,如果选择对象中没有组,它只使用旧的计数方法。我相信这并不完美,需要做一些工作,但这是一个让您开始的示例;-)这甚至是一个很好的例子!再次非常感谢您!:)万分感谢!它(对我来说)起作用了!但是,groupby
有时会影响/减少所选行的总数。这意味着,当我们从语句中删除它时,我们可能会得到一个大于实际选择的计数。对吗?或者我误解了/忽略了什么?这就是为什么这里有一个检查,如果选择对象中没有组,它只使用旧的计数方法。我相信这并不完美,需要做一些工作,但这是一个让您开始的示例;-)这甚至是一个很好的例子!再次非常感谢您!:)