Enregistre une fonction utilisateur d'agrégation pour une utilisation dans les instructions SQL

# Pdo\Sqlite::createAggregate

(PHP 8 >= 8.4.0)

Pdo\Sqlite::createAggregate — Enregistre une fonction utilisateur d'agrégation pour une utilisation dans les instructions SQL

### Description

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

Cette méthode est similaire à Pdo\Sqlite::createFunction() sauf qu'elle enregistre des fonctions qui peuvent être utilisées pour calculer un résultat agrégé sur l'ensemble des lignes d'une requête.

La principale différence entre cette méthode et Pdo\Sqlite::createFunction() est que deux fonctions sont nécessaires pour gérer l'agrégation.

Astuce

En utilisant cette méthode, il est possible de remplacer les fonctions SQL natives.

### Liste de paramètres

`name`
  Le nom de la fonction utilisé dans les instructions SQL.
`step`
  La fonction de rappel appelée pour chaque ligne de l'ensemble de résultats. La fonction de rappel doit accumuler le résultat et le stocker dans le contexte d'agrégation.

  Cette fonction doit être définie comme suit :

  function step(
  mixed `$context`,
  int `$rownumber`,
  mixed `$value`,
  mixed `...$values`
  ): mixed
  `context`
    `null` pour la première ligne ; sur les lignes suivantes, elle aura la valeur qui a été précédemment retournée par la fonction de rappel ; il faut utiliser ceci pour maintenir l'état de l'agrégation.
  `rownumber`
    Le numéro de la ligne actuelle.
  `value`
    Le premier argument passé à l'agrégation.
  `values`
    Les arguments supplémentaires passés à l'agrégation.
  La valeur de retour de cette fonction sera utilisée comme argument `context` dans l'appel suivant de la fonction de rappel ou de finalisation.
`finalize`
  La fonction de rappel pour agréger les données "étape" de chaque ligne. Une fois que toutes les lignes ont été traitées, cette fonction sera appelée, et elle devrait ensuite prendre les données du contexte d'agrégation et retourner le résultat. Cette fonction de rappel doit retourner un type compris par SQLite (c'est-à-dire un type scalaire).

  Cette fonction doit être définie comme suit :

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

    Contient la valeur de retour du tout dernier appel à la fonction de rappel.

  `rowcount`

    Contient le nombre de lignes sur lesquelles l'agrégation a été effectuée.

  La valeur de retour de cette fonction sera utilisée comme valeur de retour pour l'agrégation.
`numArgs`
  Indication au parseur SQLite si la fonction de rappel accepte un nombre prédéterminé d'arguments.

### Valeurs de retour

Cette fonction retourne `true` en cas de succès ou `false` si une erreur survient.

### Exemples

Exemple #1 Pdo\Sqlite::createAggregate() example

Dans cet exemple, nous allons créer une fonction d'agrégation personnalisée nommée `max_length` qui peut être utilisée dans les requêtes SQL.

Dans cet exemple, nous allons créer une fonction d'agrégation nommée `max_length` qui va calculer la longueur de la chaîne la plus longue dans l'une des colonnes de la table. Pour chaque ligne, la fonction `max_len_step` est appelée et passe un paramètre `$context`. Le paramètre de contexte est comme n'importe quelle autre variable PHP et peut être défini pour contenir un array ou même un object. Dans cet exemple, nous l'utilisons pour contenir la longueur maximale que nous avons vue jusqu'à présent ; si la $string a une longueur plus longue que la longueur maximale actuelle, nous mettons à jour le contexte pour contenir cette nouvelle longueur maximale.

Après que toutes les lignes ont été traitées, SQLite appelle la fonction `max_len_finalize` pour déterminer le résultat agrégé. Il est possible d'effectuer un certain type de calcul basé sur les données dans `$context`. Dans cet exemple de base, le résultat a été calculé au fur et à mesure que la requête progressait, donc la valeur de contexte peut être directement retournée.

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

    ?>

Astuce

Il n'est PAS recommandé de stocker une copie des valeurs dans le contexte et des traiter à la fin, car on obligerait SQLite à utiliser beaucoup de mémoire pour traiter la requête - imaginez combien de mémoire l'on aurait besoin si un million de lignes étaient stockées en mémoire, chacune contenant une chaîne de 32 octets de longueur.

### Voir aussi

- Pdo\Sqlite::createFunction() - Enregistre une fonction utilisateur pour une utilisation dans les instructions SQL
- Pdo\Sqlite::createCollation() - Enregistre une fonction utilisateur de tri pour une utilisation dans les instructions SQL
- sqlite_create_function()
- sqlite_create_aggregate()

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