2013-02-22 2 views
1

Я попытался создать эту функцию, но система возвращает «ошибку LOOP», и я не знаю, как вернуть 3 переменных одновременно. Я очень старался понять это, но нигде не нашел ответа.Функция Postgres End Loop и return error

CREATE OR REPLACE FUNCTION conta_relatos(fator_normativo integer, fator_determinativo integer) 
    RETURNS integer AS 
$BODY$ 
DECLARE 
    vinculos_encontrados RECORD; 
    rel_pri INT; 
rel_sec INT; 
rel_ref INT; 
no_item INT; 
tipo_relato TEXT; 
BEGIN 
    rel_pri := 0; 
    rel_sec := 0; 
    rel_ref := 0;  
FOR vinculos_encontrados IN SELECT * FROM "Vinculos" WHERE ("Vinculos"."Fator_Normativo" = Fator_Normativo AND "Vinculos"."Fator_Determinativo" = Fator_Determinativo) LOOP 
    no_item := vinculos_encontrados."Item"; 
SELECT "Fontes"."Tipo_Relato" INTO tipo_relato FROM "Fontes" WHERE "Fontes"."ID" = no_item; 
--IF tipo_relato = "1 - Relato Primário" THEN 
    rel_pri := rel_pri + 1; 
--ELSE IF tipo_relato = "2 - Relato Secundário" THEN 
    rel_sec := rel_sec + 1; 
--ELSE IF tipo_relato = "3 - Relato Referencial" THEN 
    rel_ref := rel_ref + 1; 
    --END IF; 
    END LOOP; 
    RETURN rel_pri, rel_sec, rel_ref; 
END; 
$BODY$ 
LANGUAGE plpgsql VOLATILE 
COST 100; 

ответ

2

Используйте OUT parameters, чтобы вернуть одну строку с несколькими столбцами. Тип RETURN не является обязательным в этом случае, я цитирую инструкцию here:

Когда есть OUT или INOUT параметров, положение RETURNS может быть опущен.

CREATE OR REPLACE FUNCTION conta_relatos(
    _fator_normativo integer 
    ,_fator_determinativo integer 
    ,OUT rel_pri integer 
    ,OUT rel_sec integer 
    ,OUT rel_ref integer 
    ) AS 
$func$ 
DECLARE 
    tipo_relato text; 
BEGIN 

rel_pri := 0; 
rel_sec := 0; 
rel_ref := 0; 

FOR tipo_relato IN 
    SELECT f."Tipo_Relato" 
    FROM "Vinculos" v 
    JOIN "Fontes" f ON f."ID" = v."Item" 
    WHERE v."Fator_Normativo" = _fator_normativo 
    AND v."Fator_Determinativo" = _fator_determinativo 
LOOP 
    CASE tipo_relato 
    WHEN '1 - Relato Primário' THEN 
     rel_pri := rel_pri + 1; 
    WHEN '2 - Relato Secundário' THEN 
     rel_sec := rel_sec + 1; 
    WHEN '3 - Relato Referencial' THEN 
     rel_ref := rel_ref + 1; 
    END CASE; 
END LOOP; 

-- No RETURN needed, OUT parameters are returned automatically. 

END 
$func$ LANGUAGE plpgsql; 

Вызов:

SELECT * FROM conta_relatos(1,2); 

я также в значительной степени упрощена вашу функцию. Среди прочих:

  • Используйте "Simple CASE" для своих заданий.
  • Упростите два запроса в одно соединение.

Вся функция может быть легко переписана как один оператор SQL.

+0

Большое спасибо Erwin! Ваше решение отлично работает! Вы мне очень помогаете, я новичок в Postgres. С наилучшими пожеланиями из Бразилии! – Britto

+0

Уважаемый Эрвин. Еще один вопрос: что мне нужно сделать, чтобы вставить функцию conta_relatos внутри сложного выбора, чтобы создать представление? – Britto

+0

Система сообщает мне, что запрос должен возвращаться только на столбец – Britto

2

Чтобы вернуть несколько значений в то же время, вы хотите, чтобы указать OUT параметры и изменить тип возвращаемого значения функции record. См. Документацию here. Обязательно вызовите функцию с помощью SELECT *, чтобы вернуть параметры в виде трех столбцов.

Пожалуйста, уточните свой вопрос, чтобы включить ошибку, которую вы получаете, и если я могу помочь, я обновлю этот ответ, чтобы обратиться к нему.

+0

Большое спасибо Скотту. С наилучшими пожеланиями от Бразилии – Britto