Pular para o conteúdo
  • Este tópico contém 6 respostas, 5 vozes e foi atualizado pela última vez 17 anos, 2 meses atrás por jspaulonci.
Visualizando 7 posts - 1 até 7 (de 7 do total)
  • Autor
    Posts
  • #84495
    felipeldm
    Participante

      Prezados,

      Primeiramente desculpe se alguém já tiver postado algo nesse sentido. O ambiente em que me deparo é o seguinte:

      1) Existem algumas tabelas no meu banco que necessito auditar, contudo, algumas dessas tabelas possuem mais de 30 colunas.

      2) A trigger que eu quero é BEFORE UPDATE, pra gravar meu registro antes de o mesmo ser atualizado. Eu poderia fazer uma tranquilamente gravando todos os registros antigos e todos os novos, porém ficaria difícil auditar já que tem algumas tabelas com muitas colunas.

      O que eu queria era:
      Que no nomento em que a trigger for disparada ela detectasse apenas a(s) coluna(s) que foram modificadas e não precisasse gravar o registro todo na tabela de auditoria.

      Dessa forma a tabela teria a estrutura:
      * COD_EVENTO – Codigo do evento;
      * Data – Contendo SYSDATE;
      * Tabela – Tabela que sofreu alteração.
      * Usuario – Usuario que alterou a tabela (SYS_CONTEXT);
      * ALTERACAO – Algo do tipo “O VALOR DA COLUNA TAL MUDOU DISSO PARA ISSO”.

      Assim ficaria perfeito, eu poderia integrar várias triggers gravando nessa mesma tabela.

      Aguardo e desde já agradeço a todos!!!

      Felipe Lima

      #84496
      Rodrigo Mesquita
      Participante

        utilize as variáveis :NEW e :OLD

        exemplo para a coluna código

        IF :NEW.CODIGO :OLD.CODIGO THEN

        — coloque o insert na tabela de auditoria

        End IF;

        coloque isso para todos os campos que possam ser atualizados

        #84498
        felipeldm
        Participante

          Eu já até pensei nisso…..
          Mas será que é a única maneira???

          Já pensou eu fazendo isso pra uma tabela que tem mais de 50 colunas???
          50 IFs com insert dentro…. complicado neh???

          Acho que pode existir uma maneira mais fácil.
          Mas se não houver essa vai adiantar sim.

          Obrigado de toda forma…

          Felipe Lima

          #84505
          Avatar photoLeonardo Litz
          Participante

            Felipe…

            cara faca um gerador que leia o metadados e gere os ifs automaticamente, assim vc não precisa digitar if a if…

            Fora isso voce tb pode fazer trigger por coluna, nesta forma voce devera gerar um trigger para cada coluna… as ai irá gerar uma demanda maior e a performace irá diminuir…

            Vlw Leonardo Litz

            #84557
            felipeldm
            Participante

              Olá mais uma vez pessoal…

              Como não surgiu uma solução mais “compacta” hehehe tive que fazer da seguinte maneira, segue um exemplo que audita uma tabelinha do sistema:

              CREATE OR REPLACE TRIGGER TR_AUDITA_ITEM_VDP BEFORE UPDATE ON ITEM_VDP
              FOR EACH ROW

              DECLARE

              VCOD_EVENTO TB_AUDITA_ITENS.COD_EVENTO%TYPE;
              VOS_USER TB_AUDITA_ITENS.USUARIO%TYPE;
              VVLR_TXT TB_AUDITA_ITENS.VLR_ALTERADO%TYPE;

              BEGIN
              SELECT SYS_CONTEXT(‘USERENV’,’OS_USER’) INTO VOS_USER FROM DUAL;

              SELECT MAX(COD_EVENTO) INTO VCOD_EVENTO
              FROM TB_AUDITA_ITENS
              WHERE COD_ITEM = :OLD.COD_ITEM;

              IF VCOD_EVENTO IS NULL THEN
              VCOD_EVENTO := 0;
              END IF;

              IF :OLD.COD_EMPRESA :NEW.COD_EMPRESA THEN

              VVLR_TXT := ‘A COLUNA COD_EMPRESA MUDOU DE ‘||:OLD.COD_EMPRESA||’ PARA ‘||:NEW.COD_EMPRESA;
              GOTO INSERE;

              ELSIF :OLD.COD_ITEM :NEW.COD_ITEM THEN

              VVLR_TXT := ‘A COLUNA COD_ITEM MUDOU DE ‘||:OLD.COD_ITEM||’ PARA ‘||:NEW.COD_ITEM;
              GOTO INSERE;

              ELSIF :OLD.PRE_UNIT_BRUT :NEW.PRE_UNIT_BRUT THEN

              VVLR_TXT := ‘A COLUNA PRE_UNIT_BRUT MUDOU DE ‘||:OLD.PRE_UNIT_BRUT||’ PARA ‘||:NEW.PRE_UNIT_BRUT;
              GOTO INSERE;

              ELSIF :OLD.COD_GRUPO_ITEM :NEW.COD_GRUPO_ITEM THEN

              VVLR_TXT := ‘A COLUNA COD_GRUPO_ITEM MUDOU DE ‘||:OLD.COD_GRUPO_ITEM||’ PARA ‘||:NEW.COD_GRUPO_ITEM;
              GOTO INSERE;

              ELSIF :OLD.IES_LISTA_PRECO :NEW.IES_LISTA_PRECO THEN

              VVLR_TXT := ‘A COLUNA IES_LISTA_PRECO MUDOU DE ‘||:OLD.IES_LISTA_PRECO||’ PARA ‘||:NEW.IES_LISTA_PRECO;
              GOTO INSERE;

              ELSIF :OLD.PRE_UNIT_BRUT_EXP :NEW.PRE_UNIT_BRUT_EXP THEN

              VVLR_TXT := ‘A COLUNA PRE_UNIT_BRUT_EXP MUDOU DE ‘||:OLD.PRE_UNIT_BRUT_EXP||’ PARA ‘||:NEW.PRE_UNIT_BRUT_EXP;
              GOTO INSERE;

              ELSIF :OLD.COD_TIP_CARTEIRA :NEW.COD_TIP_CARTEIRA THEN

              VVLR_TXT := ‘A COLUNA COD_TIP_CARTEIRA MUDOU DE ‘||:OLD.COD_TIP_CARTEIRA||’ PARA ‘||:NEW.COD_TIP_CARTEIRA;
              GOTO INSERE;

              END IF;

              <>
              INSERT INTO TB_AUDITA_ITENS(COD_EVENTO,
              DATA_ATUA,
              HORA_ATUA,
              USUARIO,
              TABELA,
              COD_EMPRESA,
              COD_ITEM,
              VLR_ALTERADO)
              VALUES(VCOD_EVENTO+1,
              TO_CHAR(SYSDATE,’DD/MM/YY’),
              TO_CHAR(SYSDATE,’HH24:MM:SS’),
              VOS_USER,
              ‘ITEM_VDP’,
              :OLD.COD_EMPRESA,
              :OLD.COD_ITEM,
              VVLR_TXT);

              END;

              Funcionar funciona sim, só é ruim para as tabelas imensas que tem no banco…

              Valeu galera!!!

              #84561
              Marcio68Almeida
              Participante

                Existe uma sollução um pouco mais simples (ou complexa, não sei como você vai encarar)… risos…
                Crie uma função que fará o insert, passe o nome da tabela e dois vetores como parâmetro.
                O primeiro array vai possuir os dados novos e o segundo os dados antigos.
                Faça um loop que leia o vetor pelo seu tamanho e insira só os que for diferente…
                Só não me peça para fazer a função por que sou preguiçoso… 😳
                Não lembro se há alguma restrição passar array como parâmetro… 💡

                #84565
                jspaulonci
                Participante

                  Pessoal é Oracle 10g ?, (pois no 9i tem algumas limitações) , dá uma pesquisada pois no 10 tem muitos recursos de auditoria, auditar esta tabela de 30 colunas através de trigger será meio pesado para o Banco, (é claro que irá dependender do número de inserts ,updates e deletes) mas se fosse eu , partiria para os recursos disponíves em nível de banco ou até dar uma pesquisada no Oracle Vault.

                  Não devo ter ajudado muito.

                  Spaulonci

                Visualizando 7 posts - 1 até 7 (de 7 do total)
                • Você deve fazer login para responder a este tópico.