(PHP 5 >= 5.1.0, PHP 7, PHP 8, PECL pdo_sqlite >= 1.0.0)
PDO::sqliteCreateAggregate — 注册一个聚合的用户定义函数,用于 SQL 语句
$function_name
,$step_func
,$finalize_func
,$num_args
= ?此函数为实验性。此函数的行为、名称和周围的文档可能在 PHP 的未来版本中发生变化,恕不另行通知。使用此函数需自行承担风险。
此方法类似于 PDO::sqliteCreateFunction,除了它注册可以用于计算跨查询所有行的结果的聚合函数。
此方法和 PDO::sqliteCreateFunction 之间的关键区别在于,需要两个函数来管理聚合。
function_name
SQL 语句中使用的函数名称。
step_func
对结果集的每一行调用的回调函数。您的 PHP 函数应累积结果并将其存储在聚合上下文中。
此函数需要定义为
context
对于第一行,为null
;在后续行中,它将具有之前从 step 函数返回的值;您应该使用它来维护聚合状态。
rownumber
当前行号。
value
传递给聚合的第一个参数。
values
传递给聚合的更多参数。
context
参数。
finalize_func
回调函数,用于聚合来自每一行的“分步”数据。处理完所有行后,将调用此函数,它应该从聚合上下文中获取数据并返回结果。此回调函数应返回 SQLite 能够理解的类型(即 标量类型)。
此函数需要定义为
context
保存 step 函数最后一次调用的返回值。
rowcount
保存执行聚合的行数。
num_args
如果回调函数接受预定数量的参数,则向 SQLite 解析器提供提示。
示例 #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, $rowcount)
{
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
中找到的数据执行某种计算。不过,在我们简单的示例中,我们一直在查询过程中计算结果,因此我们只需返回上下文值。
不建议您在上下文中存储值的副本,然后在最后处理它们,因为这会导致 SQLite 使用大量内存来处理查询 - 只要想想如果一百万行存储在内存中,每一行包含 32 字节长的字符串,您需要多少内存。
您可以使用 PDO::sqliteCreateFunction 和 PDO::sqliteCreateAggregate 覆盖 SQLite 本地 SQL 函数。