[sqlite] SQLite의 “존재하지 않으면 삽입”문

SQLite 데이터베이스가 있습니다. 행에 이전에 둘 다 존재하지 않는 경우에만 table에 값 ( 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 오류.



답변

당신이 두 개의 열이있는 테이블라는 메모가있는 경우 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 와 같은 행이 이미 포함되어 있으면 삽입 작업이 무시됩니다.

이것이 귀하의 특정 쿼리에 효과가 있는지는 모르겠지만 진행 방법에 대한 힌트를 줄 수 있습니다.

대신 @CLs answer아래 설명과 같이 중복이 허용되지 않도록 테이블을 디자인하는 것이 좋습니다 .


답변

중복을 원하지 않으면이를 테이블 제약 조건으로 선언해야합니다.

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 OR REPLACE INTO table () values();

자세한 정보는 sqlite.org/lang_insert를 참조하십시오.


답변

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 레코드를 포함하는 더미 테이블을 사용할 수 있습니다. 예 :

select 1, 167 from ONE_RECORD_DUMMY_TABLE


답변