Инструкция «Вставить, если не существует» в SQLite

65

У меня есть база данных SQLite. Я пытаюсь вставить значения (users_id, lessoninfo_id) в таблицу bookmarks, только если они не существуют раньше в строке.

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 рядом с синтаксисом.

Теги:
constraints
sql-insert

5 ответов

72
Лучший ответ

Если у вас есть таблица с именем memos, которая имеет два столбца 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 равно "текст для вставки", а id равен 5, тогда операция вставки будет проигнорирована.

Я не знаю, будет ли это работать для вашего конкретного запроса, но, возможно, это даст вам подсказку о том, как действовать.

280

Если вы никогда не хотите дублировать, вы должны объявить это как ограничение таблицы:

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)
  • 8
    Каков оптимальный способ получения идентификатора вновь вставленной строки или уже существующей, чтобы я мог вставить ее в другую таблицу с внешним ключом для этой таблицы? например, у меня есть две таблицы person (id, name unique) и cat (person_id, name unique) и я хочу вставить много пар (person_name, cat_name) ?
  • 2
    Чтение идентификатора существующей строки возможно только с помощью запроса SELECT. Но это другой вопрос.
Показать ещё 9 комментариев
2
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, содержащую 1 запись. например:

select 1, 167 from ONE_RECORD_DUMMY_TABLE
0

для уникального столбца используйте это:

ВСТАВИТЬ ИЛИ ЗАМЕНИТЬ В таблицу() значения();

подробнее: sqlite.org/lang_insert

-3
INSERT INTO Database.dbo.Table
     SELECT *
       FROM Database.dbo.Table
      WHERE ID not in (select ID from Database.dbo.Table)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню