Poderia funcionar assim:
CREATE OR REPLACE FUNCTION tt_query(orig_name regclass, data_tt timestamp)
RETURNS SETOF record AS
$func$
BEGIN
EXECUTE 'CREATE OR REPLACE TEMP VIEW tmp as
select *
from '
|| orig_name
|| ' where trigger_changed >'
|| quote_literal(data_tt)
|| ' ORDER BY trigger_changed DESC';
-- other work on view tmp
-- return the rows of view temp
RETURN QUERY
SELECT * FROM tmp;
END
$func$ LANGUAGE plpgsql;
-
Observe o uso do tipo de identificador de objetoregclass
para evitar automaticamente a injeção de SQL.
-
Não use a sintaxe desatualizadavar ALIAS for $1
se você não precisa. Em vez disso, declare nomes de parâmetros.
-
Eu não usaria a palavra-chavetemp
como identificador, mesmo que isso seja permitido. Usandotmp
em vez de.
-
UseRETURN QUERY
para retornar um conjunto de registros. Isso pode até ser uma chamada estática semEXECUTE
. No entanto, você está retornando registros anônimos e o Postgres exige uma lista de definição de coluna a cada chamada:
SELECT * FROM tt_query('tbl_name', '2014-02-15 12:00')
AS f(col1 int, col2 text, ...);
Isso é bastante complicado.
Melhores soluções
Se você sabe o tipo de retorno (mesmo que os nomes das tabelas estejam mudando, a lista de colunas pode compartilhar os mesmos tipos), declare-o no momento da criação. Considere esta pergunta relacionada:
PostgreSQL:ERRO:42601:uma lista de definição de coluna é necessária para funções que retornam "registro"
Se o tipo de retorno variar com o nome da tabela fornecida, ainda há uma solução muito melhor. Como você está criando uma visão com
SELECT * FROM tbl
, você pode utilizar o tipo conhecido da própria tabela como polimórfico
parâmetro:CREATE OR REPLACE FUNCTION tt_query(orig_name anyelement, data_tt timestamp)
RETURNS SETOF anyelement AS
$func$
BEGIN
EXECUTE format('CREATE OR REPLACE TEMP VIEW tmp AS
SELECT * FROM %s
WHERE trigger_changed > %L
ORDER BY trigger_changed DESC'
,pg_typeof(orig_name)
,data_tt);
-- other work on view tmp
-- return the rows of view tmp
RETURN QUERY
SELECT * FROM tmp;
END
$func$ LANGUAGE plpgsql;
Chamada simplificada:
SELECT * FROM tt_query(NULL::tbl_name, '2014-02-15 12:00');
Também usando
format()
para concatenação de strings simples e segura. Mais detalhes nesta resposta relacionada:
Refatorar uma função PL/pgSQL para retornar a saída de várias consultas SELECT