【问题标题】:Cleanly setting the role when doing DDL from inside a PLPgSQL function从 PLPgSQL 函数内部执行 DDL 时干净地设置角色
【发布时间】:2018-05-11 09:02:52
【问题描述】:

先介绍一下背景知识:我有一个部署到许多站点的应用程序,每个站点都有自己的数据库。

多个用户可以使用数据库。我创建了一个appdbusers ROLE,我授予每个用户。数据库和所有表都归appdbusers所有。

在应用程序启动时,upgradedb() 函数执行所需的 DDL 来添加/修改/删除关系、元组、约束等,以匹配应用程序的要求。

在调用upgradedb() 之前,应用程序调用SET ROLE appdbusers,之后调用RESET ROLE。这样,第一个启动新版本的用户会升级数据库。

现在我有一个相当大的 PLPgSQL 函数,我在其中删除 2 个表并重新创建它们;这些应该定义为 TEMP 表,但由于不同的原因,它们不能。我可以将它们视为常规表并在 upgradedb() 中执行 DDL 魔术,但我更喜欢在每次运行时 DROP 并重新创建它们。

我想在函数的开头包含SET ROLE appdbusers,在结尾包含RESET ROLE,但如果函数因任何原因(包括用户中断)中止,RESET ROLE 将永远不会发生。

我没有在 PLPgSQL 中看到 TRY...FINALLY 构造,我读过 (here) :

需要捕获异常的函数成本要高得多,因此最好避免异常。

那么有没有办法在函数退出时自动重置角色?或者有没有更好的方法来处理 DDL 逻辑?

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    使用SET LOCAL ROLE

    文档说:

    SET LOCAL 的效果只持续到当前事务结束,无论是否已提交。

    除非您在调用该函数之前启动显式事务,否则它应该可以满足您的要求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-14
      • 1970-01-01
      • 2018-07-18
      • 1970-01-01
      • 2011-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多