1

我需要编写一个在无限循环中执行更新语句的 plpgsql 函数:

create function change_type() returns void as $$
begin
  loop  
    update table a set type = 1 where date < now(); 
  end loop;
end;
$$ LANGUAGE plpgsql;

当我调用此函数时,不会执行更新语句,尽管我可以看到循环正在运行。我将更新语句作为单个查询运行,它可以工作。我怎么解决这个问题?

谢谢

4

2 回答 2

4

您遇到的问题是 PostgreSQL 中的存储过程自动在其自己的事务中运行。所以更新正在发生,它们在提交之前是不可见的——这发生在存储过程退出时(在这种情况下它永远不会这样做)。

这将产生的实际影响是,一旦活动事务变得太大,您的服务器最终将耗尽磁盘空间或内存,或两者(或其他一些内置安全限制)。

正如@JackManey 建议的那样,解决方案是彻底重新考虑您的策略。如果你能解释你想要完成什么,我敢打赌我的下一张薪水支票,有更好的方法来完成它。

于 2012-04-23T08:02:30.480 回答
3

你正在寻找的是一个在特定时间(重复)安排任务的cronjob 。man crontab在 UNIX/LINUX 系统上试一试。最好作为系统用户postgres

要每 5 分钟运行一次查询,请在 cron 表中输入这样的一行。我crontab -e在 LINUX 下使用来编辑我的 cron 作业:

* 5 * * * psql mydb -c 'UPDATE TABLE a SET type = 1 WHERE date < now()'

如果您有更复杂的工作,请创建一个包含多个 SQL 命令的 shell 脚本,并将其命名为:

* 5 * * * psql mydb -f '/path/to/my_script.sh'

或者创建一个 plpgsql 函数并调用它:

* 5 * * * psql mydb -c 'SELECT myfunc()'

设置您的系统,以便超级用户 postgres 无需密码即可登录(默认设置)。


或者看看pgAdmin附带的pgAgent

于 2012-04-23T19:07:31.260 回答