доступ к составным элементам массива plpgsql

У меня есть массив пользовательских составных типов данных. Мне нужно выполнить некоторые манипуляции с элементами массива в функции plpgsql, но я не понимаю синтаксис для доступа к отдельным элементам. Любая помощь приветствуется. Ниже вставлена ​​упрощенная версия кода.

CREATE TYPE playz AS(
                     a integer,
                     b numeric,
                     c integer,
                     d numeric);

CREATE OR REPLACE FUNCTION playx(OUT mod playz[]) AS $$
BEGIN
   FOR i in 1..5 LOOP
       mod[i].a = 1;
       mod[i].b = 12.2;
       mod[i].c = 1;
       mod[i].d = 0.02;

   END LOOP;
END;
$$ LANGUAGE plpgsql;

Я получаю следующую ошибку, когда пытаюсь выполнить это.

ОШИБКА: синтаксическая ошибка в или рядом с "." СТРОКА 5: mod[i].a = 1;

Я использую Постгрес 9.2.


person let_there_be_light    schedule 18.08.2016    source источник


Ответы (2)


Левые выражения должны быть довольно простыми в PLpgSQL. Комбинация массива и составного типа не поддерживается. Вы должны установить значение составного типа, а затем это значение присвоить массиву.

CREATE OR REPLACE FUNCTION playx(OUT mod playz[]) AS $$
DECLARE r playz;
BEGIN
  FOR i in 1..5 LOOP
    r.a = 1;
    r.b = 12.2;
    r.c = 1;
    r.d = 0.02;
    mod[i] = r;
  END LOOP;
END;
$$ LANGUAGE plpgsql;

Возможен ярлык:

CREATE OR REPLACE FUNCTION public.playx(OUT mod playz[])
LANGUAGE plpgsql
AS $function$
BEGIN
  FOR i in 1..5 LOOP
    mod[i] = ROW(1, 12.2, 1, 0.02);
  END LOOP;
END;
$function$;
person Pavel Stehule    schedule 19.08.2016
comment
Вы можете подтвердить свое заявление о том, что задание не поддерживается, добавив ссылку на документы - person Julius Tuskenis; 27.04.2021
comment
@JuliusTuskenis — эта старая проблема должна быть исправлена ​​в Postgres 14. - person Pavel Stehule; 27.04.2021

Следуя ответу Павла выше, вы можете еще больше упростить это до простой функции sql (что дает вам лучшую прозрачность планировщика и проверку типов), если вы сделаете что-то вроде:

CREATE OR REPLACE FUNCTION playx(OUT mod playz[]) AS $$
select array_agg(row(1, 12.2, 1, 0.02)::playz) 
  from generate_series(1, 5) 
 $$ LANGUAGE sql;

Обычно я стараюсь использовать простые функции SQL, когда могу (хотя pl/pgsql занимает очень важную нишу).

person Chris Travers    schedule 20.08.2016