Android SQLite SELECT WHERE LIKE 意外行为

发布于 2024-12-11 05:22:54 字数 1577 浏览 0 评论 0原文

我有一个带有 SQLite 数据库的 Android 应用程序,我正在尝试实现一个搜索界面。首先,我意识到制作 FTS 数据库是可行的方法,但我认为如果使用通配符,我可以使用 LIKE 语句并获得类似的结果。这样就可以测试接口并稍后更新后端。

以下是我构建查询的方法:

public Cursor getMatching(String query) {
    Cursor mCursor = db.query(false, TABLE, new String[] { KEY_ROWID,
            KEY_NAME }, KEY_NAME + " LIKE ?",
            new String[] { "%" + query + "%" }, null, null, null, null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;
}

KEY_NAME 是我想要其结果的文本列,query 是我想要匹配的小写字符串。我希望它会返回查询出现在名称中任何位置的结果,不区分大小写。然而,我观察到的情况有所不同。查询“”(空字符串)的结果:

Coch**** ****
Squi*** St*****
Owe** ****
Smi** Ca****
G. Bur** Jo******
Gr******* Brown

现在,当我查询“o”时:

Owe** ****
G. Bur** Jo******
Gr******* Brown

奇怪的是,第一个结果被过滤掉了,尽管它包含一个“o”。当我查询“ow”时:

Gr******* Brown

最后当我用“own”查询时:

null

这是我用来处理游标的方法:

public static void logMatches(Context context, String query) {
    DBAdapter adapter = new DBAdapter(context);
    adapter.open();

    Cursor c = adapter.getMatching(query);

    if (c == null)
        return;

    while (c.moveToNext()) {
        String name = c.getString(c
                .getColumnIndex(DBAdapter.KEY_NAME));
        Log.d(TAG, name);
    }

    c.close();
    adapter.close();
}

其中 DBAdapter 包含 SQLiteOpenHelper。我传入的上下文来自使用 getContext() 方法的 ContentProvider。

我最终想实现一个 FTS 表,但我的数据库现在很小,所以我希望现在可以使用现有表实现类似的功能。是否可以使用 LIKE 子句做我想做的事情?我犯了一个明显的错误吗?

I have an android application with a SQLite database and I am trying to implement a search interface. First of all, I realize that making a FTS database is the way to go, but I thought that I could use a LIKE statement and get similar results if I use wildcards. That way the interface can be tested and the backend updated later.

Here is how I build the query:

public Cursor getMatching(String query) {
    Cursor mCursor = db.query(false, TABLE, new String[] { KEY_ROWID,
            KEY_NAME }, KEY_NAME + " LIKE ?",
            new String[] { "%" + query + "%" }, null, null, null, null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;
}

KEY_NAME is the text column that I want results for, and query is the lowercase string that I want to match against. I would expect that it would return results where the query appears anywhere in the name, case insensitive. However, what I observe is different. The results of querying "" (empty string):

Coch**** ****
Squi*** St*****
Owe** ****
Smi** Ca****
G. Bur** Jo******
Gr******* Brown

Now when I query "o":

Owe** ****
G. Bur** Jo******
Gr******* Brown

Oddly enough, the first result is filtered out, although it contains an 'o'. When I query "ow":

Gr******* Brown

And finally when I query with "own":

null

Here is the method I use to handle the cursor:

public static void logMatches(Context context, String query) {
    DBAdapter adapter = new DBAdapter(context);
    adapter.open();

    Cursor c = adapter.getMatching(query);

    if (c == null)
        return;

    while (c.moveToNext()) {
        String name = c.getString(c
                .getColumnIndex(DBAdapter.KEY_NAME));
        Log.d(TAG, name);
    }

    c.close();
    adapter.close();
}

Where DBAdapter contains the SQLiteOpenHelper. The context I am passing in comes from a ContentProvider by using the getContext() method.

I want to implement a FTS table eventually, but my database is quite small now so I hoped that I could implement similar functionality using existing tables for now. Is it possible to do what I want with the LIKE clause? Am I making an obvious mistake?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

错爱 2024-12-18 05:22:54

我自己没有尝试过,但 fts 实际上是在 Android 的 SQLite 中实现的。例如,请参阅此处此处

啊,是的。将 while (c.moveToNext()) {} 改为 do { } while (c.moveToNext())

I did not tried it myself but fts actually implemented in SQLite for android. See for example here and here.

Ah, yes. Instead of while (c.moveToNext()) {} put do { } while (c.moveToNext())

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文