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

# Pdo\Sqlite::createAggregate

(PHP 8 >= 8.4.0)

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

### Описание

public function 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-функция должна накапливать результат и сохранять его в контексте агрегации.

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

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

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

  function 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()

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open