2012-06-25 11 views
5

Chciałbym się upewnić, że zrobiłem wszystko we właściwy sposób.sqlite wstaw nową wartość do widoku

Istnieje plik dziennika 3Gb, który chcę analizować. Aby wykonać wszystkie zapytania w ": memory:" w celu zwiększenia wydajności, zastępuję 10 kolumn tekstowych liczbami całkowitymi dla każdego rzędu dzienników.

create table if not exists app (
    id Integer primary key autoincrement, 
    value text unique 
); 

create table if not exists secret (
    id integer primary key autoincrement, 
    value text unique 
); 

and 10 more tables 

create table if not exists raw_log 
(
    id Integer primary key autoincrement, 
    app_id INTEGER, 
    secret_id INTEGER, 
    and 10 more _id columns 
); 

i utworzyć widok dla zapytania oraz spust do wkładki.

create view if not exists log as 
    Select 
     raw_log.id, 
     app.value as app, 

     secret.value as secret, 
     and 10 more ... 

     from raw_log, app, secret, ..... x 10 
     where raw_log.app_id = app_id.id and raw_log.secret = secret.id and ... x 10 


CREATE TRIGGER insert_log 
    INSTEAD OF INSERT ON log 
    FOR EACH ROW BEGIN 
INSERT OR IGNORE INTO app(value) VALUES(NEW.app); 
INSERT OR IGNORE INTO secret(value) values(NEW.secret); 
... x 10 

INSERT INTO raw_log(app_id,secret_id, .... x 10) 
select app.id, secret.id, x 10 
from app, secret, x 10 
where app.value = NEW.app 
and secret.value = NEW.secret 
and ... x 10 
END;   

pytania:

Wkładka poprzez wyzwalacz nie wygląda pracują. Liczba encji w tabeli dziennika jest znacznie mniejsza niż powinna być, podczas gdy numery encji są tajne, a aplikacja wygląda poprawnie.

Myślę, że dzieje się tak dlatego, że nowa aplikacja i sekret pojawiają się w dzienniku. Mogą być wstawiane do stołu bez problemu. Jednak ponieważ zmiany te nie zostały jeszcze zatwierdzone, następujące zapytanie nie może pomyślnie odwołać się do tych wartości.

Jeśli tak, jak mogę poprawić te zapytania?

INSERT INTO raw_log(app_id,secret_id, .... x 10) 
     select app.id, secret.id, x 10 
      from app, secret, x 10 
      where app.value = NEW.app 
       and secret.value = NEW.secret 
       and ... x 10 
+1

ewentualnie niektóre kolumny gdzie null i tak, kiedy robi licznik, nie liczy się dostać? czy to rozwiązałeś? Jestem zainteresowany twoim rozwiązaniem. – cybork

+0

czy przetestowałeś moje rozwiązanie? –

Odpowiedz

1

Aby wstawiony id użytkowania last_insert_rowid(), ale jeśli nie jestem pewien, czy uzyskać identyfikator na konflikt, więc trzeba użyć IFNULL uzyskać identyfikator dla wkładki do raw_log.
maszt można zapisać wartość last_insert_rowid() przed następną wkładką, dlatego należy użyć zmienne ...

CREATE TEMP TABLE IF NOT EXISTS _Variables (Name TEXT PRIMARY KEY, Value TEXT); 
... 
INSERT OR IGNORE INTO app(value) VALUES(NEW.app); 
INSERT OR REPLACE INTO _Variables(Key, Value) VALUES('app_id', ifnull((SELECT app.id from app where app.value = NEW.app), last_insert_rowid()); 
... 
INSERT INTO raw_log(app_id, secret_id, ... x 10) 
values((SELECT Value FROM _Variables WHERE Key = 'app_id') 
, (SELECT Value FROM _Variables WHERE Key = 'secret_id'), ... x 10); 
END; 
Powiązane problemy