динамический многомерный массив в PL / pgSQL - PullRequest
1 голос
/ 01 апреля 2011

Я хочу создать двумерный массив в PL / pgSQL.

Я нашел такой пример: myarray1 INT [2] [2]: = массив [[NULL, NULL], [NULL, NULL]];

но в моем случае я не знаю массив таблицы при создании таблицы, потому что данные читаются из запроса select. Как я могу объявить динамический массив?


Я спрашиваю по-другому. В 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;

Таким образом, я могу сохранить свой результат запроса select в типе типов, который является просто двумерной таблицей. И мне не нужно знать количество строк, возвращаемых запросом выбора.

Как мне это сделать в plpsql?

Спасибо

Ответы [ 3 ]

1 голос
/ 02 апреля 2011

Вам не нужно указывать размер массивов, когда вы объявляете их :

myarray1 int[][];

, но обратите внимание, что двумерные массивы не растут как 1-размерные массивы :

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
0 голосов
/ 11 мая 2017

в 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
0 голосов
/ 04 апреля 2011

отвечаю по-другому:)

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...