Olá,

2009/5/18 Newton Teixeira do Nascimento Júnior <
[email protected]>

>  Olá comunidade,
>
>
>
> Como fazer uma função retornar genericamente o resultado de um SELECT
> qualquer? (PostgreSql 8.2.4 + CentOS 4.5)
>
Acho que um SELECT version(); resolve o seu problema.


>
>
> Por exemplo, quando executo o seguinte comando select
> fs_select_registros_pts_invalidos(current_date);
>
> O seguinte erro é retornado:
>
>
>
> ERRO:  função que tem argumento do tipo conjunto foi chamada em um contexto
> que não pode aceitar um conjunto
>
> CONTEXT:  PL/pgSQL function "fs_select_registros_pts_invalidos" line 58 at
> return next
>

Isso acontece porque o retorno de sua função está definido com SETOF e você
está chamando a função no seguinte formato: SELECT
nome_da_funcao(parametros); enquanto que a função deve ser chamada no
formato: SELECT * FROM nome_da_funcao(parametros);

>
>
> ********** Erro **********
>
>
>
> ERRO: função que tem argumento do tipo conjunto foi chamada em um contexto
> que não pode aceitar um conjunto
>
> SQL state: 0A000
>
> Contexto: PL/pgSQL function "fs_select_registros_pts_invalidos" line 58 at
> return next
>
>
>
> Isso porque não existe uma tabela com a mesma estrutura (campos) que o
> select retorna, uma vez que retorna
>
> campos oriundos de junções de outras tabelas.
>
> Como fazer uma função retornar um select sem que ter criar uma tabela ou
> view para os resultados desse select ?
>
>
>
> Eis a função (exemplo) :
>
>
>
> CREATE OR REPLACE FUNCTION fs_select_registros_pts_invalidos(data date)
>
>   RETURNS SETOF record AS
>
> $BODY$
>
>
>
> DECLARE
>
>
>
> sql varchar;
>
> str_return varchar;
>
> str_hora_integridade varchar;
>
>
>
> data_aux date;
>
>
>
> r RECORD;
>
> record_aux RECORD;
>
>
>
> chave boolean;
>
> flag boolean;
>
>
>
>
>
> BEGIN
>
>
>
> chave=true;
>
> data_aux = data;
>
>
>
> WHILE (chave = true) LOOP
>
>             sql = 'SELECT MAX(B.BH_DTHR) AS resultado FROM PAS_R A,
> BHPAS_H_' || replace(CAST(data_aux AS character varying(300)), '-','_') ||
>
>                         ' B where A.BH_CHAVE=B.BH_CHAVE AND B.BH_VARIACAO=0
> AND B.BH_CHAVE IN
>
>                         (SELECT BH_CHAVE FROM PAS_R WHERE ID =
> ''ACBR701VBV'') GROUP BY A.ID';
>
>
>
>             flag = false;
>
>             FOR record_aux IN EXECUTE sql LOOP
>
>                         flag = true;
>
>                         str_hora_integridade = record_aux.resultado;
>
>                         str_hora_integridade =
> substring(record_aux.resultado from 11 for 18);
>
>                         str_hora_integridade =
> substring(str_hora_integridade from 1 for 9);
>
>                         str_hora_integridade = trim(str_hora_integridade);
>
>             END LOOP;
>
>
>
>             if ( flag = false) THEN
>
>                         data_aux = data_aux - 1;
>
>             ELSE
>
>                         chave = false;
>
>             END IF;
>
>
>
> END LOOP;
>
>
>
> sql = 'SELECT a.id, a.nome, TO_CHAR(b.bh_dthr,''DD/MM/YYYY HH24:MI'') as
> data, b.bh_variacao, b.estado,
>
>        (b.estado::bit(14) & 1::bit(14))::INTEGER as af,
>
>        (b.estado::bit(14) & 2::bit(14))::INTEGER as fovar,
>
>        (b.estado::bit(14) & 4::bit(14))::INTEGER as falha,
>
>        (b.estado::bit(14) & 8::bit(14))::INTEGER as ivorg,
>
>        (b.estado::bit(14) & 16::bit(14))::INTEGER as maorg,
>
>        (b.estado::bit(14) & 32::bit(14))::INTEGER as manua,
>
>        (b.estado::bit(14) & 64::bit(14))::INTEGER as ninci
>
>             FROM pds_r a, bhpds_h_'  || replace(CAST(data_aux AS character
> varying(300)), '-','_') || ' b  WHERE a.bh_chave=b.bh_chave AND
>
>             (b.estado::bit(14) & 8::bit(14))::INTEGER > 0 AND  bh_dthr =
> ''' || data_aux || ' ' || str_hora_integridade || '''
>
>             GROUP BY a.id, a.nome, b.estado, b.bh_dthr, b.bh_variacao
> ORDER BY id, bh_dthr';
>
>
>
>
>
> FOR r IN EXECUTE sql LOOP
>
>             RETURN NEXT r;
>
> END LOOP;
>
>
>
> RETURN;
>
>
>
> END; $BODY$
>
>   LANGUAGE 'plpgsql' VOLATILE;
>
>
>
>
>
>
>
>
>
>
>
>
> Aviso:
> "O emitente desta mensagem é responsável por seu conteúdo e endereçamento.
> Cabe ao destinatário cuidar quanto ao tratamento adequado. Sem a devida
> autorização, a divulgação, a reprodução, a distribuição ou qualquer outra
> ação em desconformidade com as normas internas da ELETRONORTE S/A são
> proibidas e passíveis de sanção disciplinar, cível e criminal. Esta mensagem
> pode ser monitorada".
>
>
>
>
> _______________________________________________
> pgbr-geral mailing list
> [email protected]
> https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
>
>

Espero ter ajudado.

[]s
-- 
JotaComm
http://jotacomm.wordpress.com
http://www.dextra.com.br/postgres
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a