Запрос на отчет о возврате - PostgreSQL - PullRequest
0 голосов
/ 17 апреля 2020

У меня есть этот вопрос, я выполнял некоторую миграцию с SQL Сервера на PostgreSQL 12.

Сценарий, который я пытаюсь выполнить sh:

Функция должен иметь инструкцию RETURN, будь то SETOF 'tableType' или RETURN TABLE (некоторое количество столбцов)

Тело начинается с количества записей, если не найдено записей на основе входных параметров, тогда просто Возвращает ноль (0), иначе возвращает полный набор записей, определенный в операторе RETURN.

Эквивалентная часть в SQL Server или Oracle: Они могут просто поместить инструкцию SELECT внутрь Процедура для выполнения sh этого. Но это довольно сложно в случае PostgreSQL.

Любое предложение, пожалуйста.

Что я мог бы сделать sh до сих пор - если не найдено ни одной записи, он просто вернется NULL, возможно, используется PERFORM, или может быть выбрано NULL в качестве имени столбца для возвращаемых столбцов tableType.

Я надеюсь, что все ясно!

То, что я хочу, выглядит примерно так -

================================================ ============

CREATE OR REPLACE FUNCTION public.get_some_data(
    id integer)
    RETURNS TABLE ( id_1 integer, name character varying )

    LANGUAGE 'plpgsql'



AS $BODY$

 DECLARE 

 p_id alias for $1;
 v_cnt integer:=0;

BEGIN

    SELECT COUNT(1) FROM public.exampleTable e
    WHERE id::integer = e.id::integer;

    IF v_cnt= 0 THEN
        SELECT 0;
    ELSE

    SELECT
       a.id, a.name
        public.exampleTable a 
        where a.id = p_id;
END;
$BODY$;

Ответы [ 2 ]

1 голос
/ 17 апреля 2020

Если вы просто хотите вернуть набор из одной таблицы, использование returns setof some_table действительно самый простой способ. Самая базовая c SQL функция для этого будет:

create function get_data()
   returns setof some_table
as
$$
  select * 
  from some_table;
$$
language sql;

PL / pg SQL, на самом деле нет необходимости помещать оператор SELECT в функцию, но если вам нужно для других целей вам нужно использовать RETURN QUERY в функции PL / pg SQL:

create function get_data()
   returns setof some_table
as
$$
begin
  return query
    select * 
    from some_table;
end;
$$
language plpgsql;

Функция с точностью до one возвращаемого типа. У вас не может быть функции, которая иногда возвращает целое число, а иногда возвращает тысячи строк с дюжиной столбцов.

Единственное, что вы можете сделать, если вы настаиваете на возвращении что-то , примерно так:

create function get_data()
   returns setof some_table
as
$$
begin
  return query
    select * 
    from some_table;

  if not found then  
    return query 
      select (null::some_table).*;
  end if;
end;
$$
language plpgsql;

Но я бы посчитал вышеупомянутое крайне уродливым и запутанным (не сказать глупо) решение. Я, конечно, не позволю этому пройти через проверку кода.


вызывающая сторона функции может проверить, было ли что-то возвращено так же, как я реализовал этот уродливый хак: check переменная found после использования функции.

0 голосов
/ 18 апреля 2020

Еще один хак, чтобы получить как можно ближе к тому, что вы хотите. Но я повторю то, что вам сказали другие: Вы не можете делать то, что хотите напрямую . Тот факт, что MS SQL Server позволяет избавиться от плохого кодирования, не означает, что Postgres обязана это делать. Поскольку ссылка @a_horse_with_no_name подразумевает, что преобразование кода легко, после того, как вы сначала перенесете то, как вы думаете о проблеме. Самое близкое, что вы можете получить, это вернуть кортеж с идентификатором 0. Следующее является одним из способов.

create or replace function public.get_some_data(
    p_id integer)
    returns table ( id integer, name character varying )
    language plpgsql
as $$
declare 
    v_at_least_one boolean = false; 
    v_exp_rec record;
begin
    for v_exp_rec in  
        select a.id, a.name
          from public.exampletable a
        where a.id = p_id   
        union all
        select 0,null
    loop
        if v_exp_rec.id::integer > 0
        or (v_exp_rec.id::integer = 0 and not v_at_least_one)
        then 
            id = v_exp_rec.id;
            name = v_exp_rec.name;
            return next;
            v_at_least_one = true;
        end if;
    end loop ;    
    return;
end 
$$;

Но это все еще просто взлом, и предполагается, что в недопустимой строке с id = 0. Гораздо лучший подход для вызывающей маршрутизации состоит в том, чтобы проверить, что возвращает функция (в любом случае она должна делать это так или иначе), и позволить функции просто возвращать найденные данные вместо того, чтобы составлять данные. Это то, что сдвиг мышления . Таким образом, вы можете уменьшить эту функцию до простого оператора выбора:

create or replace function public.get_some_data2(
    p_id integer)
    returns table ( id integer, name character varying )
    language sql strict
as $$
   select a.id, a.name
     from public.exampletable a
    where a.id = p_id;   
$$;  

или другого предлагаемого решения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...