2014-04-01 2 views
3

Можем ли мы использовать инструкцию SELECT в условном выражении CASE в функции?
Я выполнил следующую функцию для выполнения вышеуказанной задачи.PostgreSQL: Как использовать инструкцию SELECT в выражении CASE в функции?

Пример: У меня есть функция, которая используется для отображения таблицы, содержащей некоторые строки.

create or replace function test(n integer) 
returns table (name text,city text) as 
$body$ 
begin 
    case n when 1 then 
    select * from table1 

    when 2 then 
    select * from table2 

    when 3 then 
    select * from view1 

    end; 
end; 
$body$ 
language plpgsql; 

--Calling функция

select * from test(1); 
/*have to show details of table1*/ 

select * from test(2); 
/*have to show details of table2*/ 

select * from test(3); 
/*have to display details of view1*/ 

ответ

2

На самом деле, есть plpgsql CASE statement, не следует путать с SQL CASE expression:

CREATE OR REPLACE function test(n integer) 
    RETURNS TABLE (name text, city text) AS 
$func$ 
BEGIN 

CASE n 
WHEN 1 THEN 
    RETURN QUERY SELECT t.name, t.city FROM table1 t; 
WHEN 2 THEN 
    RETURN QUERY SELECT t.foo, t.bar FROM table2 t; 
WHEN 3 THEN 
    RETURN QUERY SELECT t.bar, t.bamm FROM view1 t; 
END CASE; 

END 
$func$ LANGUAGE plpgsql; 
  • Если объявить функцию RETURNS TABLE (name text, city text), то ваши ЗЕЬЕСТЫ должны иметь список столбцов с соответствующими типами.
    Если с другой стороны вы хотите SELECT *, объявите функцию RETURNS SETOF table1 соответственно.

  • При присвоении имен столбцам типа возврата эти переменные видны в теле функции. Обязательно укажите имена столбцов, которые будут конфликтующими с теми же именами. Итак, t.name вместо name.

  • Имена столбцов из запросов внутри функции не видны снаружи. Только объявленный тип возврата. Таким образом, имена не должны совпадать, а только типы данных.

В любом случае, я предлагаю, чтобы упростить вещи:

CREATE OR REPLACE function test(n integer) 
    RETURNS SETOF table1 AS 
$func$ 

SELECT * FROM table1 t WHERE n = 1 
UNION ALL 
SELECT * FROM table2 t WHERE n = 2 
UNION ALL 
SELECT * FROM view1 t WHERE n = 3; 

$func$ LANGUAGE sql; 

Тот же результат. Так же быстро. Функция SQL или PL/pgSQL является вопросом вкуса и некоторых других деталей. PL/pgSQL, вероятно, быстрее для автономных вызовов. SQL легче встраивается.

+0

Большое вам спасибо. Здесь немного путаницы. UNION ALL нужно, чтобы все столбцы были одинаковыми, но когда я хочу отобразить таблицу с другим столбцом, возможно ли это здесь? – Meem

+0

@Meem: * число * столбцов и их * типы дат * должны совпадать (или автоматический подбор возможен между близкими типами). Или вам нужно заполнить константы и бросить, чтобы они соответствовали друг другу. То же самое верно для функции. Для запроса 'UNION' используются только имена первого этапа, имена на последующих этапах запроса UNION не являются несущественными. Для этой функции используются только имена объявленного типа «RETURN». –

+0

О! хорошо. – Meem

2

Для этого вам нужно IF заявление и RETURN QUERY, например

create or replace function test(n integer) 
returns table (name text,city text) as 
$body$ 
begin 
    IF n = 1 THEN 
     RETURN QUERY select * from table1; 
    ELIF n = 2 THEN 
     RETURN QUERY select * from table2; 
    ELIF n = 3 THEN 
     RETURN QUERY select * from view1; 
    END IF; 
end; 
$body$ 
language plpgsql; 

Это очень странная вещь, которую нужно делать.

+0

Еще один вопрос, если я хочу показать строки таблицы2, которые имеют другое имя столбца сверху таблицы возврата, а затем, как отобразить это. – Meem

+0

Пожалуйста, задайте новый вопрос, если вы хотите спросить что-то еще; Stack Overflow пытается оставаться одной важной темой для каждого вопроса. –

+0

Хорошо позаботится об этом. – Meem

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