【发布时间】:2017-03-10 07:09:51
【问题描述】:
我有一个与Sqlite 数据库一起使用的UWP 项目。我在参考资料中添加了sqlite-net-pcl。
我想在select 查询中使用REGEXP,但它给了我no such function: REGEXP。
我搜索了错误,但结果与此处未定义的 SQLiteFunction 有关。
我该怎么办?
【问题讨论】:
标签: c# sqlite uwp sqlite-net
我有一个与Sqlite 数据库一起使用的UWP 项目。我在参考资料中添加了sqlite-net-pcl。
我想在select 查询中使用REGEXP,但它给了我no such function: REGEXP。
我搜索了错误,但结果与此处未定义的 SQLiteFunction 有关。
我该怎么办?
【问题讨论】:
标签: c# sqlite uwp sqlite-net
最后,我从nuget 安装了sqlite-net-pcl,而不是ReferenceManger 中Universal windows extensions 中的那个。
nuget 中的sqlite-net-pcl 包具有sqlite3_create_function 方法。
SQLiteConnection con = new SQLiteConnection(@"myDB.db");
SQLitePCL.raw.sqlite3_create_function(con.Handle, "REGEXP", 2, null, MatchRegex);
private void MatchRegex(sqlite3_context ctx, object user_data, sqlite3_value[] args)
{
bool isMatched = System.Text.RegularExpressions.Regex.IsMatch(SQLitePCL.raw.sqlite3_value_text(args[1]), SQLitePCL.raw.sqlite3_value_text(args[0]),RegexOptions.IgnoreCase);
if (isMatched)
SQLitePCL.raw.sqlite3_result_int(ctx, 1);
else
SQLitePCL.raw.sqlite3_result_int(ctx, 0);
}
这很好用:)
【讨论】:
SQLite-net PCL 是建立在SQLitePCL.raw 之上的。 sqlite3_create_function 方法实际上不是SQLite-net PCL 的方法,而是SQLitePCL.raw 中的方法。无论如何,这个问题的一个很好的解决方案。 ;)
utf8_to_string(),如SQLitePCL.raw.sqlite3_value_text( args[ 0 ] ).utf8_to_string()
参考The LIKE, GLOB, REGEXP, and MATCH operators:
REGEXP 运算符是 regexp() 用户函数的特殊语法。默认情况下没有定义 regexp() 用户函数,因此使用 REGEXP 运算符通常会导致错误消息。如果在运行时添加了名为“regexp”的application-defined SQL function,则“X REGEXP Y”运算符将被实现为对“regexp(Y,X)”的调用。
所以要使用 REGEXP,我们需要能够创建用户定义的函数。而SQLiteFunction 是设计用于在System.Data.SQLite 中轻松处理用户定义函数的类。但是 System.Data.SQLite 是 SQLite 的 ADO.NET 提供程序,不能在 UWP 应用中使用。
在SQLite-net PCL,没有这样的方法。但是,SQLite-net PCL 在下面使用SQLitePCL.raw,这是一个非常薄的 C# 包装器,用于 SQLite 的 C API,并提供对 SQLite 的低级(原始)访问。使用 SQLitePCL.raw,我们可以创建用户定义的函数,就像@Maryam 的回答一样。
【讨论】:
如果您可以使用 SQLite PCL Pretty 之类的东西,您可以执行以下操作(可能与其他 PCL 一起使用,但不确定):
using System;
using SQLitePCL.pretty;
using System.Text.RegularExpressions;
namespace TestSqlite
{
class Program
{
static void Main(string[] args)
{
Func<ISQLiteValue, ISQLiteValue, ISQLiteValue> regexFunc =
(ISQLiteValue val, ISQLiteValue regexStr) =>
{
if (Regex.IsMatch(Convert.ToString(val), Convert.ToString(regexStr)))
return true.ToSQLiteValue();
return false.ToSQLiteValue();
};
SQLitePCL.Batteries.Init();
SQLiteDatabaseConnection _dbcon = SQLiteDatabaseConnectionBuilder
.InMemory
.WithScalarFunc("REGEXP", regexFunc)
.Build();
string sql = "CREATE TABLE foo (a int, b text);";
_dbcon.ExecuteAll(sql);
_dbcon.ExecuteAll(@"INSERT INTO foo VALUES (1, 'this is me');
INSERT INTO foo VALUES (2, 'that is me');
INSERT INTO foo VALUES (3, 'he is me');");
sql = "SELECT * FROM foo where '\\w{4} is me' REGEXP b;";
foreach (var row in _dbcon.Query(sql)) { Console.WriteLine(row[1].ToString()); }
}
}
}
【讨论】: