Compartir a través de


Funciones definidas por el usuario

La mayoría de las bases de datos tienen un dialecto de procedimientos de SQL que puede usar para definir sus propias funciones. SQLite, en cambio, se ejecuta en el mismo proceso que la aplicación. En lugar de tener que aprender un nuevo dialecto de SQL, solo puede usar el lenguaje de programación de la aplicación.

Funciones escalares

Las funciones escalares devuelven un valor escalar único para cada fila de una consulta. Defina nuevas funciones escalares e invalide las integradas mediante CreateFunction.

Consulte Tipos de datos para obtener una lista de los tipos de parámetro y valor devuelto admitidos para el func argumento.

Al especificar el argumento state, ese valor se pasará a todas las invocaciones de la función. Úselo para evitar cierres.

Especifique isDeterministic si la función es determinista para permitir que SQLite use optimizaciones adicionales al compilar consultas.

En el ejemplo siguiente se muestra cómo agregar una función escalar para calcular el radio de un cilindro.

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

Operadores

Los siguientes operadores de SQLite se implementan mediante las funciones escalares correspondientes. La definición de estas funciones escalares en la aplicación invalidará el comportamiento de estos operadores.

Operador Función
X GLOB Y glob(Y, X)
X LIKE Y like(Y, X)
X LIKE Y ESCAPE Z like(Y, X, Z)
X MATCH Y match(Y, X)
X REGEXP Y regexp(Y, X)

En el ejemplo siguiente se muestra cómo definir la función regexp para habilitar su operador correspondiente. SQLite no incluye una implementación predeterminada de la función 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();

Funciones agregadas

Las funciones de agregado devuelven un valor agregado único para todas las filas de una consulta. Defina e invalide las funciones de agregado mediante CreateAggregate.

El seed argumento especifica el estado inicial del contexto. Úselo para evitar también cierres.

El func argumento se invoca una vez por fila. Use el contexto para acumular un resultado final. Devuelve el contexto. Este patrón permite que el contexto sea un tipo de valor o inmutable.

Si no se especifica resultSelector, el estado final del contexto se usa como resultado. Esto puede simplificar la definición de funciones como suma y recuento que solo necesitan incrementar un número cada fila y devolverla.

Especifique resultSelector para calcular el resultado final del contexto después de recorrer en iteración todas las filas.

Consulte Tipos de datos para obtener una lista de los tipos de parámetro admitidos para el func argumento y los tipos de valor devuelto para resultSelector.

Si la función es determinista, especifique isDeterministic para permitir que SQLite use optimizaciones adicionales al compilar consultas.

En el ejemplo siguiente se define una función de agregado para calcular la desviación estándar de una columna.

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

Errores

Si una función definida por el usuario produce una excepción, el mensaje se devuelve a SQLite. SQLite generará un error y Microsoft.Data.Sqlite producirá una excepción SqliteException. Para obtener más información, consulte Errores de base de datos.

De forma predeterminada, el código de error de SQLite será SQLITE_ERROR (o 1). pero se puede cambiar produciendo una excepción SqliteException en la función con el elemento SqliteErrorCode deseado especificado.

Depuración de errores

SQLite llama directamente a su implementación, Esto le permite agregar puntos de interrupción que se desencadenan mientras SQLite está evaluando las consultas. Está disponible toda la experiencia de depuración de .NET para ayudarle a crear sus funciones definidas por el usuario.

Consulte también