Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Większość baz danych ma proceduralny dialekt SQL, którego można użyć do zdefiniowania własnych funkcji. SQLite działa jednak wewnątrz procesu twojej aplikacji. Zamiast uczyć się nowego dialektu JĘZYKA SQL, możesz po prostu użyć języka programowania aplikacji.
Funkcje skalarne
Funkcje skalarne zwracają pojedynczą, skalarną wartość dla każdego wiersza w zapytaniu. Zdefiniuj nowe funkcje skalarne i zastąpij wbudowane przy użyciu polecenia CreateFunction.
Zobacz Typy danych , aby uzyskać listę obsługiwanych typów parametrów i zwracanych dla argumentu func .
Określenie argumentu state spowoduje przekazanie tej wartości do każdego wywołania funkcji. Użyj tego, aby uniknąć zamknięć.
Określ isDeterministic , czy funkcja jest deterministyczna, aby umożliwić sqlite używanie dodatkowych optymalizacji podczas kompilowania zapytań.
W poniższym przykładzie pokazano, jak dodać funkcję skalarną w celu obliczenia promienia cylindra.
connection.CreateFunction(
"volume",
(double radius, double height)
=> Math.PI * Math.Pow(radius, 2) * height);
var command = connection.CreateCommand();
command.CommandText =
@"
SELECT name,
volume(radius, height) AS volume
FROM cylinder
ORDER BY volume DESC
";
Operatorów
Następujące operatory SQLite są implementowane przez odpowiednie funkcje skalarne. Zdefiniowanie tych funkcji skalarnych w aplikacji spowoduje zastąpienie zachowania tych operatorów.
| Obsługujący | Funkcja |
|---|---|
| X GLOB Y | glob(Y, X) |
| X JAK Y | like(Y, X) |
| X LIKE Y ESCAPE Z | like(Y, X, Z) |
| X DOPASOWANIE Y | match(Y, X) |
| X REGEXP Y | regexp(Y, X) |
W poniższym przykładzie pokazano, jak zdefiniować funkcję regexp w celu włączenia odpowiedniego operatora. SqLite nie zawiera domyślnej implementacji funkcji regexp.
connection.CreateFunction(
"regexp",
(string pattern, string input)
=> Regex.IsMatch(input, pattern));
var command = connection.CreateCommand();
command.CommandText =
@"
SELECT count()
FROM user
WHERE bio REGEXP '\w\. {2,}\w'
";
var count = command.ExecuteScalar();
Funkcje agregujące
Funkcje agregujące zwracają pojedynczą zagregowaną wartość dla wszystkich wierszy w zapytaniu. Zdefiniuj i zastąpij funkcje agregujące przy użyciu polecenia CreateAggregate.
Argument seed określa początkowy stan kontekstu. Użyj tego również, aby uniknąć domknięć.
Argument func jest wywoływany raz w każdym wierszu. Użyj kontekstu, aby zebrać końcowy wynik. Zwróć kontekst. Ten wzorzec pozwala kontekstowi być typem wartości lub niezmiennym.
Jeśli resultSelector nie zostanie określony, jako wynik zostanie użyty stan końcowy kontekstu. Może to uprościć definicję funkcji, takich jak suma i liczba, które muszą tylko zwiększać liczbę poszczególnych wierszy i zwracać je.
Określ resultSelector , aby obliczyć wynik końcowy z kontekstu po iterowaniu przez wszystkie wiersze.
Zobacz Typy danych , aby uzyskać listę obsługiwanych typów parametrów dla argumentu func i zwracanych typów dla elementu resultSelector.
Jeśli funkcja jest deterministyczna, określ isDeterministic , aby umożliwić sqlite używanie dodatkowych optymalizacji podczas kompilowania zapytań.
W poniższym przykładzie zdefiniowano funkcję agregacji w celu obliczenia odchylenia standardowego kolumny.
connection.CreateAggregate(
"stdev",
// A tuple to maintain context between rows
(Count: 0, Sum: 0.0, SumOfSquares: 0.0),
// This is called for each row
((int Count, double Sum, double SumOfSquares) context, double value) =>
{
context.Count++;
context.Sum += value;
context.SumOfSquares += value * value;
return context;
},
// This is called to get the final result
context =>
{
var variance = context.SumOfSquares - context.Sum * context.Sum / context.Count;
return Math.Sqrt(variance / context.Count);
});
var command = connection.CreateCommand();
command.CommandText =
@"
SELECT stdev(gpa)
FROM student
";
var stdDev = command.ExecuteScalar();
Błędy
Jeśli funkcja zdefiniowana przez użytkownika zgłasza wyjątek, komunikat zostanie zwrócony do sqlite. Narzędzie SQLite zgłosi błąd, a obiekt Microsoft.Data.Sqlite zgłosi wyjątek SqliteException. Aby uzyskać więcej informacji, zobacz Błędy bazy danych.
Domyślnie kod błędu SQLite będzie SQLITE_ERROR (lub 1). Można to jednak zmienić, rzucając SqliteException w funkcji, określając żądany SqliteErrorCode.
Debugowanie
SQLite wywołuje Twoją implementację bezpośrednio. Dzięki temu można dodawać punkty przerwania wyzwalane podczas przetwarzania zapytań przez SQLite. Pełne środowisko debugowania platformy .NET jest dostępne, aby ułatwić tworzenie funkcji zdefiniowanych przez użytkownika.