【问题标题】:Changing schema name within functions在函数中更改模式名称
【发布时间】:2019-12-08 22:39:30
【问题描述】:

我在 database1 中有 schema1。我想将 schema1 的所有功能移动到 database2 中存在的 schema2。我已将database1的备份文件恢复到database2。并更改了架构名称。函数调用的模式名称自动更改。但是在函数定义中,模式名称没有改变。例如:

CREATE OR REPLACE FUNCTION schema2.execute(..)
BEGIN 
select schema1."VALIDATE_SESSION"(....)
end

如何自动将“schema1”更改为“schema2”?
我试图将当前模式名称存储在变量中并将其附加到表中。但是调用current_schema() 会返回“public”。如何获取用户创建的当前模式?因为每次生成脚本时我都需要更改架构名称。

【问题讨论】:

  • 我很确定,在导出模式时,将有一个选项可以在生成脚本文件时跳过模式名称。请查看postgresql.org/docs/9.3/app-pgdump.html .... 你是如何备份脚本的?
  • 目标数据库中是否存在 schema1?如果没有,您可以简单地将备份恢复到目标数据库,然后将 schema1 重命名为 schema2
  • @a_horse_with_no_name schema1 在源数据库中。在目标数据库中更改架构名称只会更改函数声明架构,而不是函数定义。
  • 我直接从 pgadmin 获取备份。可以选择在数据库级别进行备份@Vivek

标签: postgresql function database-design database-schema


【解决方案1】:

虚拟函数中缺少的基本细节是函数体周围的单引号(或美元引号,都一样)。意思是,函数体被保存为字符串。见:

相比之下,考虑在 FK 约束中对表的引用(或更详细地说:schema.table(column))。对象名称在创建时解析为表的内部 OID(和列号)。 “提前绑定”。稍后更改名称(包括模式名称)时,这对 FK 完全没有影响。感觉所涉及的名称是动态更改的。但实际上,在创建对象后,实际名称并不重要。因此,您可以整天重命名模式,而不会对 FK 产生副作用。

函数body 中的名称存储为字符串并在调用时进行解释。 “后期绑定”。这些名称不会动态更改。

意思是,您必须实际编辑所有函数体,包括硬编码的模式名称。一种可能的替代方法是改用search_path,而不是在一开始就在函数体中使用模式名称。有各种各样的。见:

但这并不总是可以接受的。

你可以破解转储。或者在 Postgres 中使用 sting 操作来更新受影响的函数体。使用如下元查询查找受影响的函数:

SELECT *
FROM   pg_catalog.pg_proc
WHERE  prosrc ~ '\mschema1\M';  -- not bullet-proof!

无论哪种方式,如果架构名称可以是其他字符串的一部分或作为列名称弹出等,请注意错误匹配。动态 SQL 可以以任意方式连接字符串。如果你的函数中有这种邪恶的诡计,你需要适当地处理它。

【讨论】:

    猜你喜欢
    • 2013-03-07
    • 1970-01-01
    • 2015-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    相关资源
    最近更新 更多