ChatGPT解决这个技术问题 Extra ChatGPT

"Insert if not exists" statement in SQLite

I have an SQLite database. I am trying to insert values (users_id, lessoninfo_id) in table bookmarks, only if both do not exist before in a row.

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+")))

This gives an error saying:

db error near where syntax.


C
CL.

If you never want to have duplicates, you should declare this as a table constraint:

CREATE TABLE bookmarks(
    users_id INTEGER,
    lessoninfo_id INTEGER,
    UNIQUE(users_id, lessoninfo_id)
);

(A primary key over both columns would have the same effect.)

It is then possible to tell the database that you want to silently ignore records that would violate such a constraint:

INSERT OR IGNORE INTO bookmarks(users_id, lessoninfo_id) VALUES(123, 456)

What is the optimal way to then get the ID of the newly inserted row or the already existing one, so I can insert it to another table that has a foreign key to this one? e.g. I have two tables person (id, name unique) and cat (person_id, name unique) and I want to insert lots of pairs (person_name, cat_name)?
Reading the ID of an existing row is possible only with a SELECT query. But this is a different question.
Perhaps adding ON CONFLICT IGNORE to CREATE TABLE would be a bit more handy
@rightaway717 "Ignore" means that nothing happens; this question has nothing to do with updating.
@Hack06 Android's insert() behaves differently; you should replace it with insertOrThrow() or insertWithOnConflict().
C
Cyclonecode

If you have a table called memos that has two columns id and text you should be able to do like this:

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');

If a record already contains a row where text is equal to 'text to insert' and id is equal to 5, then the insert operation will be ignored.

I don't know if this will work for your particular query, but perhaps it give you a hint on how to proceed.

I would advice that you instead design your table so that no duplicates are allowed as explained in @CLs answer below.


A
Ali Bagheri

For a unique column, use this:

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

For more information, see: sqlite.org/lang_insert


This does not work for me. it always inserts as in insert or replace into my_table (col1, col2) values('1','2'); will add multiple rows of 1 2
I might add that it does work well if the constraint is put in place Unique(col1,col2) and you also have col3, because an insert or ignore would fail where this will update col3 to the new value. insert or replace into my_table values('1','2','5') replaces a row '1','2','3'
y
youpilat13
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;

This is the fastest way.

For some other SQL engines, you can use a Dummy table containing 1 record. e.g:

select 1, 167 from ONE_RECORD_DUMMY_TABLE