2016-12-08 4 views
0

У меня есть хранимая процедура, такие как следующие:PL/PGSQL итерация через возвращенный тип

CREATE OR REPLACE FUNCTION public.sp_shared_asset_delete_by_id(
    "in_shared_asset_id" bigint, 
    "in_client_uuid" uuid) 
    RETURNS boolean AS 
$BODY$ 
declare 
"participant" cursor 
begin 
     "participant" is select * from get_all_participants("in_shared_asset_id"); 
     FOR row in "participant" 
     LOOP 
     --DELETE EACH PARTICIPANT 
     sp_participant_delete_by_id(row.participant_id, row.created_by_client); 
     END LOOP; 
    return true; 
end 
$BODY$ 
    LANGUAGE plpgsql VOLATILE SECURITY DEFINER 
    COST 100; 

get_all_participants ("in_shared_asset_id") возвращает setof "участник" запись.

Каков правильный способ перебора всех записей, возвращаемых вызовом get_all_participants? В настоящее время я получаю ошибку plsql «близко».

CREATE OR REPLACE FUNCTION public.get_all_partipants(in_shared_id bigint) 
    RETURNS SETOF participant AS 
$BODY$ 
begin 
    return query select participant.participant_id, 
         participant.shared_asset_id, 
         participant.participant_role_type, 
         participant.user_external_ref_uuid, 
         participant.user_first_name , 
         participant.user_last_name , 
         participant.user_email_address, 
         shared_asset.asset_external_ref_uuid uuid, 
         shared_asset.owner_external_ref_uuid uuid, 
         participant.deleted_timestamp 
       from participant 
       join shared_asset 
       on shared_asset.shared_asset_id = participant.shared_asset_id 
       where shared_asset.shared_asset_id = "in_shared_id" 
       and participant.deleted_timestamp is null; 

end 
$BODY$ 
    LANGUAGE plpgsql VOLATILE SECURITY DEFINER 
    COST 100 
    ROWS 1000; 
+0

Это не похоже на pl/sql. – OldProgrammer

+0

Что такое ** точное сообщение об ошибке, которое вы получаете? –

ответ

0

Вам даже не нужен курсор, но ваш синтаксис plsql выглядит довольно странно. Просто держите это просто.

CREATE OR REPLACE FUNCTION public.sp_shared_asset_delete_by_id(
"in_shared_asset_id" bigint, "in_client_uuid" uuid) 
RETURNS boolean IS 
DECLARE 
    row participant%ROWTYPE; 
BEGIN 

    FOR row IN(SELECT * FROM get_all_participants("in_shared_asset_id")) 
    LOOP 
    --DELETE EACH PARTICIPANT 
    sp_participant_delete_by_id(row.participant_id, row.created_by_client); 
    END LOOP; 
    RETURN TRUE; 

END; 
/
+0

Я пробовал ваше предложение, и я получаю следующее причину: org.postgresql.util.PSQLException: ERROR: переменная цикла цикла по строкам должна быть переменной записи или строки или списком скалярных переменных. Что это значит ? – XnaijaZ

+0

Привет @XnaijaZ, это означает, что ваша функция get_all_participants ("in_shared_asset_id") действительно не возвращает набор записей, как вы заявляли. Можете ли вы дважды проверить тип возврата или предоставить детали этой функции? – Nexus

+0

Я считаю, что вы используете синтаксис PSQL, а не PLSQL? – Nexus

0

Неверное определение курсора. Она должна быть прекращена с ;

К использование курсора вам нужно OPEN его.

Синтаксис "participant" is select *... неправильно (где в руководстве вы найдете , что)

Вы также не объявить переменную записи держа строку, возвращаемую курсором. Вы можете упростить, что не используя явный переменный курсор и просто loop over the query result

CREATE OR REPLACE FUNCTION public.sp_shared_asset_delete_by_id(
    "in_shared_asset_id" bigint, 
    "in_client_uuid" uuid) 
    RETURNS boolean AS 
$BODY$ 
declare 
    l_rec record; 
begin 
     "participant" is ; 
     FOR l_rec in select * from get_all_participants("in_shared_asset_id") 
     LOOP 
     --DELETE EACH PARTICIPANT 
     perform sp_participant_delete_by_id(l_rec.participant_id, l_rec.created_by_client); 
     END LOOP; 
    return true; 
end 
$BODY$ 
    LANGUAGE plpgsql VOLATILE SECURITY DEFINER 
    COST 100; 

Unrelated, но: get_all_partipants(in_shared_id bigint) может быть упрощен до простой функции SQL. Там не нужен PL/pgSQL.