sqlite将新值插入视图

时间:2012-06-25 02:48:57

标签: sql sqlite view triggers

我想确保我以正确的方式做了一切。

我想分析一个3Gb日志文件。 为了在“:memory:”中执行所有查询以提高性能, 我将10行文本列替换为每行日志的整数ID。

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

并创建查询视图和插入触发器。

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;          

的问题:

插入通过触发器看起来不起作用。 日志表中的实体数量远小于应有的数量,而实体数量在秘密和应用程序中看起来正确。

我认为这是因为新的应用和秘密出现在日志中。它们可以毫无问题地插入表中。但是,由于尚未提交这些更改,因此以下查询无法成功引用这些值。

如果是,我该如何修复这些查询?

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 个答案:

答案 0 :(得分:1)

要获取插入的id,请使用last_insert_rowid(),但如果我不确定您是否在冲突时获得id,那么您必须使用ifnull来获取插入raw_log的id。
你在下次插入之前保存了last_insert_rowid()的保存值,这就是为什么你必须使用变量...

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;
相关问题