2012-05-23 2 views
3

Мне нужно вернуть динамически сгенерированный оператор select из функции plpgsql. Это то, что я до сих пор:Вернуть выбор из функции plpgsql

CREATE OR REPLACE FUNCTION qa_scf(cname character varying, tname character varying) 
RETURNS text AS 
$BODY$ 
BEGIN 
return '* from ' ||tname|| 'where ' ||cname ||' != ''AL'''; 
end; 
$BODY$ 
LANGUAGE plpgsql VOLATILE 
COST 100; 

Вызывающий, бежал из пакетного файла:

select qa_scf('state', 'testtable') 

Это возвращает буквальный текст "qa_scf * от TestTable, где состояние = 'AL'!". Мне нужно запустить этот запрос из пакетного файла sql, но я не могу найти правильный оператор возврата, чтобы эта функция возвращала строку, а затем выполняла ее пакет sql. Я использую Postgres 9.0.

+0

Проблема, скорее всего, будет в вызывающей функции этой функции, как она обрабатывает результат, а не сама эта функция. –

+0

Я позвонил выше. Это была моя мысль, но никто не дал мне ответа, основанного на вызывающем. –

+0

В этом вопросе отсутствует метод вызывающего пользователя для выполнения SQL, возвращаемого функцией. Или, если вы еще этого не сделали, и вопрос «как это сделать» (= динамический SQL внутри скрипта), Id 'предложите [этот ответ] (http://stackoverflow.com/questions/7942632/how- to-extrace-pg-backend-pid-from-postgresql-in-shell-script-and-pass-it-to-ano/8305578 # 8305578) –

ответ

9

Тип возврата должен быть SETOF RECORD. Выполнение и возврат SQL-файла станет RETURN QUERY EXECUTE. В вашем запросе отсутствует SELECT. Кроме того, там было пробелы.

CREATE OR REPLACE FUNCTION qa_scf(cname character varying, tname character varying) 
RETURNS SETOF RECORD AS 
$BODY$ 
BEGIN 
    RETURN QUERY EXECUTE 'SELECT * from ' ||tname|| ' where ' ||cname ||' != ''AL'''; 
END; 
$BODY$ 
LANGUAGE plpgsql; 

Вызов этой функции будет немного сложнее, так как вам нужно будет указать столбцы, которые вы ожидаете в результате. Выбирается следующим образом:

SELECT * 
FROM qa_scf('foo', 'bar') AS t(col1_name col1_type, ...); 
+4

'return table' должно быть предпочтительнее, чем' setof record' в наши дни, потому что это гораздо проще использовать (нет необходимости указывать структуру таблицы при выборе из нее) –

+4

Да, но разве вам не нужно знать, что такое структура таблицы, когда вы создаете функцию для использования таблицы возвратов? – Eelke

+0

Хороший вопрос;) Я как-то пропустил это ... –