CakePHP 4最小值和最大值的SQL函数 Package 器返回不正确的数据类型

bvk5enib  于 2022-11-11  发布在  PHP
关注(0)|答案(1)|浏览(148)

我在使用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吗?还是我遗漏了什么?
谢谢你!

2nc8po8w

2nc8po8w1#

Greg施密特是正确的。min()和max()都接受类型参数。您需要深入研究FunctionsBuilder类的文档才能找到它:https://api.cakephp.org/4.1/class-Cake.Database.FunctionsBuilder.html#min
在我的例子中:

$query->select(['minDate' => $query->func()->min('date', ['text']),
                  'maxDate' => $query->func()->max('date', ['text'])])

回想起来,这一点从我之前发布的函数声明中可以清楚地看到:

public function max($expression, $types = []): AggregateExpression

上面的代码解决了这个问题。

相关问题