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


142

SQLiteデータベースがあります。テーブルに値(users_idlessoninfo_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+")))

これは言うエラーを与えます:

where構文の近くのdbエラー。

回答:


138

2つの列を持つメモと呼ばれるテーブルが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「挿入するテキスト」に等しい行と5に等しい行が含まれている場合、id挿入操作は無視されます。

これがあなたの特定のクエリでうまくいくかどうかはわかりませんが、おそらくそれはあなたにどのように進めるかのヒントを与えます。

代わりに、@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を取得するための最適な方法は何ですか?これを、この行への外部キーを持つ別のテーブルに挿入できますか?たとえば、2つのテーブルがperson (id, name unique)ありcat (person_id, name unique)、たくさんのペアを挿入したい(person_name, cat_name)ですか?
Aur Saraf

2
既存の行のIDの読み取りは、SELECTクエリでのみ可能です。しかし、これは別の質問です。
CL。

1
たぶん追加ON CONFLICT IGNOREするCREATE 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の複数行を追加します
Peter Moore

制約が設定され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つのレコードを含むダミーテーブルを使用できます。例えば:

select 1, 167 from ONE_RECORD_DUMMY_TABLE
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.