2017-01-14 4 views
0

Я хочу создать сохраненную функцию. Я хочу вернуть значение столбца или нулевое значение, когда запрос выбора выполняется, если данные найдены. Но я получаю синтаксическую ошибку. Как я могу решить эту проблему?Функция Postgres, возвращающая аргументы или нулевое значение

Ошибка

ERROR: syntax error at or near "do" LINE 6: do $$

Мой код:

CREATE OR REPLACE FUNCTION tuvimer.getProjectTypes(
    OUT id integer, 
    OUT name character varying) 
RETURNS SETOF record AS 
do $$ 
IF EXISTS (select t.id, t.name from tuvimer.tuvi_project_category t) THEN 
    RETURN t.id, t.name; 
ELSE 
    RETURN 0; 
END IF; 
$$ 
LANGUAGE plpgsql 
+1

Что именно вы пытаетесь сделать? Помимо очевидного недействительного использования 'DO' (вам нужно« BEGIN », см. [Руководство] (https://www.postgresql.org/docs/current/static/plpgsql-control-structures.html#PLPGSQL- ЗАЯВЛЕНИЯ-ВОЗВРАЩЕНИЕ)), остальное тоже не имеет смысла. Вы не можете вернуть одно целое из функции, определенной для возврата таблицы. И вы не можете получить доступ к псевдониму 't' вне выбора внутри существующего. И вы вернете случайную строку из этой таблицы - для меня это не имеет смысла. –

+0

Я пытаюсь сделать, если select query return not null id и функция name name должна возвращать значения id и name. Если функция возврата запроса возвращает значение null, необходимо вернуть 0; – SezKo

+0

Вы не можете случайно возвращать разные типы результатов из разных мест в одной и той же функции. Пожалуйста, см. Мой ответ, объясняя, что это слишком много для комментария. Один вопрос: пытаетесь ли вы вернуть все строки из этой таблицы или конкретной? Если определенная строка, то ** которая ** одна. В вашем запросе нет предложения 'where'. –

ответ

2

do для анонимных PL/PgSQL блоков, а не для функций. В PL/PgSQL вам нужно begin ... end (на самом деле, что необходимо внутри блок DO, а)

Но это только исправить очевидную ошибку синтаксиса относительно неправильного использования DO, но он все равно не будет работать в течение нескольких причины:

Вы не можете просто вернуть t.id, t.name, как и в тот момент кода, которому вы не присвоили значения, - на самом деле псевдоним t не существует вне оператора select.

Проверка exists, похоже, не имеет никакого смысла. Он проверяет, есть ли в таблице по крайней мере одна строка, если нет никого, вы пытаетесь получить некоторые случайные значения из этой таблицы - не имеет смысла

Вы также можете вернуть только скалярное значение (0) из функция, заданная для возврата результата с двумя столбцами. Вам нужно вернуть хотя бы одну строку с двумя колонками.

Если бы у меня догадались: вы пытаетесь вернуть «фиктивный ряд», если ничего не найдено. В этом случае вы могли бы адаптировать this example from the manual

CREATE OR REPLACE FUNCTION tuvimer.getProjectTypes(
    OUT id integer, 
    OUT name character varying) 
RETURNS SETOF record AS 
$$ 
BEGIN --<< The BEGIN goes into the body 

return query select t.id, t.name from tuvimer.tuvi_project_category t; 

IF NOT FOUND THEN 
    -- return a dummy row 
    return query select 0, null::character varying; 
END IF; 

END; --<< And you need an END here 
$$ 
LANGUAGE plpgsql 

Unrelated, но: Я предпочитаю синтаксис returns table (id integer, name varchar) над returns setof record и определение столбцов как OUT параметров.

+0

Я использовал select * from tuvimer.getProjectTypes(); Я получаю ERROR: структура запроса не совпадает с результатом результата функции ДЕТАЛИ: Тип возвращаемого типа неизвестен не соответствует ожидаемому типу символов, отличающемуся в столбце 2. CONTEXT: функция PL/pgSQL tuvimer.getprojecttypes() строка 8 в RETURN QUERY – SezKo

+0

@SezKo : вам нужно указать значение фиктивной строки.См. Мое редактирование –

+0

Спасибо, что он работает :) – SezKo

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