【问题标题】:Postgresql plpgsql stored procedure update statement in loop循环中的 Postgresql plpgsql 存储过程更新语句
【发布时间】:2012-04-23 06:41:11
【问题描述】:

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

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

当我调用这个函数时,更新语句没有被执行,尽管我可以看到循环正在运行。我将更新语句作为单个查询运行,它可以工作。我该如何解决这个问题?

谢谢

【问题讨论】:

  • 0_0 首先,不要使用带有无限循环的存储过程,不会中断!
  • 那我该怎么办?我需要一些可以无限期运行并根据时间进行更新的东西。
  • 完全重新考虑你在做什么。彻底彻底。
  • 你认为你为什么需要这个?

标签: postgresql stored-procedures loops plpgsql


【解决方案1】:

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

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

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

【讨论】:

  • 感谢您的回答。我有一个使用 JSF 2.1、EJB 和 Primefaces 开发的 Web 应用程序。我需要一些功能或服务,当应用程序启动并查询某个表 A 并检查该表中的“日期”列时,它会在数据库中自动运行。如果日期等于或小于当前日期,则将“类型”列中的值更改为表 A 中相应行的其他值。
  • 我需要这个函数启动一次并在应用程序的生命周期内运行,因为新记录将被添加到表 A 中并且也需要检查。我可以使用定期向数据库发送查询的 java Timer 来执行相同的任务,但我不想在应用程序层执行此任务,因为它似乎很昂贵。我认为可以在数据库层完成,在性能方面会更有效。您对我如何解决这个问题有什么建议吗?
  • @Nurzhan - “我需要一些在应用程序启动时在数据库中自动运行的功能或服务......”不,你不需要。您需要一次执行一组更新的守护程序或 cron 作业。重新思考你对你正在做的事情的整个方法。
  • @Nurzhan:您对问题的描述不够清楚,无法确定,但听起来您可能需要一些trigger 功能。 postgresql.org/docs/9.1/interactive/trigger-definition.html
  • @Nurzhan:我不知道为什么您需要更新列,只要它的“日期”早于 NOW();为什么不调整您的查询来弥补这一点? SELECT *,date &lt;= NOW() AS type ...SELECT * ... WHERE date &lt;= NOW() 可能应该这样做。如果您真的确实需要定期更新,请按照 JackManey 的建议使用 cron 作业。
【解决方案2】:

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

要每 5 分钟运行一次查询,请在您的 cron 表中输入这样的一行。我在 LINUX 下使用 crontab -e 来编辑我的 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-30
    • 1970-01-01
    • 2012-04-16
    • 1970-01-01
    相关资源
    最近更新 更多