2009-12-29 26 views
10

Chciałbym utworzyć tabelę SQL, która ma nie więcej niż n wierszy danych. Po wstawieniu nowego wiersza chciałbym, aby usunięto najstarszy wiersz, aby zrobić miejsce na nowy.Rolling wierszy w tabeli SQL

Czy istnieje typowy sposób postępowania w SQLite?

Czy należy nim zarządzać za pomocą kodu zewnętrznego (zewnętrznego)?

Odpowiedz

11

Rozszerzając Alex' answer i zakładając mieć przyrost, nie powtarzając kolumnę seryjny na stole t nazwie serial które mogą być używane do określenia względnego wieku wierszy:

CREATE TRIGGER ten_rows_only AFTER INSERT ON t 
    BEGIN 
    DELETE FROM t WHERE serial <= (SELECT serial FROM t ORDER BY serial DESC LIMIT 10, 1); 
    END; 

To nic zrobić, gdy masz mniej niż dziesięć wierszy, a DELETE najniższą seryjny gdy INSERT doprowadziłaby do jedenastu wierszy.

UPDATE

Oto nieco bardziej skomplikowany przypadek, gdzie rekordy tabeli „wiek” z wiersza w kolumnie, która może zawierać duplikaty, jak na przykład kolumnę TIMESTAMP śledzenia razy wkładki.

sqlite> .schema t 
CREATE TABLE t (id VARCHAR(1) NOT NULL PRIMARY KEY, ts TIMESTAMP NOT NULL); 
CREATE TRIGGER ten_rows_only AFTER INSERT ON t 
    BEGIN 
    DELETE FROM t WHERE id IN (SELECT id FROM t ORDER BY ts DESC LIMIT 10, -1); 
    END; 

Tu bierzemy za pewnik, że nie możemy używać id do określenia względnej wiek, więc usunąć wszystko po pierwszych 10 wierszy zamówionych przez datownik. (SQLite narzuca arbitralne zamówienie na wiersze mające ten sam numer ts).

+0

nie będzie to zawsze usunąć pierwszy wiersz? – aronchick

+0

@aronchick, nie - skalarne podzapytanie oceni na NULL, jeśli nie ma rekordu na 11 pozycji (PO naszej INSERT prawdopodobnie z 11 rzędu), a zatem klauzula "WHERE" staje się "WHERE serial <= NULL", który nie pasuje do niczego. – pilcrow

+0

Co zrobić, jeśli _id jest automatycznie zwiększany. Nie można tego kodu wykonać za pomocą _id zamiast TIMESTAMP lub serial? Zwłaszcza gdy TIMESTAMP nie zawsze jest częścią schematu tabeli ... –

0

To byłoby coś w stylu, w jaki sposób można to zrobić. Zakłada się, że my_id_column jest automatycznie inkrementowany i jest kolumną porządkowania dla tabeli.

-- handle rolls forward 
-- deletes the oldest row 
create trigger rollfwd after insert on my_table when (select count() from my_table) > max_table_size 
    begin 
    delete from my_table where my_id_column = (select min(my_id_column) from my_table); 
    end; 

-- handle rolls back 
-- inserts an empty row at the position before oldest entry 
-- assumes all columns option or defaulted 
create trigger rollbk after delete on my_table when (select count() from my_table) < max_table_size 
    begin 
    insert into my_table (my_id_column) values ((select min(my_id_column) from my_table) - 1); 
    end; 
Powiązane problemy