更改函数内的模式名称

问题描述 投票:0回答:1

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

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

如何自动将“schema1”更改为“schema2”?
我尝试将当前模式名称存储在变量中并将其附加到表中。但调用

current_schema()
返回“public”。如何获取用户当前创建的模式?因为每次我需要在生成脚本时更改模式名称。

postgresql function database-design database-schema
1个回答
2
投票

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

相比之下,请考虑在 FK 约束中引用表(或更详细地说:

schema.table(column)
)。对象名称在创建时解析为表的内部 OID(和列号)。 “早期绑定”。当名称(包括模式名称)稍后更改时,这对 FK 完全没有影响。感觉涉及的名称是动态更改的。但实际上,在创建对象之后,实际名称就不再重要了。因此,您可以整天重命名模式,而不会对 FK 产生副作用。

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

Postgres 14 起,此规则有一个例外,但仅适用于

LANGUAGE sql
函数:“SQL 标准函数体”。它们在创建时进行解析,因此它们会尽早绑定,并跟踪模式的 OID,而不是其名称。参见:

除此之外,您必须实际编辑所有函数体,包括硬编码的架构名称。一种可能的替代方案是依赖

search_path
而不是一开始就在函数体中使用模式名称。有各种各样的。参见:

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.