PHP 8.4.2 Released!

Pdo\Sqlite::createAggregate

(PHP 8 >= 8.4.0)

Pdo\Sqlite::createAggregate Регистрирует агрегирующую пользовательскую функцию для использования в SQL-выражениях

Описание

public Pdo\Sqlite::createAggregate(
    string $name,
    callable $step,
    callable $finalize,
    int $numArgs = -1
): bool

Метод похож на Pdo\Sqlite::createFunction(), за исключением того, что он регистрирует функции, которые могут быть использованы для вычисления результата, агрегированного по всем строкам запроса.

Ключевое отличие метода от Pdo\Sqlite::createFunction() заключается в том, что для управления агрегатом требуется две функции.

Подсказка

С помощью метода можно переопределить собственные SQL-функции.

Список параметров

name
Имя функции, используемой в SQL-выражениях.
step
Callback-функция, вызываемая для каждой строки набора результатов. Callback-функция должна накапливать результат и сохранять его в контексте агрегации.

Сигнатура функции должна быть определена как:

step(
    mixed $context,
    int $rownumber,
    mixed $value,
    mixed ...$values
): mixed
context
null для первой строки; в последующих строках это будет значение, которое ранее было возвращено функцией step; это необходимо использовать для поддержания агрегатного состояния.
rownumber
Номер текущей строки.
value
Первый аргумент, передаваемый агрегату.
values
Дополнительные аргументы, передаваемые агрегату.
Возвращаемое значение функции будет использовано в качестве аргумента context при следующем вызове функций step или finalize.

finalize
Callback-функция для агрегации «пошаговых» данных из каждой строки. После обработки всех строк будет вызвана функция, которая должна получить данные из контекста агрегации и вернуть результат. Callback-функция должна возвращать тип, понятный SQLite (например, скалярный тип).

Сигнатура функции должна быть определена как:

fini(mixed $context, int $rowcount): mixed
context

Хранит значение, возвращённое при последнем вызове функции step.

rowcount

Указывает количество строк, по которым было выполнено агрегирование.

Возвращаемое значение функции будет использоваться в качестве возвращаемого значения для агрегата.

numArgs
Подсказка парсеру SQLite, если callback-функция принимает заданное количество аргументов.

Возвращаемые значения

Функция возвращает true, если выполнилась успешно, или false, если возникла ошибка.

Примеры

Пример #1 Пример использования метода Pdo\Sqlite::createAggregate()

В этом примере создаётся пользовательская агрегатная функция с именем max_length, которую можно использовать в SQL-запросах.

В этом примере создаётся агрегирующая функция с именем max_length, которая будет вычислять длину самой длинной строки в одном из столбцов таблицы. Для каждой строки вызывается функция max_len_step, которой передаётся параметр $context. Параметр context, как и любая другая переменная PHP, может содержать массив (array) или даже объект (object). В этом примере он используется для хранения максимальной длины, которую уже была обработана; если $string длиннее, чем текущий максимум, контекст обновляется, чтобы содержать новую максимальную длину.

После обработки всех строк, SQLite вызывает функцию max_len_finalize для определения агрегированного результата. Можно выполнить какое-либо вычисление на основе данных в $context. В данном примере результат вычислялся по мере выполнения запроса, поэтому значение контекста может быть возвращено напрямую.

<?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());

?>
Подсказка

НЕ рекомендуется хранить копию значений в контексте и затем обрабатывать их в конце, так как SQLite будет использовать много памяти для обработки запроса – просто подумайте, сколько памяти вам понадобится, если в памяти будет храниться миллион строк, каждая из которых будет содержать строку длиной 32 байта.

Смотрите также

  • Pdo\Sqlite::createFunction() - Регистрирует определяемую пользователем функцию для использования в SQL-выражениях
  • Pdo\Sqlite::createCollation() - Регистрирует определяемую пользователем функцию для использования в качестве функции сопоставления в SQL-выражениях
  • sqlite_create_function()
  • sqlite_create_aggregate()
Добавить

Примечания пользователей

Пользователи ещё не добавляли примечания для страницы
To Top