Câu hỏi Câu lệnh "Chèn nếu không tồn tại" trong SQLite


Tôi có một cơ sở dữ liệu SQLite. Tôi đang cố gắng chèn các giá trị (users_id, lessoninfo_id) trong bảng bookmarks, chỉ khi cả hai không tồn tại trước khi liên tiếp.

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

Điều này cho một lỗi nói:

lỗi db gần nơi cú pháp.


75
2017-10-12 17:19


gốc




Các câu trả lời:


Nếu bạn có một bảng gọi là bản ghi nhớ có hai cột id và text bạn sẽ có thể làm như thế này:

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

Nếu một bản ghi đã chứa một hàng text bằng 'văn bản cần chèn' và id bằng 5, khi đó thao tác chèn sẽ bị bỏ qua.

Tôi không biết nếu điều này sẽ làm việc cho truy vấn cụ thể của bạn, nhưng có lẽ nó cung cấp cho bạn một gợi ý về cách tiến hành.

Tôi sẽ khuyên bạn thay vì thiết kế bảng của bạn để không có bản sao được cho phép như được giải thích trong @CLs answer phía dưới.


80
2017-10-12 17:38





Nếu bạn không bao giờ muốn có bản sao, bạn nên khai báo điều này dưới dạng ràng buộc bảng:

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

(Khóa chính trên cả hai cột sẽ có cùng tác dụng.)

Sau đó, bạn có thể nói với cơ sở dữ liệu mà bạn muốn âm thầm bỏ qua các hồ sơ vi phạm ràng buộc như vậy:

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

326
2017-10-13 08:10



Cách tối ưu để lấy ID của hàng mới được chèn vào hoặc hàng đã tồn tại là gì, vì vậy tôi có thể chèn nó vào một bảng khác có khóa ngoài cho khóa này? ví dụ. Tôi có hai bảng person (id, name unique) và cat (person_id, name unique) và tôi muốn chèn rất nhiều cặp (person_name, cat_name)? - Aur Saraf
Việc đọc ID của hàng hiện tại chỉ có thể có với truy vấn SELECT. Nhưng đây là một câu hỏi khác. - CL.
Có lẽ thêm ON CONFLICT IGNORE đến CREATE TABLE sẽ tiện dụng hơn một chút - defhlt
@CL. Điều gì sẽ xảy ra nếu tôi không chỉ định UNIQUE khi tạo bảng, nhưng tôi có cột đầu tiên id như một khóa chính? Tôi đã kiểm tra, nó không cập nhật các giá trị nếu tôi cố chèn bất kỳ thứ gì có cùng id với INSERT OR IGNORE. Vì vậy, tôi có cần một UNIQUE hạn chế nếu tôi có một chìa khóa PRIMARY hoặc có bất cứ điều gì tôi đang thiếu? - rightaway717
@ Hack06 Android chèn () hoạt động khác nhau; bạn nên thay thế bằng insertOrThrow () hoặc là insertWithOnConflict (). - CL.


Đối với một cột duy nhất, hãy sử dụng cột này:

INSERT OR REPLACE INTO table () values();

Để biết thêm thông tin, hãy xem: sqlite.org/lang_insert


3
2017-12-20 10:10





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;

Đây là cách nhanh nhất.

Đối với một số công cụ SQL khác, bạn có thể sử dụng bảng Dummy chứa 1 bản ghi. ví dụ:

select 1, 167 from ONE_RECORD_DUMMY_TABLE

2
2018-06-01 11:46





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

-2
2018-04-03 05:41



Sqlite có Schema ?????????????? - amin
Đây là truy vấn cho hai cơ sở dữ liệu khác nhau và chèn hai bảng dữ liệu khác nhau. - Almamun
bạn đã sử dụng Database.dbo.Table, nhưng nó không đúng. dbo là Schema và Sqlite không có Schema. Nếu bạn muốn kết nối 2 cơ sở dữ liệu khác nhau với nhau trong SQlite, bạn nên sử dụng Databse1.Table1 và Database2.Table2 - amin