我目前正在将一些过程从Oracle迁移到Postgres,这些过程使用的类型是为处理未知数量的值而创建的:
TYPE array_text IS TABLE OF VARCHAR2 (50);
因此他们可以声明一个变量,例如:
myValues in array_text;
并稍后以这种方式使用它:
myValues(1) := 'VALUE1';
myValues(2) := 'VALUE2';
...
因此,我一直在学习并尝试使用Postgres复制此行为,但直到现在我仍找不到正确的方法。我尝试创建一个像这样的复合类型:
CREATE TYPE array_text AS (
val varchar(50)
);
或
CREATE TYPE array_text AS (
v varchar(50)[]
);
但是我不能像使用原始方法那样使用它们,实际上我无法创建成功的测试。
如何获得这种行为或类似的东西?因此,我可以像在Oracle中一样设置和获取值,甚至计算其长度
答案 0 :(得分:4)
在Postgres中,它比在Oracle中简单得多-您无需定义集合类型。只需声明一个数组即可。
在Postgres中,TYPE array_text IS TABLE OF VARCHAR2 (50);
是text[]
的明智,最有效的替代方法。
要获取数组的长度,请使用cardinality()
。您不需要特殊的方法来扩展其容量,只需为所需的索引分配一个值即可。唯一的主要区别是,Postgres中没有缩小数组的简单方法。
declare
myValues text[];
num_values int;
begin
myValues[1] := 'VALUE1';
myValues[2] := 'VALUE2';
num_values := cardinality(myvalues); // yields 2
myValues[3] := 'VALUE3';
num_values := cardinality(myvalues); // yields 3
end;
要扩展答案:您还可以使用类似的表类型。因此,您无需定义中间的“表”集合类型,只需将表的类型用于数组即可。
create table person
(
id integer,
firstname text,
lastname text
);
然后您可以使用
do
$$
declare
people_list person[];
begin
people_list[1] := row(42, 'Arthur', 'Dent')::person;
raise notice 'Name %', people_list[1].firstname;
end;
$$
答案 1 :(得分:2)
postgres不允许具有未命名列的表(或复合类型)
与表数组不同的是,数组可以是多维的,也可以从[1]或[0]处开始,因此您可能需要检查输入格式是否正确(除非输入错误) 隐式导致错误)
CREATE TYPE array_text AS (
val varchar(50)[]
);
但这会创建一个具有一个属性的复合类型,该属性是一个数组...因此您需要使用.val
来访问该数组。
jasen=# do $$
declare a array_text;
begin
a.val[0]='won';
a.val[1]='too';
raise notice 'len=%',array_length(a.val,1); end;
$$;
NOTICE: len=2
DO
但是如果您在线声明数组,则可以使用简单的名称。
jasen=# do $$
declare a varchar(50)[];
begin
a[5]='eigh';
a[6]='bee';
raise notice 'len=%',array_length(a,1); end;
$$;
NOTICE: len=2
DO