2

我正在尝试创建一个类似于tail -fsqlite 文件的脚本。认为触发器是最好的答案,我尝试了以下方法:

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

这个想法是在插入时,它将新行打印到标准输出。不幸的是,当插入表格时,我什么也没得到。

我究竟做错了什么?

另外,假设我可以从 sqlite shell 让它全部工作,当其他进程插入表时它仍然工作吗?

4

2 回答 2

3

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

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

理论上,您可以定义自己的用户定义函数来打印一些东西:

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

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

于 2013-02-02T10:52:11.970 回答
1

您可以循环运行 sqlite。

双倒车

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

简单的监控

$ 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...)

您可以过滤结果。

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

您可以提取所需的列

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

可能的改进

您也可以考虑将其添加到.bashrc,因此您可以执行类似的操作

sqlitetailf /tmp/db.db j1939


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

2秒后

1621524|LOGIN1|838
1621525|LOGIN2|19
1621526|LOGIN3|839
1621527|LOGIN4|20
1621528|LOGIN5|839
1621527|LOGIN6|20
1621528|LOGIN7|839
于 2016-10-20T19:17:07.340 回答