sqlite_create_aggregate
SQLiteDatabase::createAggregate
Registriert eine benutzerdefinierte Funktion, um SQL-Abfragen zu aggregieren
Beschreibung
void sqlite_create_aggregate
( resource $dbhandle
, string $function_name
, callable $step_func
, callable $finalize_func
[,
int
$num_args
= -1
] )
public void SQLiteDatabase::createAggregate
( string $function_name
, callable $step_func
, callable $finalize_func
[,
int
$num_args
= -1
] )
Der größte Unterschied in dieser Funktion und
sqlite_create_function liegt darin, das man zwei
Funktionen registrieren muss, um zu aggregieren;
step_func wird für jede Zeile des Abfrageergebnisses
aufgerufen. Ihre PHP-Funktion (function_name)
sollte das Ergebnis akkumulieren und dieses im Aggregatkontext speichern.
Sobald alle Zeilen verarbeitet wurden, wird
finalize_func aufgerufen. Diese Funktion sollte die
Daten aus dem Aggregatkontext nehmen und als Ergebnis zurückgeben.
Callback-Funktionen sollten einen Typ liefern, der von SQLite verstanden wird
(z.B. Skalartypen).
Parameter-Liste
-
dbhandle
-
Die Ressource der SQLite-Datenbank, die bei prozeduraler Benutzung von
sqlite_open zurückgegeben wurden. Der Parameter
wird bei der objektorientierten Methode nicht benötigt.
-
function_name
-
Der Name der Funktion, der in SQL-Abfragen benutzt wird.
-
step_func
-
Callback-Funktion mit der jede Zeile des Abfrageergebnisses aufgerufen
wird. Die Funktions-Parameter sind &$context, $value, ....
-
finalize_func
-
Callback-Funktion, die die durchlaufenen Daten aggregiert.
Der Funktions-Parameter ist &$context und die Funktion
sollte das finale Ergebnis der Aggregation zurückliefern.
-
num_args
-
Hinweis für den SQLite-Parser, ob die Callback-Funktion eine
vordefinierte Anzahl von Argumenten annimmt.
Rückgabewerte
Es wird kein Wert zurückgegeben.
Beispiele
Beispiel #1 aggregierte max_length-Funktion
<?php
$data = array(
'eins',
'zwei',
'drei',
'vier',
'fuenf',
'sechs',
'sieben',
'acht',
'neun',
'zehn',
);
$dbhandle = sqlite_open(':memory:');
sqlite_query($dbhandle, "CREATE TABLE strings(a)");
foreach ($data as $str) {
$str = sqlite_escape_string($str);
sqlite_query($dbhandle, "INSERT INTO strings VALUES ('$str')");
}
function max_len_step(&$context, $string)
{
if (strlen($string) > $context) {
$context = strlen($string);
}
}
function max_len_finalize(&$context)
{
return $context;
}
sqlite_create_aggregate($dbhandle, 'max_len', 'max_len_step', 'max_len_finalize');
var_dump(sqlite_array_query($dbhandle, 'SELECT max_len(a) from strings'));
?>
In diesem Beispiel haben wir eine Aggregatfunktion erstellt, die die Länge
des längsten Strings einer Tabellenspalte berechnet. Jede Zeile wird mit
der Funktion max_len_step mit dem Parameter
context aufgerufen. Der Parameter context ist wie jede
andere PHP-Variable und sollte ein Array oder auch ein Objekt speichern
können. In diesem Beispiel benutzen wird ihn lediglich dazu, die bisherige
maximale Länge zu speichern; sollte string größer
sein, als das aktuelle Maximum, aktuallisieren wir den Wert mit der neuen
maximalen Länge.
Wenn alle Zeilen durchlaufen sind, ruft SQLite die Funktion
max_len_finalize auf, um das aggregierte Ergebnis
auszuwerten. Hier könnten wir einige Berechnungen anstellen, basierend auf
den Daten, die in context stehen. In unserem einfachen
Beispiel haben wir das Ergebnis bereits während der Abfrage berechnet, sodass
wir einfach nur den Wert in context zurückgeben können.
Hinweis:
Das oben aufgeführte Beispiel funktioniert nicht akkurat, wenn die Spalte
Binärdaten enthalten würde. Eine Erklärung dafür liefert die Dokumentation
unter sqlite_udf_decode_binary, genauso wie ein
Beispiel dafür, wie man die Binärkodierung berücksichtigt.
Tipp
Es wird NICHT empfohlen eine Kopie der Werte in context zu speichern und
diese erst am Schluss zu verarbeiten. Dadurch würde SQLite viel Speicher
verbrauchen, um die Abfrage zu bearbeiten. Man muß sich nur vorstellen,
wieviel Speicher man brauchen würde, um eine Million Zeilen, jede mit
einer Länge von 32 Byte, im Speicher zu halten.
Tipp
Man kann sqlite_create_function und
sqlite_create_aggregate nutzen, um native
SQL-Funktionen im SQLite zu überschreiben.
Siehe auch
- sqlite_create_function
- sqlite_udf_encode_binary
- sqlite_udf_decode_binary