PDO::sqliteCreateAggregate
SQL 文で使用する集約ユーザー定義関数 (UDF) を登録する
説明
public bool PDO::sqliteCreateAggregate(
string $function_name
,
callable $step_func
,
callable $finalize_func
,
int $num_args
= ?
)
警告この関数は、
実験的 なものです。この関数の動作・
名前・その他ドキュメントに書かれている事項は、予告なく、将来的な PHP
のリリースにおいて変更される可能性があります。
この関数は自己責任で使用してください。
このメソッドは
PDO::sqliteCreateFunction と似ていますが、
この関数で登録した関数は、クエリのすべての行の内容を集約する関数を登録します。
この関数と PDO::sqliteCreateFunction の最大の違いは、
集約関数を作成するためには 2 つの関数が必要であるということです。
パラメータ
-
function_name
-
SQL 文で使用する関数の名前。
-
step_func
-
結果セットの各行についてコールされるコールバック関数。
この PHP 関数は、結果を蓄積して集約コンテキストに保存しなければなりません。
この関数は次のように定義しなければなりません。
mixed step(
mixed $context
,
int $rownumber
,
mixed $value
,
mixed ...$values
)
-
context
-
最初の行では null
二行目以降では、ステップ関数から以前返された値を持ちます。
この値を、集約の状態を管理するのに使うべきです。
-
rownumber
-
現在の行番号
-
value
-
集約関数に渡されるはじめの引数
-
values
-
集約関数に渡されるふたつめ以降の引数
この関数の戻り値を、次のステップあるいはファイナライズ関数の
context
引数として使います。
-
finalize_func
-
すべての行が処理された後でコールされるコールバック関数。
ここでは、集約コンテキストからデータを取得して結果を返します。
コールバック関数の返す値は、SQLite が理解できる形式 (すなわち
スカラー型)
でなければなりません。
この関数は次のように定義しなければなりません。
mixed fini(mixed $context
, int $rowcount
)
-
context
-
ステップ関数を最後に呼んだ時の戻り値を保持します。
-
rowcount
-
集約関数が実行された行数を保持します。
この関数の戻り値が、集約の戻り値となります。
-
num_args
-
コールバック関数があらかじめ定義済みの引数を受け取る場合に、
SQLite のパーサに渡すヒント。
戻り値
成功した場合に true
を、失敗した場合に false
を返します。
例
例1 集約関数 max_length の例
<?php
$data = array(
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine',
'ten',
);
$db = new PDO('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, $rownumber, $string)
{
if (strlen($string) > $context) {
$context = strlen($string);
}
return $context;
}
function max_len_finalize($context, $rownumber)
{
return $context === null ? 0 : $context;
}
$db->sqliteCreateAggregate('max_len', 'max_len_step', 'max_len_finalize');
var_dump($db->query('SELECT max_len(a) from strings')->fetchAll());
?>
この例では、
テーブルのカラムの中で一番長い文字列の長さを計算する集約関数を作成します。
各行について max_len_step
関数がコールされ、
$context
パラメータが渡されます。
このパラメータには、他の PHP 変数と同様に、配列やオブジェクトが設定されます。
この例では、これまでに登場した値のうち長さが最大のものの長さを保持しています。
$string
が現在の最大値より長い場合に、
その値で現在の最大値を更新します。
すべての行に対する処理が終わると、SQLite は
max_len_finalize
関数をコールして集約結果を決定します。
ここでは、$context
の内容に基づいた、
なんらかの計算を行うことができます。
しかし、この例ではクエリを処理している過程で既に結果が決定しているので、
ここでは単に context の値を返しているだけです。
ヒント
結果の値を context に溜め込んでおき、最後に一括して処理するという方法は推奨
「しません」。これは、SQLite のメモリ消費量が大きくなるからです。
仮に 32 バイトの長さのデータが百万件あったとして、
それを溜め込むためにどれだけのメモリが必要になるか考えてみましょう。