7 марта 2011 г. 21:13 пользователь Dmitry E. Oboukhov <unera@debian.org> написал:
есть таблица
parent: | id | somecol |
есть десяток унаследованных таблиц:
childX: | id | somecol | .... |
есть некий скрипт, который обрабатывает все данные в унаследованных по каким-то критериям.
работает примерно так:
1. делает SELECT parent.id, pg_class.relname AS tbl FROM parent, pg_class WHERE pg_class.oid = r.tableoid LIMIT 1;
2. если результаты есть делает SELECT %1 AS tbl, * FROM %1 WHERE id = %2
где вместо %1 подставляется поле tbl выбранное из первого запроса, а вместо %2 - id.
После того как результаты обработаны они удаляются из унаследованной таблицы.
вот хочется запхать 1 и 2 в хранимую процедуру, пишем:
CREATE OR REPLACE FUNCTION foo() RETURNS RECORD AS $$ DECLARE retval RECORD; recid RECORD; BEGIN SELECT p.id, pg_class.relname AS tbl INTO recid FROM parent, pg_class WHERE parent.tableoid = pg_class.oid LIMIT 1;
EXECUTE 'SELECT ''' || recid.tbl || ''' AS tbl, * FROM "' || recid.tbl || '" WHERE id = ' || recid.id INTO retval; RETURN retval; $$ LANGUAGE 'plpgsql';
получаем примерно то что надо но в виде одного значения:
foo: '(tblname,1234,abc,...)'
а хочется получить в виде такого результата как вернул бы SELECT, то есть в виде хеша:
tbl: tblname id: 1234 somecol: 'abc' ...
Используйте SELECT * FROM foo();
И еще, квоттинг: в документации написано что можно использовать функции quote_ident и quote_value для создания динамических запросов, но у меня почему-то постгрис на них ругается, говорит: нет такой функции
Если функции quote_ident(), quote_literal() и quote_nullable(). Первая принимает в кач-ве аргумента только текст, а вторая и третья перегружены. Проверьте аргумент какого типа Вы указываете при вызове.