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


141

我有一个SQLite数据库。我试图在表中插入值(users_idlessoninfo_idbookmarks,前提是两个值都不连续存在。

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+")))

这给出了一个错误说:

db错误在哪里语法附近。

Answers:


137

如果您有一个称为备忘录的表,该表具有两列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如下所述。


435

如果您永远不想重复,则应将其声明为表约束:

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

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

然后可以告诉数据库您要静默忽略将违反此类约束的记录

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

12
然后获取新插入的行或已经存在的行的ID的最佳方法是什么,因此我可以将其插入到另一个具有该行外键的表中?例如我有两个表person (id, name unique)cat (person_id, name unique)我想插入很多对(person_name, cat_name)吗?
Aur Saraf

2
只有使用SELECT查询,才能读取现有行的ID。但这是一个不同的问题。
CL。

1
也许添加ON CONFLICT IGNORECREATE TABLE将是一个更方便的一点
defhlt

1
@ rightaway717“忽略”表示什么都没有发生;这个问题与更新无关。
CL。

1
@ Hack06 Android的insert()的行为有所不同;您应该将其替换为insertOrThrow()insertWithOnConflict()
CL。

21

对于唯一列,请使用以下命令:

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'
Peter Moore

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.