У меня есть проект UWP
, который работает с базой данных Sqlite
. Я добавил sqlite-net-pcl
к моим ссылкам. Я хочу использовать REGEXP
в запросе select
, но он дает мне no such function: REGEXP
. Я искал ошибку, но результаты около SQLiteFunction
, которые здесь не определены. Что мне делать?Как использовать REGEXP в `sqlite-net-pcl` в UWP
ответ
В конце я установил sqlite-net-pcl
от nuget
не тот, в Universal windows extensions
в ReferenceManger.
sqlite-net-pcl
упаковка в nuget есть 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);
}
это работает отлично :)
Ссылка The LIKE, GLOB, REGEXP, and MATCH operators:
Оператор REGEXP это специальный синтаксис для функции пользователя регулярного выражения(). Пользовательская функция regexp() не определена по умолчанию, поэтому использование оператора REGEXP обычно приводит к сообщению об ошибке. Если во время выполнения добавляется application-defined SQL function с именем «regexp», то оператор «X REGEXP Y» будет реализован как вызов «regexp (Y, X)».
Таким образом, чтобы использовать REGEXP, мы должны иметь возможность создавать пользовательские функции. И SQLiteFunction - это класс, который легко обрабатывает пользовательские функции в System.Data.SQLite. Однако System.Data.SQLite является поставщиком ADO.NET для SQLite, который не может использоваться в приложениях UWP.
В SQLite-net PCL, такого метода нет. Тем не менее, SQLite-net PCL использует SQLitePCL.raw внизу, что является очень тонкой оболочкой C# вокруг C API для SQLite и обеспечивает низкоуровневый (необработанный) доступ к SQLite. С помощью SQLitePCL.raw мы можем создавать пользовательские функции, как в ответе @ Марьяма.
Если вы можете использовать что-то вроде SQLite 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()); }
}
}
}
Wow! Не заметил, что 'SQLite-net PCL' построен на' SQLitePCL.raw'. Метод 'sqlite3_create_function' фактически не является методом' SQLite-net PCL', а метод в 'SQLitePCL.raw'. Во всяком случае, отличное решение этой проблемы. ;) –