OUT'ы, SETOF of record'ы и все-все-все

VanillaNInja
Дата: 13.12.2014 21:10:36
Ребята, помогите разобраться, как запустить сие чудо:
CREATE OR REPLACE FUNCTION "public"."test"(int4, json)
  RETURNS SETOF "pg_catalog"."record" AS $BODY$ 
DECLARE
rb boolean;
vld text;
msg text;
clmn_name text;
v text;
codes text[];
msg_param text;
BEGIN
 codes := ARRAY 
    [
      'code1'
    ];
  for v in select unnest(codes)

  loop
        IF ((SELECT NULLIF(json_extract_path_text($2, 'first_param'), '') IS NOT NULL)  AND 
             (SELECT NULLIF(json_extract_path_text($2, 'sec_param'), '') IS NOT NULL)) THEN
                    IF (json_extract_path_text($2, 'first_param')='2' and json_extract_path_text($2, 'sec_param')<>'9') THEN
                                rb := true; vld :='code1'; 
                                msg := 'hi there!';
                clmn_name := '1';
                    RETURN NEXT rb, vld, msg, clmn_name;    
                END IF; 
ELSE    

            end if;

      end loop;
END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE COST 100
 ROWS 1000
;


когда пытаюсь так:
[SQL]select * from test(0::integer, '{"first_param":"2", "sec_param":"5"}'::json)

[Err] ERROR:  a column definition list is required for functions returning "record"



Когда так:
[SQL]
select * from test(0::integer, '{"first_param":"2", "sec_param":"5"}'::json) t1(rb boolean, vld text, msg text, clmn_name text)

[Err] ERROR:  query "SELECT rb, vld, msg, clmn_name" returned 4 columns
CONTEXT:  PL/pgSQL function test(integer,json) line 24 at RETURN NEXT


Даже пытался первую строчку заменить на
CREATE OR REPLACE FUNCTION "public"."test"(IN int4, IN json, OUT rb bool, OUT vld text, OUT msg text, IN clmn_name text)

но в этом случае - не понимаю, как ее вызвать, ибо
[SQL]select * from test(0::integer, '{"first_param":"2", "sec_param":"5"}'::json)

[Err] ERROR:  function test(integer, json) does not exist
LINE 1: select * from test(0::integer, '{"first_par...

помогите разобраться, а? :-)
/\/\/\/\/\/\
Дата: 13.12.2014 21:35:59
VanillaNInja,

Вам английским языком говорят: Вы пытаетесь вернуть 4 колонки, хотя должны вернуть только одну величину типа "запись".

То есть Вы пытаетесь вернуть не то, что обязались согласно объявлению функции.
Да и в объявлении функции фигня какая-то написана.

Должна быть и еще одна ошибка, так как между ELSE и END IF нет ни одного оператора.

Итого:
1. Разберитесь, что Вы хотите получить на выходе функции. Прямо сейчас это не понятно.
2. Что заказали, то и верните в теле.
VanillaNInja
Дата: 13.12.2014 21:48:18
/\/\/\/\/\/\,

чтрочка с else - там лишняя. Забыл удалить следы тестироваия :-/

Хочу получить рекорд с 4мя полями. Ну то есть не обязательно рекорд. Но четыре поля. Я об этом и пытаюсь сообщить кусочком: t1(rb boolean, vld text, msg text, clmn_name text) Я же ей указываю те 4 поля, которые надо вернуть. Но она мне отвечает "Ошибка, возвращаю 4 поля"
VanillaNInja
Дата: 13.12.2014 21:54:24
точнее, хочется получить как раз некоторое число рекордов с этими 4мя полями.
/\/\/\/\/\/\
Дата: 13.12.2014 22:23:52
VanillaNInja,

Хочется - так делайте!

Прочитайте RTFM. Там все написано.

Кстати, у Вас на удивление мерзкий стиль написания кода.
VanillaNInja
Дата: 13.12.2014 22:28:55
А со стилем что не так?
SmeL_md
Дата: 13.12.2014 23:06:46
VanillaNInja
А со стилем что не так?
если (NULL сделай пустой текст и если после этого не NULL ) то сделай подобную проверку
/\/\/\/\/\/\
Дата: 13.12.2014 23:20:47
VanillaNInja,

Много ненужных слов, которые уводят в сторону от главного смысла.
Так пишут тупые роботы из встроенных помогалок.

Расскажите зачем:
-- Берете наименование схемы и наименование функции в кавычки.
-- Зачем указываете наименование схемы. (Особенно мерзко смотрится "pg_catalog"."record")
-- Зачем указываете параметры в конце функции, которые можно и не указывать?
-- Пишете какие-то странные типы
-- Не пользуетесь алиасами, а обращаетесь к параметрам по номеру.

Ну и форматирование отсутствует.

Укажите пример из официального RTFM для поддерживаемой версии PG, где пишется именно так.
VanillaNInja
Дата: 13.12.2014 23:28:31
/\/\/\/\/\/\,

На самом деле, как образцом кода было то, как пишут у меня в компании. Никогда не задумывался что это плохо :-/
Спасибо за советы. Будем исправляться :-)
VanillaNInja
Дата: 13.12.2014 23:30:13
SmeL_md,

если вы про строчку
     IF ((SELECT NULLIF(json_extract_path_text($2, 'first_param'), '') IS NOT NULL) 


То я не представляю как это элегантно сделать, избежав 2х проверок. Результат json_extract_path_text может быть как ' ' так null