KES*_*ESO 2 sql oracle postgresql plpgsql
我目前正在将一些过程从 Oracle 迁移到 Postgres,这些过程使用的类型是为处理未知数量的值而创建的:
TYPE array_text IS TABLE OF VARCHAR2 (50);
Run Code Online (Sandbox Code Playgroud)
所以他们可以声明一个变量,如:
myValues in array_text;
Run Code Online (Sandbox Code Playgroud)
稍后以这种方式使用它:
myValues(1) := 'VALUE1';
myValues(2) := 'VALUE2';
...
Run Code Online (Sandbox Code Playgroud)
所以我一直在学习并尝试使用 Postgres 复制这种行为,但直到现在我找不到合适的方法。我尝试创建一个复合类型,如:
CREATE TYPE array_text AS (
val varchar(50)
);
Run Code Online (Sandbox Code Playgroud)
或者
CREATE TYPE array_text AS (
v varchar(50)[]
);
Run Code Online (Sandbox Code Playgroud)
但是,我无法像使用原始版本那样使用它们,实际上我无法创建成功的测试。
我怎么能得到这种行为或类似的东西?所以我可以设置和获取值,甚至像在 Oracle 中一样计算它的长度
在 Postgres 中它比在 Oracle 中简单得多——您不需要定义集合类型。只需声明一个数组。
明智和最有效的替代方法TYPE array_text IS TABLE OF VARCHAR2 (50);是text[]在 Postgres 中。
要获取数组的长度,请使用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;
Run Code Online (Sandbox Code Playgroud)
扩展答案:您也可以使用这样的表类型。所以你不需要定义一个中间的“表”集合类型,只需要将表的类型用于数组。
create table person
(
id integer,
firstname text,
lastname text
);
Run Code Online (Sandbox Code Playgroud)
然后你可以使用
do
$$
declare
people_list person[];
begin
people_list[1] := row(42, 'Arthur', 'Dent')::person;
raise notice 'Name %', people_list[1].firstname;
end;
$$
Run Code Online (Sandbox Code Playgroud)