【问题标题】:How to use REGEXP in `sqlite-net-pcl` in UWP如何在 UWP 的“sqlite-net-pcl”中使用 REGEXP
【发布时间】:2017-03-10 07:09:51
【问题描述】:

我有一个与Sqlite 数据库一起使用的UWP 项目。我在参考资料中添加了sqlite-net-pcl。 我想在select 查询中使用REGEXP,但它给了我no such function: REGEXP。 我搜索了错误,但结果与此处未定义的 SQLiteFunction 有关。 我该怎么办?

【问题讨论】:

    标签: c# sqlite uwp sqlite-net


    【解决方案1】:

    最后,我从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()
    【解决方案2】:

    参考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 的回答一样。

    【讨论】:

    【解决方案3】:

    如果您可以使用 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()); }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-11
      • 1970-01-01
      • 2015-12-21
      • 1970-01-01
      • 1970-01-01
      • 2017-08-22
      • 2015-12-20
      • 2023-03-19
      相关资源
      最近更新 更多