web-dev-qa-db-ja.com

SQLiteの「存在しない場合は挿入」ステートメント

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エラー。

102
user2780638

idtextの2つの列を持つmemosというテーブルがある場合、次のようにすることができます。

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 で説明されているように、重複が許可されないようにテーブルを設計することをお勧めします。

107
Cyclonecode

重複したくない場合は、これをテーブル制約として宣言する必要があります。

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)
377
CL.

一意の列の場合、これを使用します。

INSERT OR REPLACE INTO table () values();

詳細については、以下を参照してください: sqlite.org/lang_insert

12
Ali Bagheri
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
2
suat dmk