在函数中更改架构名称

Changing schema name within functions

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

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

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

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

  • What are '$$' used for in PL/pgSQL

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

函数 body 中的名称存储为字符串,并在调用时进行解释。 "Late binding"。这些名称不会动态更改。

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

  • How does the search_path influence identifier resolution and the "current schema"

但这并不总是能接受table。

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

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

无论哪种方式,如果架构名称可以是其他字符串的一部分或作为列名称弹出等,请提防错误匹配。并且动态 SQL 可以以任意方式连接字符串。如果你的函数中有这样的恶作剧,你需要妥善处理。