1

我有一个 Perl 脚本,它查询数据库以查看是否有任何新行添加到数据库中,以及是否有新行我想根据它的列的值做一些事情。我想知道有没有办法每次都不选择数据库中的所有行?每次有新行可用时,PSQL 中是否有类似钩子的东西可以执行 Perl 子程序?

4

2 回答 2

3

每次有新行可用时,PSQL 中是否有类似钩子的东西可以执行 Perl 子程序?

选项 1:PL/Perl

您可以为此使用PL/Perl触发器。

您不能从现有程序运行 Perl 子程序,您需要提供 PL/Perl 过程,并且它不能直接调用 PostgreSQL 之外的代码。您可以做的是使用进程间通信(网络套接字、信号等)与外部程序通信。system()不过,通过 PL/Perl调用外部命令并不是一个好主意。

选项 2:LISTEN/NOTIFY

有一个简单的 PL/PgSQL 触发器,NOTIFY只要发生更改,它就会通过通知有效负载(较新的 Pg 和 DBI 版本)发送详细信息,或者将详细信息插入表中供您的客户端查询。让 PL/Perl 程序保持连接到数据库并LISTEN针对该事件。当事件发生时,使用通知有效负载来决定做什么,或者查询表以获取详细信息。

搜索“收听”和“通知”以了解有关此方法的更多信息。这通常是最好的选择。

于 2013-06-11T05:47:43.700 回答
2

我知道这是一个老问题,但我遇到了类似的问题,并像 Craig Ringer 建议的那样使用 LISTEN / NOTIFY 解决了它,但我直接使用 DBI 来解决它。

DBD::Pg 中有一个很好的功能,可以用来收听 Postgres 通知。这来自 DBD::Pg CPAN 文档:

$dbh->do("LISTEN abc");
$dbh->do("LISTEN def");

## Hang around until we get the message we want
LISTENLOOP: {
  while (my $notify = $dbh->pg_notifies) {
    my ($name, $pid, $payload) = @$notify;
    print qq{I received notice "$name" from PID $pid, payload was "$payload"\n};
    ## Do something based on the notice received
  }
  $dbh->ping() or die qq{Ping failed!};
  $dbh->commit();
  sleep(5);
  redo;
}
于 2015-11-12T09:21:27.383 回答