Delen via


Door de gebruiker gedefinieerde functies

De meeste databases hebben een procedureel dialect van SQL dat u kunt gebruiken om uw eigen functies te definiëren. SQLite wordt echter in verwerking uitgevoerd met uw app. In plaats van een nieuw dialect van SQL te leren, kunt u gewoon de programmeertaal van uw app gebruiken.

Scalaire functies

Scalaire functies retourneren één scalaire waarde voor elke rij in een query. Definieer nieuwe scalaire functies en overschrijf de ingebouwde functies met behulp van CreateFunction.

Zie Gegevenstypen voor een lijst met ondersteunde parameters en retourtypen voor het func argument.

Als u het state argument opgeeft, wordt deze waarde doorgegeven aan elke aanroep van de functie. Gebruik dit om sluitingen te voorkomen.

Geef op isDeterministic of uw functie deterministisch is, zodat SQLite aanvullende optimalisaties kan gebruiken bij het compileren van query's.

In het volgende voorbeeld ziet u hoe u een scalaire functie toevoegt om de radius van een cilinder te berekenen.

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
";

Operators

De volgende SQLite-operators worden geïmplementeerd door bijbehorende scalaire functies. Als u deze scalaire functies in uw app definieert, wordt het gedrag van deze operators overschreven.

Operator Functie
X GLOB Y glob(Y, X)
X LIKE Y like(Y, X)
X LIKE Y ESCAPE Z like(Y, X, Z)
X VERGELIJKEN Y match(Y, X)
X REGEXP Y regexp(Y, X)

In het volgende voorbeeld ziet u hoe u de functie regexp definieert om de bijbehorende operator in te schakelen. SQLite bevat geen standaardimplementatie van de functie 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();

Statistische functies

Statistische functies retourneren één geaggregeerde waarde voor alle rijen in een query. Statistische functies definiëren en negeren met behulp van CreateAggregate.

Het seed argument geeft de initiële status van de context aan. Gebruik dit om ook sluitingen te voorkomen.

Het func argument wordt eenmaal per rij aangeroepen. Gebruik de context om een eindresultaat te verzamelen. Retourneer de context. Met dit patroon kan de context een waardetype of onveranderbaar zijn.

Als er geen resultSelector is opgegeven, wordt de uiteindelijke status van de context gebruikt als resultaat. Dit vereenvoudigt de definitie van functies, zoals som en aantal, die slechts een getal per rij hoeven te verhogen en te retourneren.

Geef resultSelector op om het uiteindelijke resultaat van de context te berekenen nadat alle rijen zijn herhaald.

Zie Gegevenstypen voor een lijst met ondersteunde parametertypen voor het func argument en retourtypen voor resultSelector.

Als uw functie deterministisch is, geeft u isDeterministic op dat SQLite aanvullende optimalisaties kan gebruiken bij het compileren van query's.

In het volgende voorbeeld wordt een statistische functie gedefinieerd om de standaarddeviatie van een kolom te berekenen.

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();

Fouten

Als een door de gebruiker gedefinieerde functie een uitzondering genereert, wordt het bericht geretourneerd naar SQLite. SQLite genereert vervolgens een fout en Microsoft.Data.Sqlite genereert een SqliteException. Zie Databasefouten voor meer informatie.

De fout SQLite-foutcode wordt standaard SQLITE_ERROR (of 1). U kunt deze echter wijzigen door een SqliteException in uw functie te gooien met de gewenste SqliteErrorCode opgegeven functie.

Foutopsporing

SQLite roept uw implementatie rechtstreeks aan. Hiermee kunt u onderbrekingspunten toevoegen die worden geactiveerd terwijl SQLite query's evalueert. De volledige .NET-foutopsporingservaring is beschikbaar om u te helpen bij het maken van door de gebruiker gedefinieerde functies.

Zie ook