Зацикливание каждого элемента массива Postgresql - PullRequest
0 голосов
/ 05 октября 2018

У меня есть функция, в которой я хочу запустить цикл для каждого элемента массива.Я получаю строку ввода, например, «tab1 # tab2 # tab3» ... Каждый элемент строки должен быть разделен (на #), чтобы получить tab1, tab2, tab3 в myArray.Моя функция:

CREATE OR REPLACE FUNCTION funcA(
myUid integer,
mytable_name varchar,
state varchar)
RETURNS void AS

$BODY$


declare

TABarray varchar[];
indx int;

BEGIN  


    select REGEXP_REPLACE('{'||myTABLE_NAME||'}','#','','g') into TABarray;


    for indx in 1..array_length(TABarray, 1) loop

    execute 'update ' || TABarray(indx) || ' set CODE_STATO = ''' || state || ''' where uid = ' ||  myUid || 'and CODE_STATO <> ''N'' ';
    raise notice 'i: %', TABarray[ indx ];

    end loop;

    END; $BODY$
    LANGUAGE plpgsql stable

В результате я ожидаю 3 разбитых строки, таких как:

-tab1

-tab2

-tab3

Прямо сейчас myFunction print {tab1tab2tab3}.

   select oms_write_stato (10, 'tab1#tab2#tab3', '')

Что я делаю не так?

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 06 октября 2018

PL / pgSQL имеет для этой цели оператор FOREACH IN ARRAY:

Ваша задача может быть записана примерно так:

-- Don't use case mixed identifiers (prohibit camel notation)
create or replace function funca(uid integer,
                                 tablenames varchar,
                                 state varchar)
returns void as $$
declare tablename text;
begin
  foreach tablename in array string_to_array(tablenames, '#')
  loop
    execute format('update %I set code_stato = $1 where uid = $2 and code_state <>'N',
                   tablename)
      using state, uid;
  end loop;
end;
$$ language plpgsql;

Примечания:

  1. donне смешивайте верхние нижние символы в идентификаторах
  2. не смешивайте верхние / нижние ключевые слова - есть несколько вариантов - ключевые слова в верхнем регистре или все в нижнем регистре, но это плохо для чтения
  3. когда вы используете динамический SQL, затем санируйте данные, прежде чем использовать их в динамическом запросе - используйте функции quote_ident, quote_literal или функцию format с безопасными заполнителями и, когда это возможно, передайте с предложением USING.
  4. postgres имеет типы массивов - использование str1#str2#str3#str4 немного неясно в Postgres - используйте собственные массивы, такие как ARRAY['str1','str2','str3','str4'].
0 голосов
/ 05 октября 2018

Вы можете использовать string_to_array, чтобы разбить строку на массив.Кроме того, вы использовали () для ссылки на элементы индекса вместо []

CREATE OR replace FUNCTION funca( myuid integer, mytable_name varchar, state varchar) 
    returns void AS 
    $BODY$
    DECLARE 
    tabarray VARCHAR[];
    indx    int;
    BEGIN 
      SELECT string_to_array(mytable_name ,'#') 
      INTO   tabarray; 
      for indx IN 1..array_length(tabarray, 1) 
      LOOP 
     --check the o/p of this notice below to see if update statement is correct
     --raise notice '%', 'update ' || tabarray[indx] || ' set CODE_STATO = ''' || state || ''' where uid = ' || myuid || 'and CODE_STATO <> ''N'' ';
        execute 'update ' || tabarray[indx] || ' set CODE_STATO = ''' || state || ''' where uid = ' ||  myUid || ' and CODE_STATO <> ''N'' ';
      raise notice 'i: %', tabarray[ indx ]; 
    END LOOP;
    END;
 $BODY$ language plpgsql stable;
...