2010-09-05 23 views
13

Trong SQLite, được đưa ra giản đồ cơ sở dữ liệu nàyTăng truy cập hoặc chèn hàng trong một tuyên bố, trong SQLite

CREATE TABLE observations (
    src TEXT, 
    dest TEXT, 
    verb TEXT, 
    occurrences INTEGER 
); 
CREATE UNIQUE INDEX observations_index 
    ON observations (src, dest, verb); 

bất cứ khi nào một quan sát tuple (:src, :dest, :verb) mới đến, tôi muốn hoặc tăng các "sự cố" cột cho hiện hàng cho tuple đó hoặc thêm hàng mới với lần xuất hiện = 1 nếu chưa có. Trong mã giả bê tông:

if (SELECT COUNT(*) FROM observations 
     WHERE src == :src AND dest == :dest AND verb == :verb) == 1: 
    UPDATE observations SET occurrences = occurrences + 1 
     WHERE src == :src AND dest == :dest AND verb == :verb 
else: 
    INSERT INTO observations VALUES (:src, :dest, :verb, 1) 

Tôi tự hỏi liệu có thể thực hiện toàn bộ hoạt động này trong một câu lệnh SQLite hay không. Điều đó sẽ đơn giản hóa logic ứng dụng (được yêu cầu để hoạt động cơ sở dữ liệu không đồng bộ đầy đủ) và cũng tránh tìm kiếm chỉ mục kép với chính xác cùng một khóa. INSERT HOẶC THAY THẾ không xuất hiện là những gì tôi muốn, và than ôi không có CẬP NHẬT HOẶC INSERT.

+0

Sẽ không có ý nghĩa hơn khi khai báo 'lần xuất hiện' là INTEGER? – dan04

+0

D'oh! Xin chào. Đã chỉnh sửa. – zwol

Trả lời

11

tôi có câu trả lời này từ Igor Tandetnik trên sqlite-người sử dụng:

INSERT OR REPLACE INTO observations 
VALUES (:src, :dest, :verb, 
    COALESCE(
    (SELECT occurrences FROM observations 
     WHERE src=:src AND dest=:dest AND verb=:verb), 
    0) + 1); 

Nó hơi nhưng luôn nhanh hơn cách tiếp cận của dan04.

+1

Xin lỗi nếu điều này là hiển nhiên, nhưng đừng quên tạo chỉ mục duy nhất theo OP hoặc điều này sẽ luôn tạo một bộ đếm mới và không bao giờ tăng: 'TẠO UNIQUE INDEX observations_index TRÊN quan sát (src, dest, verb);' . – ahcox

+0

Cũng lưu ý rằng nó tăng ROWID trên mỗi bản cập nhật (vì mỗi bản cập nhật thực chất là DELETE + INSERT) – ayke

3

Không biết một cách để làm điều đó trong một tuyên bố, nhưng bạn có thể thử

BEGIN; 
    INSERT OR IGNORE INTO observations VALUES (:src, :dest, :verb, 0); 
    UPDATE observeraions SET occurrences = occurrences + 1 WHERE 
     src = :src AND dest = :dest AND verb = :verb; 
COMMIT; 
Các vấn đề liên quan