Salvar Data e Campo alterado no DB

Delphi

15/09/2015

Olá amigos, estou querendo criar um histórico de alterações dos registros do sistema, criei campos com <data, hora e Membro(Usuário)> que inclui o registro e data, hora e de que membro que foi alterado registros.

Como poderia criar uma rotina que fizesse isso automaticamente, sem precisar que eu tenha que inserir os dados manualmente?

Grato

Allan
Allan

Allan

Curtidas 0

Melhor post

Luiz Freitas

Luiz Freitas

16/09/2015

Olá Allan,

O que você precisa pode ser realizado com uma Trigger no banco de dados.
GOSTEI 1

Mais Respostas

Allan

Allan

15/09/2015

Luiz, obrigado.
poderias dá um exemplo?
to quebrando a cabeça desde ontem....
GOSTEI 0
Luiz Freitas

Luiz Freitas

15/09/2015

Qual banco de dados você utiliza Allan?
GOSTEI 0
Allan

Allan

15/09/2015

Access
GOSTEI 0
Jothaz

Jothaz

15/09/2015

Access


Qual versão?
GOSTEI 0
Allan

Allan

15/09/2015

2007
GOSTEI 0
Jothaz

Jothaz

15/09/2015

No Access não existem triggers.

Nas versões iguais ou superiores a 2010 você pode simular triggers utilizando Data Macros.

Dê uma pesquisada no Pai Google que você achará exemplos.
GOSTEI 0
Allan

Allan

15/09/2015

Então, eu deveria tipo, trocar de banco de dados pra poder salvar um histórico (log)?
GOSTEI 0
Jothaz

Jothaz

15/09/2015

Isto que deve deve decidir é você.

Nesta versão que você esta utilizando não tem como implementar trigger ou Data Macros, então teria de mudar para a versão 2010
ou mudar para um banco de dados tpagos: SQL Server ou Oracle ou gratis: PostgreSQL, Maria DB ou MySql.

Agora somente você terá poderá decidir se você terá capacidade de utilizar outro bacno de dados ou mesmo qual o impacto da mudança.
GOSTEI 1
Allan

Allan

15/09/2015

ok amigo, Obrigado.
GOSTEI 0
Fabio Cardoso

Fabio Cardoso

15/09/2015

Alan pelo que entendi você quer criar uma rotina que qualquer alteração feita no seu banco vc fique sabendo é isso?
Você quer essa rotina direto no banco ou seria um procedimento via delphi mesmo?

Porque via Delphi não precisa de mudança nenhuma de banco de dados. podemos desenvolver uma ideia aqui
você quer via delphi ou banco?
GOSTEI 1
Allan

Allan

15/09/2015

Isso mesmo Fabio. quero tipo criar um histórico. que quando for feita alterações no banco crie um histórico...
então, queria de preferencia via banco, mas também pode ser via Delphi.
GOSTEI 0
Luiz Freitas

Luiz Freitas

15/09/2015

Olá Allan,

Realmente, a maneira mais simples de fazer o que você precisa é utilizando trigger, mas como o db que você está utilizando não as suporta, nada impede que o trabalho seja realizado diretamente pelo delphi.

Então, criando uma procedure (ou function, depende se você vai querer algum retorno, ou não) com o código necessário para gravar nesta tabela de log, é só chamar essa procedure nas inclusões e a cada alteração.

Compartilha a estrutura da tabela na qual você vai armazenar os logs que, como o Fábio disse, te auxiliamos na criação dessa procedure, se você precisar de ajudar.
GOSTEI 0
Allan

Allan

15/09/2015

Então Luiz, eu criei uma tabela TB_CACHE com os campos COD, ALTERACAO, CLIENTE, DATA, HORA.
recebendo o campo que foi alterado de qual cliente e quando.
GOSTEI 0
Luiz Freitas

Luiz Freitas

15/09/2015

Então Luiz, eu criei uma tabela TB_CACHE com os campos COD, ALTERACAO, CLIENTE, DATA, HORA.
recebendo o campo que foi alterado de qual cliente e quando.


Olá Allan, boa tarde!

Blz! Vamos lá:

Se você estiver utilizando um DataModule (provavelmente sim) declare um procedimento como este (declara em Public, assim fica visível em todos os formulários que estiverem fazendo uso do seu DataModule):
public
  procedure GravaLog(pCampo, pCliente: string; pData, pHora: tDateTime);
  { Public declarations }


E implementa assim, caso você esteja utilizado os componentes ADO (a lógica é a mesma, caso você esteja utilizando outros componentes de acesso a dados):
procedure TDataModule.GravaLog(pCampo, pCliente: string; pData, pHora: tDateTime);
begin

  qryTB_CACHE.SQL.Clear;
  qryTB_CACHE.SQL.Add('insert into TB_CACHE(ALTERACAO, CLIENTE, DATA, HORA)');
  qryTB_CACHE.SQL.Add('values(' +quotedStr(pCampo) + ', '
                                +quotedStr(pCliente) + ', '
                                +'#' +formatDateTime('yyyy/MM/dd', pData) +'#' +', '
                                +quotedStr(formatDateTime('hh:mm:ss', pHora)) + ')');
  qryTB_CACHE.SQL.SaveToFile('d:\teste-sql.txt');
  qryTB_CACHE.ExecSQL;

  //obs:
  //deduzi que o campo COD seja auto incremento
end;


Utilize toda vez que realizar uma alteração:
  GravaLog('CIDADE', 'LUIZ', Date, Time);


Não sei exatamente como você está trabalhando, talvez já tenha essas informações em outro lugar, mas acredito que faltam campos para você identificar, principalmente, de qual tabela é o campo sendo alterado e a qual registro alterado na tabela aquele log pertence.

É uma ideia básica pra você tentar solucionar o problema ai... espero que te dê uma base pra conseguir o que precisa.

Qualquer coisa, sinta-se a vontade para perguntar.

t++
GOSTEI 1
Allan

Allan

15/09/2015

Olá Luiz, deixa ver se entendi direito.
Eu declaro a procedure publica GravaLog no DM, e a TDataModule.GravaLog eu chamo No envento do botão, ou num evento da table?

Desculpe por minha ignorância.
GOSTEI 0
Allan

Allan

15/09/2015

fiz o seguinte
unit UDM;
interface
uses
  SysUtils, Classes, DB, ADODB, Provider, DBClient;

type
  TDM = class(TDataModule)
    Conexao: TADOConnection;
    TB_CLIENTES: TADOTable;
    Ds_TB_CLIENTES: TDataSource;
    Tb_clintesMcodigo: TAutoIncField;
    Tb_clientesFcodigo: TIntegerField;
    ........
  private
    { Private declarations }
  public
procedure GravaLog(pCampo, pMembroe: string; pData, pHora: tDateTime);
  { Public declarations }
{procedure TDM.Gravalog(pCampo, pCliente: string; pData, pHora: tDateTime);
  { Public declarations }
  end;

var    DM: TDM;
implementation

uses UCadClientes;
{$R *.dfm}
procedure TDM.Tab_ClientesBeforePost(DataSet: TDataSet);
begin
  qryTb_Cache.SQL.Clear;
  qryTb_Cache.SQL.Add('insert into Tab_Cache(Alteracao, Clinte, Data, Hora)');
  qryTb_Cache.SQL.Add('values(' +quotedStr(pCampo) + ', '+quotedStr(pCliente) + ', '+'#' +formatDateTime('yyyy/MM/dd', pData) +'#' +', '+quotedStr(formatDateTime('hh:mm:ss', pHora)) + ')');
  qryTb_Cache.SQL.SaveToFile('d:\teste-sql.txt');
  qryTb_Cache.ExecSQL;
end;

procedure TDataModule.GravaLog(pCampo, pCliente: string; pData, pHora: tDateTime);
begin

  qryTB_CACHE.SQL.Clear;
  qryTB_CACHE.SQL.Add('insert into TB_CACHE(ALTERACAO, CLIENTE, DATA, HORA)');
  qryTB_CACHE.SQL.Add('values(' +quotedStr(pCampo) + ', '+quotedStr(pCliente) + ', '+'#' +formatDateTime('yyyy/MM/dd', pData) +'#' +', '+quotedStr(formatDateTime('hh:mm:ss', pHora)) + ')');
  qryTB_CACHE.SQL.SaveToFile('d:\teste-sql.txt');
  qryTB_CACHE.ExecSQL;
end;                                       
end.
GOSTEI 0
Luiz Freitas

Luiz Freitas

15/09/2015

Olá Allan, tudo bem?

Quase isso, mas seria mais como isso aqui:

unit UDM;

interface

uses
  SysUtils, Classes, DB, ADODB, Provider, DBClient;
 
type
  TDM = class(TDataModule)
    Conexao: TADOConnection;
    TB_CLIENTES: TADOTable;
    Ds_TB_CLIENTES: TDataSource;
    Tb_clintesMcodigo: TAutoIncField;
    Tb_clientesFcodigo: TIntegerField;
    ........
  private
    { Private declarations }
  public
    procedure GravaLog(pCampo, pMembroe: string; pData, pHora: tDateTime);
  { Public declarations }
  end;
 
var
  DM: TDM;

implementation
 
  uses UCadClientes;

{$R *.dfm}

procedure TDM.Tab_ClientesBeforePost(DataSet: TDataSet);
begin
  
  GravarLog('CIDADE', 'Allan', Date, Time);
end;
 
procedure TDM.GravaLog(pCampo, pCliente: string; pData, pHora: tDateTime);
begin
 
  qryTB_CACHE.SQL.Clear;
  qryTB_CACHE.SQL.Add('insert into TB_CACHE(ALTERACAO, CLIENTE, DATA, HORA)');
  qryTB_CACHE.SQL.Add('values(' +quotedStr(pCampo) + ', '+quotedStr(pCliente) + ', '+'#' +formatDateTime('yyyy/MM/dd', pData) +'#' +', '+quotedStr(formatDateTime('hh:mm:ss', pHora)) + ')');
  qryTB_CACHE.ExecSQL;
end;                                       

end.
GOSTEI 0
Allan

Allan

15/09/2015

Então Luiz, ele ta respondendo com os seguintes erros:

[Error] UDM.pas(157): Undeclared identifier: 'qryTB_CACHE'

e já declarei "Variants" na clausula USES...
GOSTEI 0
Luiz Freitas

Luiz Freitas

15/09/2015

Olá Allan, blz?

Fiz um exemplo, bem básico, que pode ser melhorado, e que vai te dar uma boa base pra fazer o que precisa.

Do jeito que ele está acredito que já vai te atender, mas sempre dá pra melhorar um código neh... :)

gravaLogAccess.rar

Se tiver dúvida em algum ponto do projeto me avisa.
GOSTEI 1
Allan

Allan

15/09/2015

Obrigado pela força.
Mas então, a propriedade String sql eu vou precisar usar alguma?
GOSTEI 0
Luiz Freitas

Luiz Freitas

15/09/2015

Tranquilo Allan! :)

Em qual situação? Dê um exemplo da sua questão relacionada "a propriedade String sql"?
GOSTEI 0
Allan

Allan

15/09/2015

Ol¨¢, desculpe pela demora, mas a respeito da sql ja vi aqui. obrigado por tudo. :)
GOSTEI 0
Luiz Freitas

Luiz Freitas

15/09/2015

Que bom que deu tudo certo Allan!

Qualquer coisa, no que for possível, estamos aqui para ajudar!
GOSTEI 0
POSTAR