PostgreSQL plpgsql。如何扩展二维数组的第二维?
Postgresql plpgsql. How to expand the second dimension of a two-dimensional array?
下午好。
如何通过标准的方式将二维数组的第二维进行扩容?
数组的大小是事先不知道的,所以 array_fill (null :: text, array [2,3]) 不适用。
我用标准“||”扩展了第一个维度。
实验代码:
DO
$$declare
p_StrArr text[][];
begin
-- p_StrArr:=array[['a1', 'b1', 'c1'], ['a2', 'b2', 'c2'] ];
-- p_StrArr:=array_fill(null::text, array[2,3]);
p_StrArr[1][1]:='a1';
p_StrArr:=p_StrArr || array['a2'];
p_StrArr:=p_StrArr || array['a3'];
-- if you uncomment, then
-- ERROR: array subscript out of range
-- p_StrArr[1][2]:='b1';
raise notice 'p_Str=%', p_StrArr;
raise notice 'p_Str=%', p_StrArr[1][1];
raise notice 'p_Str=%', p_StrArr[2][1];
raise notice 'c1=%', array_length(p_StrArr,1);
raise notice 'c2=%', array_length(p_StrArr,2);
END$$;
通过临时数组的解决方案对我来说似乎是资源密集型的:
DO
$$declare
p_StrArr text[][];
p_TmpArr text[][];
begin
p_StrArr:=array[['a1', 'b1', 'c1'], ['a2', 'b2', 'c2'] ];
raise notice 'p_Str=%', p_StrArr;
p_TmpArr:=array_fill(null::text,
array[array_length(p_StrArr,1),array_length(p_StrArr,2)+1]);
for i in 1..array_length(p_StrArr,1) loop
for j in 1..array_length(p_StrArr,2) loop
p_TmpArr[i][j]:=p_StrArr[i][j];
end loop;
end loop;
p_StrArr:=p_TmpArr;
p_StrArr[1][4]:='d1';
raise notice 'p_Str=%', p_StrArr;
raise notice 'c1=%', array_length(p_StrArr,1);
raise notice 'c2=%', array_length(p_StrArr,2);
END$$;
有标准方法吗?
没有任何用于扩展和数组的内置功能(您记住,数组在任何时候都必须是矩形的)。我觉得有两种可能,具体怎么做:
- 基于
foreach slice
子句的解决方案:
DO
postgres=# do $$
declare
a int[];
b int[];
x int[];
begin
a := array[[10,20],[30,40]];
b := '{}';
foreach x slice 1 in array a
loop
b := b || array[x || NULL::int];
end loop;
raise notice 'b %', b;
end;
$$;
NOTICE: b {{10,20,NULL},{30,40,NULL}}
DO
- 在Postgres 14(下个月发布)中,你可以做丰富的数组赋值:
postgres=# do $$
declare
a int[];
b int[];
begin
a := array[[10,20],[30,40]];
b := array_fill(NULL::int, array[2,3]);
b[1:2][1:2] := a;
raise notice 'a = %', a;
raise notice 'b = %', b;
end;
$$
;
NOTICE: a = {{10,20},{30,40}}
NOTICE: b = {{10,20,NULL},{30,40,NULL}}
DO
下午好。 如何通过标准的方式将二维数组的第二维进行扩容? 数组的大小是事先不知道的,所以 array_fill (null :: text, array [2,3]) 不适用。 我用标准“||”扩展了第一个维度。 实验代码:
DO
$$declare
p_StrArr text[][];
begin
-- p_StrArr:=array[['a1', 'b1', 'c1'], ['a2', 'b2', 'c2'] ];
-- p_StrArr:=array_fill(null::text, array[2,3]);
p_StrArr[1][1]:='a1';
p_StrArr:=p_StrArr || array['a2'];
p_StrArr:=p_StrArr || array['a3'];
-- if you uncomment, then
-- ERROR: array subscript out of range
-- p_StrArr[1][2]:='b1';
raise notice 'p_Str=%', p_StrArr;
raise notice 'p_Str=%', p_StrArr[1][1];
raise notice 'p_Str=%', p_StrArr[2][1];
raise notice 'c1=%', array_length(p_StrArr,1);
raise notice 'c2=%', array_length(p_StrArr,2);
END$$;
通过临时数组的解决方案对我来说似乎是资源密集型的:
DO
$$declare
p_StrArr text[][];
p_TmpArr text[][];
begin
p_StrArr:=array[['a1', 'b1', 'c1'], ['a2', 'b2', 'c2'] ];
raise notice 'p_Str=%', p_StrArr;
p_TmpArr:=array_fill(null::text,
array[array_length(p_StrArr,1),array_length(p_StrArr,2)+1]);
for i in 1..array_length(p_StrArr,1) loop
for j in 1..array_length(p_StrArr,2) loop
p_TmpArr[i][j]:=p_StrArr[i][j];
end loop;
end loop;
p_StrArr:=p_TmpArr;
p_StrArr[1][4]:='d1';
raise notice 'p_Str=%', p_StrArr;
raise notice 'c1=%', array_length(p_StrArr,1);
raise notice 'c2=%', array_length(p_StrArr,2);
END$$;
有标准方法吗?
没有任何用于扩展和数组的内置功能(您记住,数组在任何时候都必须是矩形的)。我觉得有两种可能,具体怎么做:
- 基于
foreach slice
子句的解决方案:
DO
postgres=# do $$
declare
a int[];
b int[];
x int[];
begin
a := array[[10,20],[30,40]];
b := '{}';
foreach x slice 1 in array a
loop
b := b || array[x || NULL::int];
end loop;
raise notice 'b %', b;
end;
$$;
NOTICE: b {{10,20,NULL},{30,40,NULL}}
DO
- 在Postgres 14(下个月发布)中,你可以做丰富的数组赋值:
postgres=# do $$
declare
a int[];
b int[];
begin
a := array[[10,20],[30,40]];
b := array_fill(NULL::int, array[2,3]);
b[1:2][1:2] := a;
raise notice 'a = %', a;
raise notice 'b = %', b;
end;
$$
;
NOTICE: a = {{10,20},{30,40}}
NOTICE: b = {{10,20,NULL},{30,40,NULL}}
DO