2015-10-13 2 views
0

Я занят попыткой переписать хранимую процедуру Informix для базы данных PostgreSQL , и я застрял на чем-то, что, вероятно, вполне очевидно для всех, кто знает PostgreSQL.Postgresql plpgsql несколько строк цикла

У меня есть SQL скрипт следующего образом

-- ensure type and function get created 
drop type if exists tp_users cascade; 
drop function if exists sp_cmplist(); 

-- create type 
create type tp_users as (
    us_id  char(30), 
    us_status char(1) 
); 

create function sp_cmplist() 
    returns tp_users as $$ 
declare 
    lr_users tp_users; 
begin 

    for lr_users in 
     select users.us_id, users.us_status 
     from users 
    loop 
     return lr_users; 
    end loop; 

end 

$$ language 'plpgsql'; 

select sp_cmplist(); 

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

+0

Лучше всего подходит at: http://dba.stackexchange.com/ –

+0

Я пробовал администраторов баз данных com munity, но они закрыли меня такими вопросами, как это, заявив, что это недостаточно профессионально или что-то в этом роде. – Trent

+0

. Столбец-поток - хорошее место. plpgsql - это тема для разработчиков –

ответ

0

Этот код работает:

CREATE TABLE foo(a int); 
INSERT INTO foo VALUES(10),(20); 

CREATE OR REPLACE FUNCTION retfoo() 
RETURNS SETOF foo AS $$ 
BEGIN 
    RETURN QUERY SELECT * FROM foo; 
    RETURN; 
END; 
$$ LANGUAGE plpgsql; 

postgres=# SELECT * FROM retfoo(); 
┌────┐ 
│ a │ 
├────┤ 
│ 10 │ 
│ 20 │ 
└────┘ 
(2 rows) 

Время: 1.143 мс

0

я, возможно, ответил на мой собственный вопрос со следующим

drop type if exists tp_users cascade; 
drop function if exists sp_cmplist(); 

create type tp_users as (
    us_id  text, 
    us_status text, 
    lv_nothing text, 
    lv_cnt  int 
); 

create function sp_cmplist() 
    returns setof tp_users as $$ 
declare 
    lr_users tp_users; 
    lv_cnt  int; 
begin 

    lv_cnt := 0; 

    for lr_users in 
     select users.us_id, users.us_status 
     from users 
    loop 

     -- increment this counter for testing purposes 
     lv_cnt    := lv_cnt + 1; 

     lr_users.lv_nothing := 'yupy'; 
     lr_users.lv_cnt  := lv_cnt; 

     return next lr_users; 

    end loop; 

    return; 

end 

$$ language 'plpgsql'; 

select * from sp_cmplist(); 

это, кажется, работает отлично

+1

для этого запроса вам не нужен цикл 'for'. Он медленнее, чем 'RETURN QUERY SELECT use_id, us_status, 'yupy', row_number() over() FROM users;'. То, что можно решить простым запросом, должно решаться простым запросом. –

+0

Обычно я так делаю, когда возвращаемые переменные являются таблицей, но этот пример - только фиктивный запрос, настоящий запрос использует несколько отдельных выборок и сравнивает результаты и создает данные для возврата в цикле, I не думаю, что я смогу сделать это легко с одним выбором – Trent

Смежные вопросы