我如何定义一个 plpgsql 函数,它接受一个没有模式限定且尚未创建的类型的参数
How can I define a plpgsql function that accepts a parameter of a type that is not schema qualified and is not yet created
我的数据库是根据每个应用程序用户的架构构建的。在每个模式中,都有一个相同的 table 命名为“条目”,具有完全相同的 DDL。我还有一个通用架构,其中包含一些对这些“条目”table 进行操作的函数,并且在执行期间,搜索路径定义了该函数在哪个架构的条目table 上运行。在创建任何用户架构之前,我在定义这些函数时遇到了问题,因为它们引用了用户架构中尚未创建的 table。该问题已使用 set check_function_bodies = off;
解决,但现在我遇到了一个类似的问题,该函数将那些 table 引用为 inout 参数。我无法创建该函数,因为它接受的参数是“条目”类型,并且我收到“类型条目不存在”的错误。 set check_function_bodies = off
没有解决这个问题。有没有办法解决这个问题?
函数签名是
create or replace function common.reconcile_user_entry(inout e entries) returns void
我真的不想在每个用户模式中定义这个函数,因为它总是相同的,而且我不想在需要进行更改时必须在每个模式中重新编译它。
你可以使用 inheritance。
像所有其他 entries
table 一样定义一个 table common.entries
并更改其他 entries
table 以继承自它:
ALTER TABLE schema1.entries INHERIT common.entries;
然后定义函数以 common.entries
作为参数或 return 类型,您可以将它与任何继承的 table 一起使用。
我想你可以使用 table 继承。
您必须在通用架构中为用户架构中的每个 table 创建一个“父级”table。然后从他们那里继承用户table。定义函数参数时使用“parent”table 名称。参见示例:
CREATE TABLE parent(id integer);
CREATE TABLE child() INHERITS (parent);
INSERT INTO child(id) VALUES (1);
CREATE FUNCTION get_id(IN prm_row parent) RETURNS integer
LANGUAGE SQL
AS $$
SELECT prm_row.id;
$$;
SELECT get_id((SELECT (child) FROM child WHERE id = 1));
请注意,父 table 将包含所有子 table 的记录,因此您应该使用权限来防止用户访问父 table。
我没有使用继承,而是通过像这样绕过问题来解决它:
而不是将函数签名定义为
create or replace function common.reconcile_user_entry(inout e entries) returns void
我定义为
create or replace function common.reconcile_user_entry(inout r record) returns void
并且在函数代码中我声明了一个变量e entries;
然后将记录分配给变量:
declare
e entries;
begin
select into e r.*
...
关于继承的解决方案,它有效,但我发现上面的解决方案更简单。
我知道我的解决方案一定有注意事项和隐藏的问题,如果有人可以指出,请指出。
我的数据库是根据每个应用程序用户的架构构建的。在每个模式中,都有一个相同的 table 命名为“条目”,具有完全相同的 DDL。我还有一个通用架构,其中包含一些对这些“条目”table 进行操作的函数,并且在执行期间,搜索路径定义了该函数在哪个架构的条目table 上运行。在创建任何用户架构之前,我在定义这些函数时遇到了问题,因为它们引用了用户架构中尚未创建的 table。该问题已使用 set check_function_bodies = off;
解决,但现在我遇到了一个类似的问题,该函数将那些 table 引用为 inout 参数。我无法创建该函数,因为它接受的参数是“条目”类型,并且我收到“类型条目不存在”的错误。 set check_function_bodies = off
没有解决这个问题。有没有办法解决这个问题?
函数签名是
create or replace function common.reconcile_user_entry(inout e entries) returns void
我真的不想在每个用户模式中定义这个函数,因为它总是相同的,而且我不想在需要进行更改时必须在每个模式中重新编译它。
你可以使用 inheritance。
像所有其他 entries
table 一样定义一个 table common.entries
并更改其他 entries
table 以继承自它:
ALTER TABLE schema1.entries INHERIT common.entries;
然后定义函数以 common.entries
作为参数或 return 类型,您可以将它与任何继承的 table 一起使用。
我想你可以使用 table 继承。
您必须在通用架构中为用户架构中的每个 table 创建一个“父级”table。然后从他们那里继承用户table。定义函数参数时使用“parent”table 名称。参见示例:
CREATE TABLE parent(id integer);
CREATE TABLE child() INHERITS (parent);
INSERT INTO child(id) VALUES (1);
CREATE FUNCTION get_id(IN prm_row parent) RETURNS integer
LANGUAGE SQL
AS $$
SELECT prm_row.id;
$$;
SELECT get_id((SELECT (child) FROM child WHERE id = 1));
请注意,父 table 将包含所有子 table 的记录,因此您应该使用权限来防止用户访问父 table。
我没有使用继承,而是通过像这样绕过问题来解决它:
而不是将函数签名定义为
create or replace function common.reconcile_user_entry(inout e entries) returns void
我定义为
create or replace function common.reconcile_user_entry(inout r record) returns void
并且在函数代码中我声明了一个变量e entries;
然后将记录分配给变量:
declare
e entries;
begin
select into e r.*
...
关于继承的解决方案,它有效,但我发现上面的解决方案更简单。 我知道我的解决方案一定有注意事项和隐藏的问题,如果有人可以指出,请指出。