【发布时间】:2015-08-04 23:40:11
【问题描述】:
我正在尝试在我现有的 SQLite 数据库中使用 FTS,因此我将 external source 用于虚拟表 - 但我得到了一个 FTS3 表的令人困惑的结果,我将结束必须使用if I plan on supporting < 11 Android API
在我的 DB Contract 类的这个静态函数中,我为 SQL 创建初始化字符串以创建我的虚拟表。
数据库合同:
public static String getVirtualCreate(){
if (VIRTUAL_TABLE_NAME == "")
return "";
String createstring = "CREATE VIRTUAL TABLE IF NOT EXISTS " + VIRTUAL_TABLE_NAME + " USING fts4(content=\"" + TABLE_NAME +"\",";
for (int a = 0; a < virtualCount(); a++){
createstring += getVirtualColumn(a).getName();
if (a < count() - 1){
createstring += ",";
}
}
createstring += ")";
return createstring;
}
以及创建触发器的这段代码
public static String getVirtualCreateTriggers(){
String rowstring = "";
String postrowstring = "";
for(int a = 0; a < virtualCount(); a++){
rowstring += getVirtualColumn(a);
postrowstring += "new." + getVirtualColumn(a);
if (a < virtualCount() - 1){
rowstring += ",";
postrowstring += ",";
}
}
String ret =
"CREATE TRIGGER IF NOT EXISTS TABLE_NAME_bu BEFORE UPDATE ON TABLE_NAME BEGIN\n" +
" DELETE FROM VIRTUAL_TABLE_NAME WHERE docid=old."+COLUMN_NAME_ID+";\n" +
"END;\n" +
"CREATE TRIGGER TABLE_NAME_bd BEFORE DELETE ON TABLE_NAME BEGIN\n" +
" DELETE FROM VIRTUAL_TABLE_NAME WHERE docid=old."+COLUMN_NAME_ID+";\n" +
"END;\n" +
"CREATE TRIGGER TABLE_NAME_au AFTER UPDATE ON TABLE_NAME BEGIN\n" +
" INSERT INTO VIRTUAL_TABLE_NAME(docid,"+rowstring+") VALUES("+postrowstring+");\n" +
"END;\n" +
"CREATE TRIGGER TABLE_NAME_ai AFTER INSERT ON TABLE_NAME BEGIN\n" +
" INSERT INTO VIRTUAL_TABLE_NAME(docid, "+rowstring+") VALUES("+postrowstring+");\n" +
"END;";
return ret;
}
数据库助手:
DBContract 创建字符串似乎在实现中运行良好。如果我打电话给:
Cursor mCursor = db.rawQuery("SELECT * FROM " + DbContract.PartEntry.VIRTUAL_TABLE_NAME ,null);
它将返回原始表的所有值。
但是,如果我调用完全相同的代码,但将 CreateString 更改为 FTS3
String createstring = "CREATE VIRTUAL TABLE IF NOT EXISTS " + VIRTUAL_TABLE_NAME + " USING fts3(content=\"" + TABLE_NAME +"\",";
即使在虚拟表更改后添加了额外的行 SELECT * 返回 0 行。
改回来后一切正常。
其次,如果我使用像 Cursor mCursor = db.rawQuery("SELECT * FROM " + DbContract.PartEntry.VIRTUAL_TABLE_NAME + " WHERE " + DbContract.PartEntry.VIRTUAL_TABLE_NAME + " match '" + search + "'",null); 这样的函数,可能是相关的
search 是一个(暂时未转义)字符串,它在原始 AND 虚拟表中最明确地找到(通过 select * 验证)它为 FTS4 返回 0 行,目前在 FTS3 中无法测试,因为前面提到的问题,没有出现数据。
问题:
我是否在表定义中做错了什么?或者也许还有其他可能导致 FTS3 中的通配符搜索不返回任何结果,似乎没有抛出任何错误消息?不幸的是,这是我第一次接触香草 SQL 之外的任何东西,所以我很可能在某处做错了什么。
如果我没有足够的代码或足够好的示例,是否可以添加更好的示例或更相关的代码来帮助更好地了解情况?
【问题讨论】:
-
修复了一个问题,以便在 FTS4 表上使用
match我需要重建索引INSERT INTO vtable(vtable) VALUES('rebuild'); -
Shoot... 又仔细看了一遍手册,看起来外部内容是 FTS4 独有的选项之一... 问题 #2 已解决。
标签: android sqlite full-text-search