我试图在我现有的SQLite数据库中使用SQLite,所以我对虚拟表使用了外部源,但是对于FTS3表我得到了令人困惑的结果,而最终我不得不使用if I plan on supporting < 11 Android API
在我的DB契约类中的这个静态函数中,我为SQL创建初始化字符串以创建我的虚拟表。
Db合同:
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;
}DB助手:
在实现中,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是一个字符串(暂时是未转义的),它肯定是在原始表和虚拟表中找到的(由select *验证),它返回FTS4的0行,目前在FTS3中是不可测试的,因为前面提到的问题没有数据出现。
问题:
我在表定义中做错了什么吗?或者,是否还有其他原因导致FTS3中的通配符搜索没有返回任何结果,似乎没有抛出任何错误消息?不幸的是,这是我在使用普通SQL之外的第一次体验,所以我很可能在某个地方做错了什么。
如果我没有足够的代码,或者一个足够好的例子,我是否可以添加更好的示例或更相关的代码来帮助更好地理解情况?
发布于 2015-05-22 22:40:06
我不喜欢回答我自己的问题。然而,经过相当多的困惑之后,我发现了我的两个问题的答案。
FTS4 match请求返回0行的原因是它没有被索引。
解决办法:
INSERT INTO vtable(vtable) VALUES('rebuild');将表定义从FTS4更改为FTS3的原因是使用外部内容的选项(至少据我所知)是FTS4独占选项。意味着它在FTS3上是不可用的。
我的解决方案是构建两个版本的虚拟表,一个用于使用FTS3的pre 11,而不是外部源,另一个版本使用允许我们使用外部源的FTS4。
https://stackoverflow.com/questions/30405334
复制相似问题