PHP Conference Japan 2024

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
為結果集的每一列呼叫的回呼函式。回呼應累計結果並將其儲存在彙總內容中。

此函式需要定義為

step(
    mixed $context,
    int $rownumber,
    mixed $value,
    mixed ...$values
): mixed
context
第一列為 null;在後續列中,它將具有先前從 step 函式傳回的值;您應該使用它來維護彙總狀態。
rownumber
目前的列號。
value
傳遞給彙總的第一個引數。
values
傳遞給彙總的其他引數。
此函式的傳回值將用作下一次呼叫 step 或 finalize 函式中的 context 引數。

finalize
從每一列彙總「逐步」資料的回呼函式。處理完所有列後,將會呼叫此函式,然後它應從彙總內容中取得資料並傳回結果。此回呼函式應傳回 SQLite 可理解的類型(即純量類型)。

此函式需要定義為

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

保存最後一次呼叫 step 函式的傳回值。

rowcount

保存執行彙總的列數。

此函式的傳回值將用作彙總的傳回值。

numArgs
如果回呼函式接受預定數量的引數,則會提示 SQLite 解析器。

傳回值

成功時傳回 true,失敗時傳回 false

範例

範例 1 Pdo\Sqlite::createAggregate() 範例

在此範例中,我們將建立一個名為 max_length 的自訂彙總函式,可用於 SQL 查詢中。

在此範例中,我們正在建立一個名為 max_length 的彙總函式,它將計算資料表其中一欄中最長字串的長度。對於每一列,都會呼叫 max_len_step 函式,並傳遞 $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 位元組的字串,您將需要多少記憶體。

另請參閱

新增筆記

使用者貢獻的筆記

此頁面尚無使用者貢獻的筆記。
To Top