大多数数据库都有 SQL 的过程方言,可用于定义自己的函数。 SQLite 是在应用程序进程内运行的。 无需学习新的 SQL 方言,只需使用应用的编程语言即可。
标量函数
标量函数为查询中的每个行返回单个标量值。 定义新的标量函数,并使用 CreateFunction 覆盖内置函数。
指定 state
参数会将该值传递到函数的每个调用中。 使用此选项可避免关闭。
指定 isDeterministic
函数是否确定性,以允许 SQLite 在编译查询时使用其他优化。
以下示例演示如何添加标量函数以计算柱形的半径。
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
";
运营商
以下 SQLite 运算符由相应的标量函数实现。 在应用中定义这些标量函数将替代这些运算符的行为。
操作员 | 功能 |
---|---|
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) |
以下示例演示如何定义 regexp 函数以启用其相应的运算符。 SQLite 不包括 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();
聚合函数
聚合函数返回查询中所有行的单个聚合值。 使用 CreateAggregate.. 定义和替代聚合函数。
该 seed
参数指定上下文的初始状态。 使用它也可以避免闭包。
每个 func
行调用一次该参数。 使用上下文累积最终结果。 返回上下文。 此模式允许上下文为值类型或不可变。
resultSelector
如果未指定,则上下文的最终状态将用作结果。 这可以简化函数的定义,如总和计数,只需递增每个行的数字并返回它。
指定 resultSelector
以在遍历所有行后从上下文中计算出最终结果。
若要获取参数类型和func
返回类型支持的参数类型列表,请参阅resultSelector
。
如果函数是确定性的,请指定 isDeterministic
允许 SQLite 在编译查询时使用其他优化。
以下示例定义一个聚合函数来计算列的标准偏差。
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();
错误
如果用户定义函数引发异常,消息将返回到 SQLite。 然后,SQLite 将引发错误,Microsoft.Data.Sqlite 将引发 SqliteException。 有关详细信息,请参阅 数据库错误。
默认情况下,SQLite 错误代码将是 SQLITE_ERROR(或 1)。 但是,可以通过在函数中引发 SqliteException 并指定所需的 SqliteErrorCode 来更改它。
调试
SQLite 直接调用你的实现。 这使你可以添加在 SQLite 评估查询时触发的断点。 提供完整的 .NET 调试体验,可帮助你创建用户定义的函数。