(PHP 8 >= 8.4.0)
Pdo\Sqlite::createAggregate — Registra uma função de agregação definida pelo usuário para uso em instruções SQL
$name
,$step
,$finalize
,$numArgs
= -1Este método é semelhante a Pdo\Sqlite::createFunction() exceto que registra funções que podem ser usadas para calcular um resultado agregado em todas as linhas de uma consulta.
A principal diferença entre este método e Pdo\Sqlite::createFunction() é que duas funções são necessárias para gerenciar a agregação.
Usando este método é possível substituir funções SQL nativas.
name
step
Esta função precisa ser definida como:
context
null
para a primeira linha; nas linhas subsequentes terá o valor
que foi retornado anteriormente da função step; deve-se usar
isso para manter o estado agregado.
rownumber
value
values
context
na próxima chamada das funções step
ou finalize.
finalize
Esta função precisa ser definida como:
context
Contém o valor de retorno da última chamada para a função step.
rowcount
Contém o número de linhas nas quais a agregação foi executada.
numArgs
Exemplo #1 Exemplo de Pdo\Sqlite::createAggregate()
Neste exemplo, criaremos uma função agregada personalizada chamada
max_length
que pode ser usada em consultas SQL.
Neste exemplo, estamos criando uma função agregadora,
chamada max_length
, que calculará o comprimento
da string mais longa em uma das colunas da tabela.
Para cada linha, a função max_len_step
é chamada e
passa um parâmetro $context
.
O parâmetro context é como qualquer outra variável PHP e pode ser configurado para
conter um array ou até mesmo um object.
Neste exemplo, estamos usando-o para manter o comprimento máximo que vimos até agora;
se $string tiver um comprimento maior que o máximo atual,
atualizamos o contexto para manter esse novo comprimento máximo.
Após todas as linhas terem sido processadas,
o SQLite chama a função max_len_finalize
para determinar
o resultado agregado.
É possível realizar algum tipo de cálculo baseado nos dados em $context
.
Neste exemplo básico o resultado foi calculado à medida que a consulta avançava,
para que o valor do contexto pudesse ser retornado diretamente.
<?php
$data = [
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine',
'ten',
];
$db = new Pdo\Sqlite('sqlite::memory:');
$db->exec("CREATE TABLE strings(a)");
$insert = $db->prepare('INSERT INTO strings VALUES (?)');
foreach ($data as $str) {
$insert->execute(array($str));
}
$insert = null;
function max_len_step($context, $row_number, $string)
{
if (strlen($string) > $context) {
$context = strlen($string);
}
return $context;
}
function max_len_finalize($context, $row_count)
{
return $context === null ? 0 : $context;
}
$db->createAggregate('max_len', 'max_len_step', 'max_len_finalize');
var_dump($db->query('SELECT max_len(a) from strings')->fetchAll());
?>
NÃO é recomendado que se armazene uma cópia dos valores no contexto e depois processe-os no final, pois faria com que o SQLite usasse muita memória para processar a consulta - basta pensar em quanta memória seria necessárias se um milhão de linhas fossem armazenadas na memória, cada uma contendo uma string de 32 bytes de comprimento.