我有一个SQLite数据库。我试图在表书签中插入值(users_id, lessoninfo_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+")))

这将给出一个错误:

数据库语法错误。


当前回答

如果你永远不想有副本,你应该声明这是一个表约束:

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)

其他回答

如果你有一个名为备忘录的表,它有id和text两列,你应该可以这样做:

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等于'text to insert'并且id等于5,那么插入操作将被忽略。

我不知道这是否适用于您的特定查询,但它可能会提示您如何进行。

我建议你把你的表设计成不允许重复的,就像下面@CLs回答中解释的那样。

如果你永远不想有副本,你应该声明这是一个表约束:

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)
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引擎,可以使用包含一条记录的Dummy表。 例句:

select 1, 167 from ONE_RECORD_DUMMY_TABLE

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

INSERT OR REPLACE INTO tableName (...) values(...);

更多信息请参见:sqlite.org/lang_insert