我在使用CakePHP 4中的sql函数 Package 器时遇到了困难。我使用的是SQLite 3和Cakephp 4.2.3 Strawberry。我的数据库表中有一个名为'date'的TEXT字段。'date'中的最小值和最大值分别是:'2020-01-15'和'2020-12- 31'.我有一个简单的查询:
$query = $this->find();
$query->select(['minDate' => $query->func()->min('date'),
'maxDate' => $query->func()->max('date')])
->where(['date <>' => ''])
->enableHydration(false);
$results = $query->toList();
$maxDate = $results[0]['maxDate'];
$minDate = $results[0]['minDate'];
生成我想要的SQL:
SELECT (MIN(date)) AS minDate, (MAX(date)) AS maxDate FROM temp_income TempIncome WHERE date <> :c0
但是,代码返回的是$minDate和$maxDate的“浮点”值:
$minDate = 2020
$maxDate = 2020
如果我直接在SQLite Studio中运行此语句,我会得到正确的结果(将""放在:c 0中)
minDate = '2020-01-15'
maxDate = '2020-12-31'
如果我在CakePHP中使用连接管理器和相同的SQL运行查询,我会得到正确的答案。
$connection = ConnectionManager::get('default');
$results = $connection->execute("SELECT min(date) as minDate, max(date) as maxDate from temp_income where date <> ''")->fetchAll('assoc');
minDate = '2020-01-15'
maxDate = '2020-12-31'
cake函数 Package 函数func()->min(‘date’)
正在执行不需要的类型转换。
深入研究一下vendor/cakephp/cakephp/src/database/FunctionsBuilder.php,如果没有定义其他类型,min和max的构建器被设置为返回'float',显然在本例中没有。我不知道为什么。我还没有深入研究。
public function max($expression, $types = []): AggregateExpression
{
return $this->aggregate('MAX', $this->toLiteralParam($expression), $types, current($types) ?: 'float');
}
public function min($expression, $types = []): AggregateExpression
{
return $this->aggregate('MIN', $this->toLiteralParam($expression), $types, current($types) ?: 'float');
}
min()和max()的正确行为是返回参数的数据类型,至少在Oracle和SQL Server中是这样,在SQLite中也是如此,因为原始查询可以正常工作。
这是CakePHP函数 Package 器中的一个bug吗?还是我遗漏了什么?
谢谢你!
1条答案
按热度按时间2nc8po8w1#
Greg施密特是正确的。min()和max()都接受类型参数。您需要深入研究FunctionsBuilder类的文档才能找到它:https://api.cakephp.org/4.1/class-Cake.Database.FunctionsBuilder.html#min
在我的例子中:
回想起来,这一点从我之前发布的函数声明中可以清楚地看到:
上面的代码解决了这个问题。