sqlite触发器输出

时间:2013-02-01 21:36:37

标签: shell logging sqlite tail

我正在尝试创建一个类似于tail -f的脚本,但是对于sqlite文件。 认为触发器是最好的答案,我尝试了以下内容:

CREATE TEMPORARY TRIGGER "tailf" AFTER INSERT ON "my_table"
  BEGIN
    SELECT * FROM "my_table" WHERE rowid = NEW.rowid;
  END;

想法是在插入时,它会将新行打印到stdout。 不幸的是,当插入表格时,我什么也没得到。

我做错了什么?

另外,假设我可以从sqlite shell中完成所有工作,当其他进程插入到表中时,它是否仍然可以工作?

2 个答案:

答案 0 :(得分:3)

当SQLite执行SELECT命令时,它只是将数据返回给应用程序。 应用程序有责任对数据执行某些操作(例如在sqlite3 shell的情况下打印它)。

在触发器内部,没有应用程序等待SELECT的结果,因此结果被丢弃。 触发器内SELECT命令的唯一目的是调用具有一些副作用的用户定义函数。

理论上,您可以定义自己的用户定义函数来打印内容:

CREATE TEMPORARY TRIGGER "tailf" AFTER INSERT ON "my_table"
BEGIN
    SELECT print(column1, column2, ...) FROM "my_table" WHERE rowid = NEW.rowid;
END;

但除非您控制其他进程,否则他们不会为您安装该功能。

答案 1 :(得分:1)

You can run sqlite in a loop.

Dobule reversing

while true; do sqlite3 /tmp/db.db 'select * from (select * from j1939 order by timestamp desc limit 50) order by timestamp asc limit 50'; sleep 1; done | grep -E

Simple monitoring

$ while true; do sqlite3 /tmp/db.db 'select * from j1939 where id>(select max(id) from j1939)-50'; sleep 1; done

1621524|LOGIN1|838
1621525|LOGIN2|19
1621526|LOGIN3|839
1621527|LOGIN4|20
1621528|LOGIN5|839 (more...)

You can filter results.

while true; do sqlite3 /tmp/db.db 'select * from j1939 where id>(select max(id) from j1939)-50'; sleep 1; done | grep -E LOGIN5|LOGIN3

1621526|LOGIN3|839
1621528|LOGIN5|839

You can extract columns you need

while true; do sqlite3 /tmp/db.db 'select * from j1939 where id>(select max(id) from j1939)-50'; sleep 1; done | cut -d '|' -f 1-2

1621526|LOGIN3|839
1621528|LOGIN5|839

Possible improvements

you could also consider adding this to .bashrc, so you could do something like

sqlitetailf /tmp/db.db j1939


1621524|LOGIN1|838
1621525|LOGIN2|19
1621526|LOGIN3|839
1621527|LOGIN4|20
1621528|LOGIN5|839

and 2 seconds after

1621524|LOGIN1|838
1621525|LOGIN2|19
1621526|LOGIN3|839
1621527|LOGIN4|20
1621528|LOGIN5|839
1621527|LOGIN6|20
1621528|LOGIN7|839