- Este tópico contém 13 respostas, 3 vozes e foi atualizado pela última vez 15 anos, 2 meses atrás por
gsmdf.
-
AutorPosts
-
5 de janeiro de 2011 às 12:45 am #97546
gsmdf
ParticipanteCaros 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 ROWDECLARE
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!
5 de janeiro de 2011 às 1:17 am #97548burga
ParticipanteDá 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 ROWDECLARE
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,
5 de janeiro de 2011 às 1:27 am #97549Marcos Braga
ParticipanteOlá,
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
Braga5 de janeiro de 2011 às 4:34 am #97551gsmdf
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 ROWDECLARE
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!
5 de janeiro de 2011 às 4:37 am #97552gsmdf
ParticipanteBraga,
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’ ??5 de janeiro de 2011 às 3:00 pm #97553gsmdf
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 !5 de janeiro de 2011 às 3:33 pm #97555burga
ParticipanteIsso 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.
🙂
5 de janeiro de 2011 às 8:27 pm #97563Marcos 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
Braga5 de janeiro de 2011 às 8:56 pm #97565Marcos Braga
Participanteaproveitando 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
Braga6 de janeiro de 2011 às 9:15 pm #97575gsmdf
ParticipantePessoal,
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
--
DECLAREV_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!
6 de janeiro de 2011 às 11:20 pm #97578burga
ParticipanteOi 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,
6 de janeiro de 2011 às 11:34 pm #97579gsmdf
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 =)7 de janeiro de 2011 às 12:45 am #97580burga
ParticipanteIsso 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…
10 de janeiro de 2011 às 5:39 pm #97599gsmdf
ParticipanteQuanto 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… -
AutorPosts
- Você deve fazer login para responder a este tópico.