1

I want to create twodimensional array in PL/pgSQL.

I have found example like this: myarray1 INT[2][2]:=array[[NULL,NULL],[NULL,NULL]];

but in my case I don't know an array of the table when I create table because the data are read from select query. How I can declare dynamic array ?


I ask in another way. In Oracle I can declare:

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

This is correspondent to RECORD is plpsql.

And then in Oracle I can declared

CREATE OR REPLACE TYPE MY_TYPE_MY_TYPES IS
table of MY_TYPE;

So I can store my result of select query in type of types which is just two-dimensional table. And I don't have to know number of rows returned by select query.

How I can acomplish this in plpsql ?

Thanks

0

3 Answers 3

1

in PostgreSQL, all types -including user defined ones- has respective array types.

so if you declare a composite type, you'll have an array type as well. you can find info about composite types here: https://www.postgresql.org/docs/current/static/rowtypes.html

here's an example:

1) create a new composite type

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

2) demonstrate array presentation. type of the result is "myType"[]

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

result is: {"(1,a)","(2,b)","(3,c)","(4,d)"}

3) unnesting "myType"[] array and returning as records

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

result is:

id | name
---|-----
 1 | a
 2 | b
 3 | c
 4 | d
Sign up to request clarification or add additional context in comments.

Comments

0

You don't have to specify the size of arrays when you declare them:

myarray1 int[][];

but note that 2-dimensional arrays 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

However you can assign another array to this variable:

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

Comments

0

I answer in another way :)

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.