Цикл по составному массиву в plpgsql - PullRequest
0 голосов
/ 15 сентября 2018

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

Я несколько дней пытался написать код и сослаться на несколько ресурсов в сети, но это не сработало. Может ли кто-нибудь помочь в этом.Вот код, даже первая инициализация не работает, поэтому у меня нет кода для остальной части требования (для итерации после инициализации)

CREATE TYPE temp_n_inv_item AS (
    name            text,
    supplier_id     integer,
    price           numeric
);



CREATE OR REPLACE function temp_n_bulk_load2()
returns void
as
$$
declare
   v_t temp_n_inv_item[]; 


BEGIN


      v_t[1] := ARRAY ['Item1',1,10];
      v_t[2] := ARRAY ['Item2',2,20];
      v_t[3] := ARRAY ['Item3',3,30];


 --  raise notice 'first array % ', v_t[1];
--raise notice 'first array % ', v_t[2];
--raise notice 'first array % ', v_t[3];

--iterate though each of the v_t array in a loop 

null; --added as a temporary placeholder 

END;
$$
language plpgsql;

--select temp_n_bulk_load2()

С уважением, DbuserN

ОБНОВЛЕНИЕ Удивительно, но после публикации вопроса я увидел одну ссылку, и назначение теперь работает, но я пытаюсь изменить тип возвращаемого значения на массив, который не работает (что является дополнительной проблемой), хотя назначение исправленотеперь, как показано ниже, но ошибка, показанная ниже: «ОШИБКА: невозможно вернуть несоставное значение из функции, возвращающей составной тип» * Исправленный код :

CREATE OR REPLACE function temp_n_bulk_load2()
returns temp_n_inv_item
as
$$
declare
   v_t temp_n_inv_item[]; 


BEGIN


      v_t[1] := row ('Item1',1,10);
      v_t[2] := row ('Item2',2,20);
      v_t[3] := row ('Item3',3,30);


  raise notice 'first array % ', v_t[1];
raise notice 'first array % ', v_t[2];
raise notice 'first array % ', v_t[3];

--iterate though each of the v_t array in a loop 

null; --added as a temporary placeholder 
return v_t;

END;
$$
language plpgsql;

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

PLpgSQL имеет специальный оператор для итерации по массиву. Для больших массивов это намного эффективнее (не слишком важно для маленьких массивов):

create type tp as (a int, b int);

do $$
declare a tp[];
          r record;
begin
  /* composite array initialization */
  a = array[(1,2),(3,4),(5,6)];

  /* iterate over a array */
  foreach r in array a
  loop
    raise notice '% % %', r, r.a, r.b;
  end loop;
end;
$$;

NOTICE:  (1,2) 1 2
NOTICE:  (3,4) 3 4
NOTICE:  (5,6) 5 6
DO

Не бойтесь читать документацию .

0 голосов
/ 15 сентября 2018

Здесь вы создаете массив типа данных, который вы сгенерировали, используя

CREATE TYPE temp_n_inv_item AS (
    name            text,
    supplier_id     integer,
    price           numeric
);

Так что просто верните массив типа данных как temp_n_inv_item[].

CREATE OR REPLACE FUNCTION adm.temp_n_bulk_load2()
  RETURNS boolean AS
$BODY$
declare
   v_t temp_n_inv_item[]; 


BEGIN

/*CREATE TYPE temp_n_inv_item AS (
    name            text,
    supplier_id     integer,
    price           numeric
);*/
      v_t[1] := row ('Item1',1,10);
      v_t[2] := row ('Item2',2,20);
      v_t[3] := row ('Item3',3,30);


raise notice 'first array % ', v_t[1];
raise notice 'first array % ', v_t[2];
raise notice 'first array % ', v_t[3];

--iterate though each of the v_t array in a loop 
//updated
  FOR cnt in 1..(array_length(v_t,1))
            LOOP
Raise notice ' array value % ', v_t[cnt];

 END LOOP;

return true;

END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

Надеюсь, это решит вашу проблему.

...