繁体   English   中英

PL/pgSQL 中的动态多维数组

[英]dynamic multidimensional array in PL/pgSQL

我想在 PL/pgSQL 中创建二维数组。

我找到了这样的例子: myarray1 INT[2][2]:=array[[NULL,NULL],[NULL,NULL]];

但在我的情况下,我在创建表时不知道表的数组,因为数据是从选择查询中读取的。 我如何声明动态数组?


我换个方式问。 在 Oracle 中,我可以声明:

CREATE OR REPLACE TYPE MY_TYPE AS OBJECT
(
  var1 VARCHAR(20),
  ...
)
...

这个对应RECORD的是plpsql。

然后在 Oracle 中我可以声明

CREATE OR REPLACE TYPE MY_TYPE_MY_TYPES IS
table of MY_TYPE;

所以我可以将选择查询的结果存储在类型类型中,这只是二维表。 而且我不必知道选择查询返回的行数。

我如何在 plpsql 中完成这个?

谢谢

在 PostgreSQL 中,所有类型——包括用户定义的类型——都有各自的数组类型。

所以如果你声明一个复合类型,你也会有一个数组类型。 您可以在此处找到有关复合类型的信息: https : //www.postgresql.org/docs/current/static/rowtypes.html

这是一个例子:

1) 创建一个新的复合类型

CREATE TYPE "myType" AS ( "id" INT, "name" VARCHAR );

2) 演示数组表示。 结果的类型是“myType”[]

SELECT
    ARRAY_AGG( v::"myType" ) AS v
FROM
    ( VALUES ( 1, 'a' ), ( 2, 'b' ), ( 3, 'c' ), ( 4, 'd' ) ) AS v

结果是:{"(1,a)","(2,b)","(3,c)","(4,d)"}

3) 取消嵌套 "myType"[] 数组并作为记录返回

SELECT ( UNNEST( '{"(1,a)","(2,b)","(3,c)","(4,d)"}'::"myType"[] ) ).*

结果是:

id | name
---|-----
 1 | a
 2 | b
 3 | c
 4 | d

声明数组时不必指定数组的大小:

myarray1 int[][];

但请注意,二维数组不会像一维数组那样增长

create or replace function testfunc() returns void language plpgsql as $$
declare
  myarray1 int[][];
begin
  for i in 1..2 loop
    for j in 1..2 loop
      raise notice '% %', i, j;
      myarray1[i][j] := 1;
    end loop;
  end loop;
end$$;
select testfunc();

NOTICE:  1 1
NOTICE:  1 2
ERROR:  array subscript out of range
CONTEXT:  PL/pgSQL function "testfunc" line 7 at assignment

但是,您可以为该变量分配另一个数组:

create or replace function testfunc() returns void language plpgsql as $$
declare
  myarray1 int[][];
begin
  myarray1 := array[[NULL,NULL],[NULL,NULL]];
  for i in 1..2 loop
    for j in 1..2 loop
      raise notice '% %', i, j;
      myarray1[i][j] := 1;
    end loop;
  end loop;
end$$;
select testfunc();
NOTICE:  1 1
NOTICE:  1 2
NOTICE:  2 1
NOTICE:  2 2

我以另一种方式回答:)

create view v as
select * 
from (values (1, 'Adam'), (2, 'Bob'), (3, 'Chris')) as foo(id, forename);

create or replace function f() returns text language plpgsql as $$
declare
  myarray1 v[];
begin
  select array_agg(row(id, forename)) from v into myarray1;
  return myarray1::text;
end$$;

select f();

                 f
------------------------------------
 {"(1,Adam)","(2,Bob)","(3,Chris)"}
(1 row)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM