Bom dia! Fabiano,
> Explique porque você precisa dessa PL, qual a necessidade original, > talvez tenha outras maneiras de resolver. > Porque os comandos que já estão prontos precisam passar por ela? Trabalho desenvolvendo um sistema bem robusto, com diversos módulos e "sub-sistemas". Grande parte desse sistema já está pronto, praticamente todo feito em PHP. Há um sistema de logs, também feito em PHP, que funciona através de uma função que "quebra" a consulta, gravando as alterações (semelhante a OLD e NEW das trigger). Todas as consultas desse sistema passam por esta função, para tratar os dados. Além das alterações, nome da tabela e hora, esse sistema de logs precisa gravar alguns parâmetros, como o id do usuário atualmente logado no sistema, assim como o deck (ambiente). Em PHP, o sistema funciona com apenas 1 query de cada vez, falhando nos casos onde há várias juntas (select * ... ; insert ... ;), sem falar que gera uma lentidão tremenda. Decidimos recriar esta função através de triggers de update, insert e delete, para facilitar/agilizar a criação de logs. Até aqui tudo bem, o problema são os parâmetros que precisam ser passados via PHP. Como não é possível parametrizar as triggers, resolvi criar uma função (aquela que mandei numa resposta anterior). Esta função recebe a string de querys, juntamente com os parâmetros. Os parâmetros são gravados uma tabela(log_usuario) e a query é executada. Dentro da função da trigger, é feito um select nesta tabela(log_usuario), para receber o usuário/deck atual. Tudo é registrado na tabela final de logs (através da trigger). Resolvi usar uma função para isso tudo pela necessidade de parâmetros, e pelo fato de serem muitos usuários conectados ao mesmo tempo. Neste caso, as alterações são gravadas apenas no final da função, não deixando possibilidade de um usuário sobrescrever o id do outro, na tabela "log_usuario". Já pensei em separar tudo, deixando apenas begin/commit no início e final, mas infelizmente o begin/commit já é eventualmente utilizado no sistema, podendo gerar conflito (ou é possível usar algum tipo de cascata?) Já verifiquei vários sistemas de table audit na internet, e todos tem o mesmo problema: não aceitam parâmetros externos. Sujestões de alteração ou outros modos de realizar o mesmo procedimento são bem vindas. Desde já, agradeço pela colaboração de todos. Atenciosamente, Pedro Cavalheiro Em 2 de setembro de 2011 02:04, Fabiano Machado Dias <[email protected]> escreveu: > Em 1/9/2011 22:04, Pedro Cavalheiro escreveu: >> Boa noite a todos! >> >> Fabiano, >> >>> O seu retorno seria os registros do "select"? E se alguém passar um passar >>> um comando "select * from tabela; insert into tabela..." ? O retorno seria o >>> que? >> Sim, o retorno deve ser os registros do select. No caso de alguém >> passar uma query multipla, acredito que o mais fácil seria levar em >> conta apenas a última (ignorando os retornos anteriores). Até por isso >> comentei que pode funcionar de um jeito ou de outro (retornando tudo >> ou apenas a última consulta, o que for mais fácil para definir). No >> caso de insert, update ou delete, não é necessário retornar nada. >> >>> O retorno como está não funciona para trazer vários registros, para isso >>> você deve usar um setof com record ou type. >> Sim, estou ciente disso. Justamente por isso que entrei em contato com >> o grupo, não sei como prosseguir. Tentei definir de diversos modos >> diferentes a combinação de setof, record, entre outros, mas sempre >> recebia algum erro. >> Não entendi bem a sintaxe que precisa ser definida para receber o >> retorno em tabela. >> Queria algo como adicionar os resultados da query numa variável, e >> retornar essa variável (isso é apenas uma explicação, não sei se é >> possível em pgplsql). >> >> Infelizmente, não tenho como criar uma função para criação das querys. >> Já existe um sistema em funcionamento, com diversos consultas >> "gigantescas" que tornam a ideia inviável. >> O único modo de fazer isto é definindo retorno por type? Quais as >> exigências deste tipo? Não existe algum modo mais prático, sem nenhum >> tipo de "filtro", para retornar uma tabela de uma consulta? >> >> Desde já, agradeço pela ajuda. >> >> Abraços a todos. >> >> Atenciosamente, >> Pedro Cavalheiro > > > Explique porque você precisa dessa PL, qual a necessidade original, > talvez tenha outras maneiras de resolver. > > Porque os comandos que já estão prontos precisam passar por ela? > > De qualquer maneira segue um exemplo abaixo de uma PL com type > > DROP TYPE IF EXISTS fnc.funcao2_retornotype_retorno CASCADE; > CREATE TYPE fnc.funcao2_retornotype_retorno AS ( > codigoVARCHAR, > descricao VARCHAR); > --Coloco isso para que não exista conflito de que o mesmo type seja > usado por outra pl, é só uma convenção minha se não quiser usar não precisa. > */ > /* > CREATE OR REPLACE FUNCTION fnc.funcao2_retornotype(pTipo INTEGER) > RETURNS SETOF */fnc.funcao2_retornotype_retorno/*AS > $$ > DECLARE > */rRetorno/**/fnc.funcao2_retornotype_retorno/**/; /* > BEGIN > IF pTipo = 1 THEN > RETURN QUERY (SELECT codigo,descricao FROM situacaonfe ORDER BY codigo); > ELSIF pTipo = 2 THEN > FOR */rRetorno/*IN SELECT codigo,descricao FROM situacaonfe ORDER BY codigo > LOOP > RETURN NEXT */rRetorno/*; > END LOOP; > ELSE > RAISE EXCEPTION 'Escolha um tipo(1 ou 2)!'; > END IF; > RETURN; > END; > $$ > LANGUAGE plpgsql; > > > Exemplo da chamada: > > SELECT * FROM fnc.funcao2_retornotype(2); > SELECT fnc.funcao2_retornotype(2); > SELECT (fnc.funcao2_retornotype(2)).descricao; > > * Português - detectado > * Inglês > * Português > > * Inglês > * Português > > <javascript:void(0);> > _______________________________________________ > pgbr-geral mailing list > [email protected] > https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral > _______________________________________________ pgbr-geral mailing list [email protected] https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
