Pular para o conteúdo
Visualizando 14 posts - 1 até 14 (de 14 do total)
  • Autor
    Posts
  • #97546
    gsmdf
    Participante

      Caros colegas,

      Tenho um varchar2 com este conteudo:

      DROP TRIGGER TCU.TR_ACAO;

      CREATE OR REPLACE TRIGGER TCU.TR_ACAO AFTER INSERT OR UPDATE OR DELETE

      ON TCU.ACAO
      FOR EACH ROW

      DECLARE

      V_ChangeType CHAR(1);

      V_UsuarioAtualizacao CHAR(20);

      V_OSUSER VARCHAR2(20);

      V_MAQUINA VARCHAR2(65);

      BEGIN

      SELECT DISTINCT OSUSER, MACHINE INTO V_OSUSER, V_MAQUINA

      FROM V$SESSION

      WHERE AUDSID = USERENV('SESSIONID')

      AND STATUS IN ('ACTIVE','INACTIVE')

      ;

      V_UsuarioAtualizacao:= USER;

      IF PKG_AUDIT.COD_USUARIO IS NOT NULL THEN

      V_UsuarioAtualizacao := PKG_AUDIT.COD_USUARIO;

      END IF;

      /* I=Insert, D=Delete, U=Update */

      IF INSERTING THEN

      V_ChangeType := 'I';

      ELSE

      IF UPDATING THEN

      V_ChangeType := 'U';

      ELSE

      V_ChangeType := 'D';

      END IF;

      END IF;

      INSERT INTO AUDIT_TCU.ACAO

      (

      V_NUM_DIAS_PREVISTO

      , V_DTHORA_INICIO

      , V_DTHORA_TERMINO

      , V_TIPO

      , V_SE_DATA_ESTIMADA

      , V_SE_HORA_ESTIMADA

      , V_COD

      , N_COD

      , OPERACAO_EFETUADA

      , DTHORA_ATUALIZACAO

      , USUARIO_ATUALIZACAO

      , OSUSER

      , MAQUINA

      , USUARIO_ORACLE

      )

      Como fica a sintaxe do REGEXP_REPLACE(texto,EXPRESSAO,”) se quero substituir de DROP … até INSERT INTO AUDIT_TCU.ACAO ( por BLANK (BRANCO) ?? O que entraria em EXPRESSAO ?

      Quero ter esse texto como resultado:


      V_NUM_DIAS_PREVISTO

      , V_DTHORA_INICIO

      , V_DTHORA_TERMINO

      , V_TIPO

      , V_SE_DATA_ESTIMADA

      , V_SE_HORA_ESTIMADA

      , V_COD

      , N_COD

      , OPERACAO_EFETUADA

      , DTHORA_ATUALIZACAO

      , USUARIO_ATUALIZACAO

      , OSUSER

      , MAQUINA

      , USUARIO_ORACLE

      )

      Ou seja, minha intenção via expressão regular é apagar esta primeira parte do varchar2 pois tenho interesse em ficar somente com este resultado final.

      Como ficaria então a sintaxe do REGEXP_REPLACE?

      Grato!

      #97548
      burga
      Participante

        Dá pra fazer assim:

        with t as (select
        'DROP TRIGGER TCU.TR_ACAO;

        CREATE OR REPLACE TRIGGER TCU.TR_ACAO AFTER INSERT OR UPDATE OR DELETE

        ON TCU.ACAO
        FOR EACH ROW

        DECLARE

        V_ChangeType CHAR(1);

        V_UsuarioAtualizacao CHAR(20);

        V_OSUSER VARCHAR2(20);

        V_MAQUINA VARCHAR2(65);

        BEGIN

        SELECT DISTINCT OSUSER, MACHINE INTO V_OSUSER, V_MAQUINA

        FROM V$SESSION

        WHERE AUDSID = USERENV(''SESSIONID'')

         AND STATUS IN (''ACTIVE'',''INACTIVE'')
        

        ;

        V_UsuarioAtualizacao:= USER;

        IF PKG_AUDIT.COD_USUARIO IS NOT NULL THEN

         V_UsuarioAtualizacao := PKG_AUDIT.COD_USUARIO;
        

        END IF;

        /* I=Insert, D=Delete, U=Update */

        IF INSERTING THEN

          V_ChangeType := ''I'';
        

        ELSE

          IF UPDATING THEN
        
             V_ChangeType := ''U'';
        
          ELSE
        
             V_ChangeType := ''D'';
        
          END IF;
        

        END IF;

        INSERT INTO AUDIT_TCU.ACAO

        (

           V_NUM_DIAS_PREVISTO
        
          , V_DTHORA_INICIO
        
          , V_DTHORA_TERMINO
        
          , V_TIPO
        
          , V_SE_DATA_ESTIMADA
        
          , V_SE_HORA_ESTIMADA
        
          , V_COD
        
          , N_COD
        
          , OPERACAO_EFETUADA
        
          , DTHORA_ATUALIZACAO
        
          , USUARIO_ATUALIZACAO
        
          , OSUSER
        
          , MAQUINA
        
          , USUARIO_ORACLE
        

        )' texto from dual)
        select
        regexp_replace(texto,'DROP([[:print:]|[:cntrl:]])INSERT INTO AUDIT_TCU.ACAO([[:print:]|[:cntrl:]])(')
        from t;

        Abraços,

        #97549
        Marcos Braga
        Participante

          Olá,

          Não sei se entendi direito, creio que a coisa ficou meio confusa. Mas vamos lá…

          Estou deduzindo que você tem um campo VARCAHR2(4000) com o primeiro texto que adicionou. E quer um resultado como o segundo texto que adicionou, excluindo tudo, desde: DROP até INSERT INTO. (acho que é isso mesmo, rssss).

          Efetuei alguns testes e não funcionaram direito porque deixei o texto como adicionou no post (com ENTER ou CHR(10)).

          Então, para solucionar, fiz uma pequena alteração que funcionou.

          select regexp_replace(replace(COLUNA, chr(10),''), '.(INSERT INTO)(.)', 'INSERT INTO 2') from TABELA
          ;

          Se observar, primeiro eu exclui os ENTERs para depois aplicar a solução do regexp.

          Dá uma olhada e vê se isso ajuda ou dá uma luz.

          Qualquer coisa, entra em contato.

          []s
          Braga

          #97551
          gsmdf
          Participante

            [quote=”burga”:h031jypv]Dá pra fazer assim:

            with t as (select
            'DROP TRIGGER TCU.TR_ACAO;

            CREATE OR REPLACE TRIGGER TCU.TR_ACAO AFTER INSERT OR UPDATE OR DELETE

            ON TCU.ACAO
            FOR EACH ROW

            DECLARE

            V_ChangeType CHAR(1);

            V_UsuarioAtualizacao CHAR(20);

            V_OSUSER VARCHAR2(20);

            V_MAQUINA VARCHAR2(65);

            BEGIN

            SELECT DISTINCT OSUSER, MACHINE INTO V_OSUSER, V_MAQUINA

            FROM V$SESSION

            WHERE AUDSID = USERENV(''SESSIONID'')

             AND STATUS IN (''ACTIVE'',''INACTIVE'')
            

            ;

            V_UsuarioAtualizacao:= USER;

            IF PKG_AUDIT.COD_USUARIO IS NOT NULL THEN

             V_UsuarioAtualizacao := PKG_AUDIT.COD_USUARIO;
            

            END IF;

            /* I=Insert, D=Delete, U=Update */

            IF INSERTING THEN

              V_ChangeType := ''I'';
            

            ELSE

              IF UPDATING THEN
            
                 V_ChangeType := ''U'';
            
              ELSE
            
                 V_ChangeType := ''D'';
            
              END IF;
            

            END IF;

            INSERT INTO AUDIT_TCU.ACAO

            (

               V_NUM_DIAS_PREVISTO
            
              , V_DTHORA_INICIO
            
              , V_DTHORA_TERMINO
            
              , V_TIPO
            
              , V_SE_DATA_ESTIMADA
            
              , V_SE_HORA_ESTIMADA
            
              , V_COD
            
              , N_COD
            
              , OPERACAO_EFETUADA
            
              , DTHORA_ATUALIZACAO
            
              , USUARIO_ATUALIZACAO
            
              , OSUSER
            
              , MAQUINA
            
              , USUARIO_ORACLE
            

            )' texto from dual)
            select
            regexp_replace(texto,'DROP([[:print:]|[:cntrl:]])INSERT INTO AUDIT_TCU.ACAO([[:print:]|[:cntrl:]])(')
            from t;

            Abraços,[/quote]


            regexp_replace(texto,'DROP([[:print:]|[:cntrl:]])INSERT INTO AUDIT_TCU.ACAO([[:print:]|[:cntrl:]])(')

            Burga,

            Gostaria que explicasse o que significa o ([[:print:]|[:cntrl:]]) entre DROP e *.
            E que depois você usou de novo.
            Quando é replace por BLANK não é necessário então o terceiro parametro da função ? O default é ” ? Pois você usou apenas dois parametros, o texto e a expressão regular a ser substituida.

            Valeu!

            #97552
            gsmdf
            Participante

              Braga,

              regexp_replace(replace(COLUNA, chr(10),”), ‘.(INSERT INTO)(.)’, ‘INSERT INTO 2’)

              Entendi que você retirou os enters. Ok.
              O que seria o terceiro parametro ‘INSERT INTO 2’ ??

              #97553
              gsmdf
              Participante

                [quote=”gsmdf”:1pltzomi][quote=”burga”:1pltzomi]Dá pra fazer assim:

                Burga,

                Gostaria que explicasse o que significa o ([[:print:]|[:cntrl:]]) entre DROP e *.
                E que depois você usou de novo.
                Quando é replace por BLANK não é necessário então o terceiro parametro da função ? O default é ” ? Pois você usou apenas dois parametros, o texto e a expressão regular a ser substituida.

                Valeu![/quote][/quote]

                Ah, achei aqui, classes POSIX de caracteres e espaço visíveis e caracteres de controle em qualquer quantidade… em outras palavras você foi pegando tudo até o INSERT…
                Boa !

                #97555
                burga
                Participante

                  Isso aí, fui pegando tudo que está entre o primeiro DROP e o INSERT, e usei a mesma coisa depois pra chegar ao primeiro “(” depois do INSERT.

                  🙂

                  #97563
                  Marcos Braga
                  Participante

                    [quote=”gsmdf”:1jb6e8g7]Braga,

                    regexp_replace(replace(COLUNA, chr(10),”), ‘.(INSERT INTO)(.)’, ‘INSERT INTO 2’)

                    Entendi que você retirou os enters. Ok.
                    O que seria o terceiro parametro ‘INSERT INTO 2’ ??[/quote]

                    Como adicionei o “(INSERT INTO)” dentro de parênteses, na busca, foi preciso repetir a string “INSERT INTO” para não perdê-la.

                    O “2” significa que vou adicionar tudo que está depois do “(INSERT INTO)” da busca, representado por “(.*)” — qualquer caracter.

                    Tem alguns exemplos em:

                    https://profissionaloracle.com.br/blogs/braga/category/regexp/

                    Mas creio que a solução do burga seja mais simplista, mais fácil de aplicar.

                    []s
                    Braga

                    #97565
                    Marcos Braga
                    Participante

                      aproveitando a solução do burga, tente isso:

                      regexp_replace(COLUNA, '([[:print:]|[:cntrl:]]*)(INSERT INTO)(.*)', 'INSERT INTO 3')

                      Dessa forma, não precisa retirar os ENTERs.

                      []s
                      Braga

                      #97575
                      gsmdf
                      Participante

                        Pessoal,

                        Adcionei a ultima parte da trigger, com VALUES ( …. ao texto.
                        Ficou assim :

                        DROP TRIGGER TCU.TR_ACAO;

                        CREATE OR REPLACE TRIGGER TCU.TR_ACAO AFTER INSERT OR UPDATE OR DELETE

                        ON TCU.ACAO
                        FOR EACH ROW

                        /*

                        Cria trigger para tabela TCU.ACAO

                        Data - 22/7/2010 - 14:00:16

                        */

                        --

                        -- 01/10/2003 - Autor: Paulo César

                        -- Alterações:

                        -- Inclusão da variável V_UsuarioAtualizacao assumindo USER do Oracle

                        -- Inclusão de nova coluna USUARIO_ORACLE no Audit

                        -- Decisão da Mônica, Fábio, Mauricio R. e PC

                        --
                        DECLARE

                        V_ChangeType CHAR(1);

                        V_UsuarioAtualizacao CHAR(20);

                        V_OSUSER VARCHAR2(20);

                        V_MAQUINA VARCHAR2(65);

                        BEGIN

                        SELECT DISTINCT OSUSER, MACHINE INTO V_OSUSER, V_MAQUINA

                        FROM V$SESSION

                        WHERE AUDSID = USERENV(''SESSIONID'')

                         AND STATUS IN (''ACTIVE'',''INACTIVE'')
                        

                        ;

                        V_UsuarioAtualizacao:= USER;

                        IF PKG_AUDIT.COD_USUARIO IS NOT NULL THEN

                         V_UsuarioAtualizacao := PKG_AUDIT.COD_USUARIO;
                        

                        END IF;

                        /* I=Insert, D=Delete, U=Update */

                        IF INSERTING THEN

                          V_ChangeType := ''I'';
                        

                        ELSE

                          IF UPDATING THEN
                        
                             V_ChangeType := ''U'';
                        
                          ELSE
                        
                             V_ChangeType := ''D'';
                        
                          END IF;
                        

                        END IF;

                        INSERT INTO AUDIT_TCU.ACAO

                        (

                           V_NUM_DIAS_PREVISTO
                        
                          , V_DTHORA_INICIO
                        
                          , V_DTHORA_TERMINO
                        
                          , V_TIPO
                        
                          , V_SE_DATA_ESTIMADA
                        
                          , V_SE_HORA_ESTIMADA
                        
                          , V_COD
                        
                          , N_COD
                        
                          , OPERACAO_EFETUADA
                        
                          , DTHORA_ATUALIZACAO
                        
                          , USUARIO_ATUALIZACAO
                        
                          , OSUSER
                        
                          , MAQUINA
                        
                          , USUARIO_ORACLE
                        

                        ) VALUES (

                           :OLD.NUM_DIAS_PREVISTO
                        
                          , :OLD.DTHORA_INICIO
                        
                          , :OLD.DTHORA_TERMINO
                        
                          , :OLD.TIPO
                        
                          , :OLD.SE_DATA_ESTIMADA
                        
                          , :OLD.SE_HORA_ESTIMADA
                        
                          , :OLD.COD
                        
                          , :NEW.COD
                        
                          , V_ChangeType
                        
                          , SYSDATE
                        
                          , V_UsuarioAtualizacao
                        
                          , V_OSUSER
                        
                          , V_MAQUINA
                        
                          , USER
                        

                        );

                        END;
                        /

                        Ai quando usei a exp reg regexp_replace(texto,’DROP([[:print:]|[:cntrl:]])INSERT INTO AUDIT_TCU.ACAO([[:print:]|[:cntrl:]])(‘)
                        ele retorna há partir de :OLD.NUM_DIAS_PREVISTOS pra baixo…ele só ta parando no segundo ( após insert into.
                        Como arrumo essa exp reg para funcionar para qualquer outro nome de tabela que não seja ACAO (AUDIT_TCU.ACAO) pois poderia ser (AUDIT_TCU.NOME_OUTRA_TABELA) e ao mesmo tempo retornar esta parte do texto:

                        V_NUM_DIAS_PREVISTO

                          , V_DTHORA_INICIO
                        
                          , V_DTHORA_TERMINO
                        
                          , V_TIPO
                        
                          , V_SE_DATA_ESTIMADA
                        
                          , V_SE_HORA_ESTIMADA
                        
                          , V_COD
                        
                          , N_COD
                        
                          , OPERACAO_EFETUADA
                        
                          , DTHORA_ATUALIZACAO
                        
                          , USUARIO_ATUALIZACAO
                        
                          , OSUSER
                        
                          , MAQUINA
                        
                          , USUARIO_ORACLE
                        

                        ) VALUES (

                           :OLD.NUM_DIAS_PREVISTO
                        
                          , :OLD.DTHORA_INICIO
                        
                          , :OLD.DTHORA_TERMINO
                        
                          , :OLD.TIPO
                        
                          , :OLD.SE_DATA_ESTIMADA
                        
                          , :OLD.SE_HORA_ESTIMADA
                        
                          , :OLD.COD
                        
                          , :NEW.COD
                        
                          , V_ChangeType
                        
                          , SYSDATE
                        
                          , V_UsuarioAtualizacao
                        
                          , V_OSUSER
                        
                          , V_MAQUINA
                        
                          , USER
                        

                        );

                        END;
                        /

                        ? Grato!

                        #97578
                        burga
                        Participante

                          Oi gsmdf,

                          Com expressões regulares, você deve encontrar padrões nos valores a serem trabalhados. Não é porque funciona pra um caso que vai funcionar pra todos, então se os valores que você está trabalhando não tiverem um padrão bem definido desista das regexp… 🙂

                          Eu me equivoquei na outra mensagem dizendo que o comando iria parar no primeiro “(” após o INSERT, ele pára no ultimo. Pra isto, seguindo o padrão dos dois valores que você passou, dá prafazer desta forma:

                          regexp_replace(texto,'DROP([[:print:]|[:cntrl:]])*INSERT INTO([[:print:]])*([ |[:cntrl:]])*(')

                          Também dá pra seguir o mesmo raciocínio do Braga, se o que você realmente quer é só o conteúdo após o ultimo INSERT.

                          Abraços,

                          #97579
                          gsmdf
                          Participante

                            [quote=”burga”:1bcfcf8u]Oi gsmdf,

                            Com expressões regulares, você deve encontrar padrões nos valores a serem trabalhados. Não é porque funciona pra um caso que vai funcionar pra todos, então se os valores que você está trabalhando não tiverem um padrão bem definido desista das regexp… 🙂

                            Eu me equivoquei na outra mensagem dizendo que o comando iria parar no primeiro “(” após o INSERT, ele pára no ultimo. Pra isto, seguindo o padrão dos dois valores que você passou, dá prafazer desta forma:

                            regexp_replace(texto,'DROP([[:print:]|[:cntrl:]])*INSERT INTO([[:print:]])*([ |[:cntrl:]])*(')

                            Também dá pra seguir o mesmo raciocínio do Braga, se o que você realmente quer é só o conteúdo após o ultimo INSERT.

                            Abraços,[/quote]

                            É, eu entendi. No meu caso tem esse padrão bem definido destas triggers de auditoria, por isso dá pra usar regexp.
                            Agora entendi como você fez para parar no primeiro (, primeiro pegou as letras apos o insert into… exigiu espaços em branco ou controle e em seguida pegou o (.
                            Bacana =)

                            #97580
                            burga
                            Participante

                              Isso mesmo, mas considerando que o padrão de código é de que logo após o “INSERT INTO” venha o “OWNER.TABELA” sem nenhum caractere de controle entre estas informações. Se tiver uma quebra de linha entre estas duas informações o padrão já não é o mesmo da expressão…

                              #97599
                              gsmdf
                              Participante

                                Quanto a isso não há problema , pois é um programinha que gera essas triggers de auditoria sempre neste formato, logo a formatação é bem rígida neste ponto, em relação a posição das instruções.
                                Se fossem triggers manuais ai seria complicado mesmo, teria de ser mais robusta, prever mais casos…

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