SQLite 中的“如果不存在则插入”语句

Posted

技术标签:

【中文标题】SQLite 中的“如果不存在则插入”语句【英文标题】:"Insert if not exists" statement in SQLite 【发布时间】:2013-10-20 15:34:16 【问题描述】:

我有一个 SQLite 数据库。我正在尝试在表 bookmarks 中插入值(users_idlessoninfo_id),前提是两者之前都不存在。

INSERT INTO bookmarks(users_id,lessoninfo_id) 
VALUES(
    (SELECT _id FROM Users WHERE User='"+$('#user_lesson').html()+"'),
        (SELECT _id FROM lessoninfo 
        WHERE Lesson="+lesson_no+" AND cast(starttime AS int)="+Math.floor(result_set.rows.item(markerCount-1).starttime)+") 
        WHERE NOT EXISTS (
            SELECT users_id,lessoninfo_id from bookmarks 
            WHERE users_id=(SELECT _id FROM Users 
            WHERE User='"+$('#user_lesson').html()+"') AND lessoninfo_id=(
                SELECT _id FROM lessoninfo
                WHERE Lesson="+lesson_no+")))

这给出了一个错误提示:

where 语法附近出现 db 错误。

【问题讨论】:

【参考方案1】:

如果你不想有重复,你应该把它声明为一个表约束:

CREATE TABLE bookmarks(
    users_id INTEGER,
    lessoninfo_id INTEGER,
    UNIQUE(users_id, lessoninfo_id)
);

(两列上的主键将具有相同的效果。)

然后可以告诉数据库你想silently ignore records that would violate such a constraint:

INSERT OR IGNORE INTO bookmarks(users_id, lessoninfo_id) VALUES(123, 456)

【讨论】:

获取新插入行的 ID 或已经存在的行的 ID 的最佳方法是什么,以便我可以将其插入到另一个具有该外键的表中?例如我有两张表person (id, name unique)cat (person_id, name unique),我想插入很多对(person_name, cat_name)? 只有使用 SELECT 查询才能读取现有行的 ID。但这是一个不同的问题。 或许将ON CONFLICT IGNORE 添加到CREATE TABLE 会更方便一些 @rightaway717 “忽略”表示什么都没有发生;这个问题与更新无关。 @Hack06 android 的 insert() 行为不同;您应该将其替换为 insertOrThrow() 或 insertWithOnConflict()。【参考方案2】:

如果您有一个名为 memos 的表,它有两列 idtext,您应该可以这样做:

INSERT INTO memos(id,text) 
SELECT 5, 'text to insert' 
WHERE NOT EXISTS(SELECT 1 FROM memos WHERE id = 5 AND text = 'text to insert');

如果记录已经包含text 等于“要插入的文本”且id 等于5 的行,则插入操作将被忽略。

我不知道这是否适用于您的特定查询,但也许它会提示您如何继续。

我建议您改为设计您的表格,以便不允许重复,如下面的@CLs answer 中所述。

【讨论】:

【参考方案3】:

对于一个唯一的列,使用这个:

INSERT OR REPLACE INTO table () values();

欲了解更多信息,请参阅:sqlite.org/lang_insert

【讨论】:

这对我不起作用。它总是像插入或替换一样插入到 my_table (col1, col2) values('1','2');将添加多行 1 2 我可能会补充一点,如果将约束设置到位 Unique(col1,col2) 并且您也有 col3,它会很好地工作,因为插入或忽略将失败,这会将 col3 更新为新值。 insert or replace into my_table values('1','2','5') 替换一行 '1','2','3'【参考方案4】:
insert into bookmarks (users_id, lessoninfo_id)

select 1, 167
EXCEPT
select user_id, lessoninfo_id
from bookmarks
where user_id=1
and lessoninfo_id=167;

这是最快的方法。

对于其他一些 SQL 引擎,您可以使用包含 1 条记录的 Dummy 表。 例如:

select 1, 167 from ONE_RECORD_DUMMY_TABLE

【讨论】:

以上是关于SQLite 中的“如果不存在则插入”语句的主要内容,如果未能解决你的问题,请参考以下文章

Android Sqlite 如果不存在则插入

mysql判断一条记录是否存在,如果存在,则更新此语句,如果不存在,则插入

MySQL INSERT插入条件判断:如果不存在则插入

MySQL INSERT插入条件判断:如果不存在则插入

MySQL:如果值存在,则对行进行更新,如果值不存在,则插入 [重复]

如果不存在则插入数据的过程pl sql