使用sqlite创建虚拟表使用fts3与唯一列不保持唯一

时间:2012-03-26 22:13:35

标签: qt sqlite

即时创建(在Qt中)

QString q = "CREATE VIRTUAL TABLE playlist USING fts3 ("
                        "from_user , " 
                        "from_id , "
                        "created_time , "
                        "created_time_formated , "
                        "user_id unique )";

然后执行

"INSERT OR IGNORE INTO  play_list (from_user,from_id,created_time,created_time_formated,user_id) SELECT '....','....','.....','....','123'"  

我正在使用完整的全文搜索,所以这是使用VIRTUAL TABLE

的方式

如果我有另一行user_id == 123它仍会插入行,为什么?

1 个答案:

答案 0 :(得分:3)

FTS文件states

  

这同样适用于与FTS列名一起指定的任何约束 - 它们被解析但不被系统以任何方式使用或记录。

因此忽略UNIQUE约束。

您可以通过在视图上使用触发器来模拟约束(不在表上,因为触发器在虚拟表上不可用),然后在该视图上插入行:

CREATE VIEW playlist_view AS SELECT * FROM playlist;

CREATE TRIGGER insert_playlist INSTEAD OF INSERT ON playlist_view
BEGIN
    SELECT RAISE(ABORT, 'column user_id is not unique') FROM playlist 
        WHERE user_id=new.user_id;
    INSERT INTO playlist (from_user, from_id, created_time, 
                          created_time_formated, user_id) 
    VALUES (NEW.from_user, NEW.from_id, NEW.created_time, 
            NEW.created_time_formated, NEW.user_id);
END;

-- And you do the insertion on the view 
INSERT INTO playlist_view (from_user,from_id,created_time,created_time_formated,user_id) SELECT ...;

由于OR IGNORE不会忽略明确的RAISE,因此如果您想忽略该错误,则必须将RAISE(ABORT,...)替换为RAISE(IGNORE)