2014-02-05 Daniel Cordeiro <[email protected]>:

>  Bom dia,
>
> Em 05-02-2014 11:02, Rafael Fialho Corrêa escreveu:
>
>  Em 5 de fevereiro de 2014 11:55, Matheus Saraiva <
> [email protected]> escreveu:
>
>>
>> Rafael Fialho
>>
>> Não entendi o que vc quis dizer, o que preciso é que a clausula WHERE
>> receba um parâmetro. Como:
>>
>> V = 'matheus'
>>
>> WHERE nome = V
>>
>> A variável V receberia o seu valor por parâmetro.
>>
>
>  O que quero dizer é o seguinte:
>
>  CREATE OR REPLACE VIEW teste AS
>   select
>     id_nome
>     , nome
>   from
>     nomes;
> GRANT ALL ON TABLE teste TO public;
>
>  "select * from teste where nome = 'matheus';"
>
>  Simples assim.. hehehe Isso que eu quis dizer.
>
> Acredito que esta não seja uma opção tão 'performática', uma vez que a
> view vai gerar todos os dados e só depois é que o planejador realizará a
> restrição através do cláusula WHERE e ordenações necessárias.
>
>
humm... Sua afirmação não está correta. Dada a view "teste" a seguinte
consulta:

    SELECT * FROM teste WHERE nome = 'matheus';

Passa por algumas transformações, primeiro:

    SELECT * FROM (SELECT id_nome, nome FROM nomes) teste WHERE nome =
'matheus';

Em seguida, o PostgreSQL "percebe" que não precisa da subquery e transforma
a query acima em:

    SELECT id_nome, nome FROM nomes AS teste WHERE teste.nome = 'matheus';

Resumindo, a view não vai gerar todos os dados, a consulta (acima) é que
será executada no final (claro ainda tem o plano de execução, métodos de
acesso, etc.).

Eu até diria que nesse exemplo específico a view me parece até mais
adequada e mais fácil de manter do que a função.



> Minha sugestão é criar uma função que realiza a consulta já adicionando as
> restrições necessárias para a triagem inicial dos dados desejados.
>
> Ex (descartando índices, segurança da função, etc)*1*.
>
> *CREATE TABLE lancamentos (id int, conta text, campo1 text, campo2 text);*
>
> *INSERT INTO lancamentos VALUES(1,'Produtivo','valor1','valor2');*
> *INSERT INTO lancamentos VALUES(2,'Produtivo','valor1','valor2');*
> *INSERT INTO lancamentos VALUES(3,'Mecanica','valor1','valor2');*
> *INSERT INTO lancamentos VALUES(4,'Mecanica','valor1','valor2');*
>
> * .... *
> *CREATE OR REPLACE FUNCTION sp_lancamentos(IN CODCONTA varchar) RETURNS
> TABLE(i int, c1 text,c2 text, c text)*
> *AS $$*
>
> *    BEGIN*
> *        RETURN QUERY SELECT id,conta,campo1,campo2 FROM lancamentos WHERE
> conta = CODCONTA;*
> *    END;*
> *$$*
> *language 'plpgsql';*
>
>
>
OK. Realmente, para aceitar parâmetros da forma que o OP espera, é
necessário sim uma função.

Eu só recomendaria, nesse caso especificamente, a usar uma função SQL ao
invés de PL/pgSQL:

    CREATE OR REPLACE FUNCTION sp_lancamentos(IN CODCONTA varchar)
    RETURNS TABLE(i int, c1 text,c2 text, c text)
    AS $$
        SELECT id,conta,campo1,campo2 FROM lancamentos WHERE conta =
CODCONTA;
    $$
    LANGUAGE SQL;

Para chamá-la:

    SELECT * FROM sp_lancamentos('Produtivo');

(a chamada em si seria igual à PL/pgSQL, só quis exemplificar)


> Para uma function  muito grande e com muitas variáveis para substituição,
> vale a pena utilizar a cláusula EXECUTE no RETURN QUERY (isso já me salvou
> de vários problemas em functions com mais mais de 1500 linhas e código e
> dezenas de variáveis)* 2*:
>
>
> *     ....     RETURN QUERY EXECUTE 'SELECT id,conta,campo1,campo2 FROM
> lancamentos WHERE conta = $1' USING CODCONTA;*
>     ....
>
>
>
Ah? Por quê? Eu particularmente tento evitar o EXECUTE ao menos que
estritamente necessário. Lembre-se que ele não pode ser otimizado pelo
PL/pgSQL para armazenar o plano de execução.



> Lembrando que estas ações podem dificultar a análise de um problema
> futuro, pois o EXPLAIN não vai detalhar o conteúdo interno executado na
> função e nem nos logs.
>
>
+1. Otimizar funções é uma tarefa bem árdua. Só uma dica, a extensão
auto_explain pode ajudar nessa tarefa. ;-)



>  *1* - http://www.postgresql.org/docs/9.3/static/plpgsql-declarations.html
> *2* - http://www.postgresql.org/docs/9.3/static/plpgsql-statements.html
>
>
>
>
Atenciosamente,
-- 
Matheus de Oliveira
Analista de Banco de Dados
Dextra Sistemas - MPS.Br nível F!
www.dextra.com.br/postgres
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a