Clipper On Line • Ver Tópico - Rotina de Auditoria para SGBD

Rotina de Auditoria para SGBD

Discussão sobre SQL

Moderador: Moderadores

 

Rotina de Auditoria para SGBD

Mensagempor asimoes » 26 Fev 2020 08:34

Pessoal,

Estou migrando para um SGDB, escolhi o MariaDb, no momento usando o ADS da SYBASE como ponte na construção das query´s, tenho uma função de auditora de dados no DBF, onde comparo os campos do registro atual com o modificado, como fazer isso agora ?
â–ºHarbour 3.x | Minigui xx-x | HwGuiâ—„
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Rotina de Auditoria para SGBD

Mensagempor JoséQuintas » 26 Fev 2020 09:47

Sugestão:

Toda tabela tem uma chave.
cria uma rotina pra pegar o registro e comparar.

Uma primeira rotina salva num array
Uma segunda rotina comparara esse array com o array atual.

Registro:Salva( "tabela", "chave" )

atualiza

Registro:Compara( "tabela", "chave" )
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina de Auditoria para SGBD

Mensagempor alxsts » 26 Fev 2020 10:30

Olá!

Use triggers...
[]´s
Alexandre Santos (AlxSts)
alxsts
Colaborador

Colaborador
 
Mensagens: 2943
Data de registro: 12 Ago 2008 15:50
Cidade/Estado: São Paulo-SP-Brasil
Curtiu: 21 vezes
Mens.Curtidas: 248 vezes

Rotina de Auditoria para SGBD

Mensagempor asimoes » 26 Fev 2020 13:16

alxsts escreveu:Olá!

Use triggers...


Ainda não migrei para o MariaDb, estou na fase de troca de sintaxe paa acessar o dbf, via sql

Quintas tens algum exemplo ?
â–ºHarbour 3.x | Minigui xx-x | HwGuiâ—„
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Rotina de Auditoria para SGBD

Mensagempor asimoes » 26 Fev 2020 13:23

JoséQuintas escreveu:Sugestão:

Toda tabela tem uma chave.
cria uma rotina pra pegar o registro e comparar.

Uma primeira rotina salva num array
Uma segunda rotina comparara esse array com o array atual.

Registro:Salva( "tabela", "chave" )

atualiza

Registro:Compara( "tabela", "chave" )


Tenho uma rotina que é uma grid onde e o usuário pode excluir qq linha dessa grid que persiste no dbf, antes de auditar faço um set deleted off pra poder pegar o registro deletado, depois faço set deleted on, acontece que com o ads não tem isso, não funciona o set deleted off pra poder pegar o deleted do dbf
â–ºHarbour 3.x | Minigui xx-x | HwGuiâ—„
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Rotina de Auditoria para SGBD

Mensagempor JoséQuintas » 26 Fev 2020 13:37

ainda estou adaptando, mas de um modo geral é salvar no array.

CREATE CLASS ADORecValueClass

   VAR aValues

   METHOD New( cnMySql )
   METHOD WriteLog( cTable, cKeyName, xKeyValue )

   ENDCLASS

METHOD New( cnMySql ) CLASS ADORecValueClass

   LOCAL nCont

   ::aValues := {}
   IF cnMySql != NIL
      WITH OBJECT cnMySql
         FOR nCont = 1 TO :FCount()
            AAdd( ::aValues, :String( nCont - 1 ) )
         NEXT
      ENDWITH
   ENDIF

   RETURN SELF

METHOD WriteLog( cTable, cKeyName, xKeyValue ) CLASS ADORecValueClass

   LOCAL nCont, cnMySql := ADOClass():New( AppConexao() )

   IF AppConexao() == NIL
      RETURN NIL
   ENDIF
   WITH OBJECT cnMySql
      :cSql := "SELECT * FROM " + cTable + " WHERE " + cKeyName + " = " + NumberSql( xKeyValue )
      :Execute()
      IF ! :Eof()
         FOR nCont = 1 TO :FCount()
            IF ! "INFINC" $ :FName( nCont - 1 ) .AND. ! "INFALT" $ :FName( nCont - 1 ) ;
               .AND. ! ::aValues[ nCont ] == :String( nCont - 1 )
               GravaOcorrencia( cTable, StrZero( xKeyValue, 9 ), "ALTERADO " + :FName( nCont - 1 ) + ;
                  " de " + Transform( ::aValues[ nCont ], "" ) + ;
                  " para " + :String( nCont - 1 ) )
            ENDIF
         NEXT
      ENDIF
      :CloseRecordset()
   ENDWITH

   RETURN NIL

   // Alterado pra usar com MySQL a partir de DBF

CREATE CLASS DBFRecValueClass

   VAR  aValues

   METHOD WriteLog( xTable, xKey )
   METHOD Init()

   ENDCLASS

METHOD Init() CLASS DBFRecValueClass

   LOCAL nCont

   ::aValues := {}
   FOR nCont = 1 TO FCount()
      Aadd( ::aValues, FieldGet( nCont ) )
   NEXT

   RETURN NIL

METHOD WriteLog( xTable, xKey ) CLASS DBFRecValueClass

   LOCAL cAlias, cCodigo, nCont, cTexto

   IF ! xTable == NIL .AND. ! xKey == NIL
      FOR nCont = 1 TO FCount()
         cTexto := ""
         IF ::aValues[ nCont ] != FieldGet( nCont ) .AND. ! "INFINC" $ FieldName( nCont ) .AND. ! "INFALT" $ FieldName( nCont )
            cTexto += FieldName( nCont ) + " DE " + Trim( Transform( ::aValues[ nCont ], "" ) )
            cTexto += " PARA " + Trim( Transform( FieldGet( nCont ), "" ) )
            GravaOcorrencia( Upper( xTable ), xKey, cTexto )
         ENDIF
      NEXT
      RETURN NIL
   ENDIF

   cAlias := Lower( Alias() )
   DO CASE
   CASE cAlias == "jpcadastro" ; cCodigo := jpcadastro->idCadastro
   CASE cAlias == "jpfinan"    ; cCodigo := jpfinan->idFinan
   CASE cAlias == "jpitem"     ; cCodigo := jpitem->idProduto
   CASE cAlias == "jppedido"   ; cCodigo := jppedido->idPedido
   OTHERWISE
      cCodigo := ""
   ENDCASE
   IF Empty( cCodigo )
      RETURN NIL
   ENDIF
   FOR nCont = 1 TO FCount()
      cTexto := ""
      IF ::aValues[ nCont ] != FieldGet( nCont ) .AND. ! "INFINC" $ FieldName( nCont ) .AND. ! "INFALT" $ FieldName( nCont )
         cTexto += FieldName( nCont ) + " DE " + Trim( Transform( ::aValues[ nCont ], "" ) )
      ENDIF
      IF ! Empty( cTexto )
         GravaOcorrencia( Upper( Alias() ), cCodigo , cTexto )
      ENDIF
   NEXT

   RETURN NIL


Tenho em cada registro o INFINC e INFALT que é data de inclusão/alteração, então não comparo no log, senão sempre iria gravar.
Mas é como eu falei: cria um array antes, e compara com o array depois.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina de Auditoria para SGBD

Mensagempor JoséQuintas » 26 Fev 2020 13:41

Em DBF:

oRec := DBFRecValuesClass():New()
REPLACE .....
oRec:WriteLog( Alias(), chave )

No log vai registrar a tabela, a chave, e o que mudou.

Em ADO... aproveito o SELECT * que pega o registro atual... e passo a tabela/chave para a rotina buscar no MySQL depois.
Pensando em usar tabela/chave nos dois casos.

Uso isso também pra ter as "ocorrências" individuais.
Por exemplo: vai lá no cadastro de clientes número 10, e vê o histórico de tudo que foi alterado nele, só precisa da tabela e chave pra isso.

No log geral vê tudo.
No log do cliente, só vê o que tá como "cliente", código "10"
Simples e prático.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina de Auditoria para SGBD

Mensagempor JoséQuintas » 26 Fev 2020 13:51

asimoes escreveu:acontece que com o ads não tem isso, não funciona o set deleted off pra poder pegar o deleted do dbf


Até tem, mas não faço idéia de como faria o SELECT para os deletados.
Isso fica na string de conexão, e poderia ter uma conexão para os deletados.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina de Auditoria para SGBD

Mensagempor asimoes » 26 Fev 2020 16:09

JoséQuintas escreveu:Até tem, mas não faço idéia de como faria o SELECT para os deletados.
Isso fica na string de conexão, e poderia ter uma conexão para os deletados.

No MaySql, Oracle ou MariaDb, o delete from table, não tem como ver, o registro é seguido de um "pack" se errou ferrou!, por isso essas coisas tem que estar dentro de um controle de transação begintrans(), CommitTrans() e RollBackTrans() o driver OleDb da Ads não tem isso.
â–ºHarbour 3.x | Minigui xx-x | HwGuiâ—„
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Rotina de Auditoria para SGBD

Mensagempor alxsts » 26 Fev 2020 18:39

Olá!

asimoes escreveu:No MaySql, Oracle ou MariaDb, o delete from table, não tem como ver, o registro é seguido de um "pack" se errou ferrou!

alxsts escreveu:Use triggers...


Toda vez que um trigger é disparado, tem-se acesso à situação atual do registro e a situação futura (imagens OLD e NEW, também conhecidos como "before image" e "after image"). Um trigger pode ser disparado antes ou depois de um INSERT, UPDATE ou DELETE. É só tratar a situação conforme a necessidade.

What is a Trigger? (ADS)

Writing Triggers in SQL (ADS)

Trigger Overview MariaDB
[]´s
Alexandre Santos (AlxSts)
alxsts
Colaborador

Colaborador
 
Mensagens: 2943
Data de registro: 12 Ago 2008 15:50
Cidade/Estado: São Paulo-SP-Brasil
Curtiu: 21 vezes
Mens.Curtidas: 248 vezes

Rotina de Auditoria para SGBD

Mensagempor asimoes » 26 Fev 2020 19:21

Não faço a minima ideia como fazer uso de trigger do ads
â–ºHarbour 3.x | Minigui xx-x | HwGuiâ—„
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes




Retornar para SQL

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 7 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro