如何在 postgreSQL 中处理复合类型的变化
Posted
技术标签:
【中文标题】如何在 postgreSQL 中处理复合类型的变化【英文标题】:How to handle changes in composite type in postgreSQL 【发布时间】:2017-02-26 21:47:35 【问题描述】:我即将学习 postgresql,但遇到了某种问题。我想通过存储过程(函数)建立从网站到数据库的大部分连接。到目前为止,我有大约 20 个函数,其中 5 个函数返回与列完全相同的表,即:
create or replace function my_Function( t text )
returns setof table(uid uuid,testText text, randomInt int ...)
...
因为 table(uid uuid,testText text, randomInt int ...) 重复了 5 次,我发现我可以使用复合类型从我的函数返回相同类型的数据,所以如果我需要返回一个额外的列我可以更改我的复合类型,瞧,所有 5 个函数都应该返回相同的列。
不幸的是,这不是如何工作的,一旦我向复合类型添加了一个新列,所有使用我的复合类型的函数都因 saem 错误而中断:
Final statement returns too few columns
这是有道理的,因为我没有选择额外的列来适应复合类型。
有什么方法可以判断哪些函数使用复合类型作为返回类型? 有没有办法强制复合类型为新创建的列填充空白(如果没有,那么我也可以使用 table(...) 返回类型,因为它不能解决我试图避免的冗余问题)?
【问题讨论】:
【参考方案1】:示例设置:
create type my_type as (id int, name text);
create or replace function my_function_1()
returns setof my_type language plpgsql as $$
declare
rec my_type;
begin
rec.id := 1;
rec.name := 'name';
return next rec;
end $$;
create or replace function my_function_2()
returns setof my_type language plpgsql as $$
begin
return query select 1::int, 'name'::text;
end $$;
有什么方法可以判断哪些函数使用复合类型作为返回类型?
是的:
select nspname as schema_name, proname as function_name
from pg_proc p
join pg_namespace n on n.oid = pronamespace
join pg_type t on t.oid = prorettype
where typname = 'my_type';
schema_name | function_name
-------------+---------------
public | my_function_1
public | my_function_2
(2 rows)
有没有办法强制复合类型为新创建的列填充空白?
没有。在向类型添加新属性后,您可以尝试重新创建(不修改)函数:
alter type my_type add attribute new_col int;
create or replace function my_function_1() ...
create or replace function my_function_2() ...
但只有返回下一个类型变量的函数才能正常工作(my_function_1()
可以工作,my_function_2()
不行)。
【讨论】:
嗯,这听起来很压抑。修改这么难,我就不去了。【参考方案2】:使用 Postgres 复合类型有什么好处?这似乎是一个痛苦的世界。我可以探索这将如何与QueryFirst 一起工作吗?您的程序将在您的应用程序中的 .sql 文件中,与您的应用程序一起进行版本控制,源代码受控。对于共享返回类型的 5 个过程,您将创建一个 C# 接口。在 5 个 Results.cs 文件的每一个中,在结果部分类上,继承接口。因此,这 5 个 proc 可以单独发展,根据需要添加列。如果您修改了 proc 使其不再满足接口:编译错误。一个更宽容、更能容忍变化的场景。
免责声明:我写的是 QueryFirst
【讨论】:
以上是关于如何在 postgreSQL 中处理复合类型的变化的主要内容,如果未能解决你的问题,请参考以下文章