【问题标题】:dynamic multidimensional array in PL/pgSQLPL/pgSQL 中的动态多维数组
【发布时间】:2021-06-16 00:05:20
【问题描述】:

我想在 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 中完成这个?

谢谢

【问题讨论】:

    标签: sql postgresql multidimensional-array


    【解决方案1】:

    在 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
    

    【讨论】:

      【解决方案2】:

      declare them时不必指定数组的大小:

      myarray1 int[][];
      

      但请注意二维数组do not grow like 1-dimensional arrays:

      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
      

      【讨论】:

        【解决方案3】:

        我用另一种方式回答:)

        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)
        

        【讨论】:

          猜你喜欢
          • 2018-02-10
          • 2012-03-27
          • 2012-05-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-28
          • 2012-12-17
          • 1970-01-01
          相关资源
          最近更新 更多