Fórum AutoIncremento DbExpress Duvidas no botao insert? #59036
30/10/2007
0
To com uma duvida sobre autroincremento com firebird 2.0 + DBExpress
Por ser um programa multicamadas resolvi fazer assim o autoincremento
Primeiro criei o autoincremento por um SP
CREATE PROCEDURE AUTO_SINDICATO RETURNS ( CODIGO INTEGER) AS begin codigo = GEN_ID(gen_sindicato_id,1); suspend; end
Ai no aplicativo tenho o trio de componentes SQLDataSet + DataSetProvider+ClientDataSet e um SQLStoreProc para chamar a SP
E no ClientdataSet no evento onAfterInsert coloquei para disparar a SP
procedure Tdm.cdsSindicatoAfterInsert(DataSet: TDataSet);
begin
{:Gerando o autoincremento do sindicato}
SPAutoSindicato.ExecProc;
cdsSindicato.FieldByName(´ID´).AsInteger:= SPAutoSindicato.Params[0].AsInteger;
end;Bom nenhum problema ai. O que eu percebi foi no botão de Insert no form, a cada clique no botão insert que eu faço ele incrementa o generators +1, só que se eu apertar no botão cancelar ele nao retorna o autoincremento.
vamos supor que ao cliclar em insert dispara a generatos para o autoincremento 18, ai eu não quero incluir e aperto no botão cancel, e novamente vou querer incluir o lançamento, em vez de pegar o 18 ele gera um novo no caso 19.
O button novo eu fiz assim
procedure TFHerdeiro.btnNovoClick(Sender: TObject);
begin
{:Muda o autoedit do DataSource para true}
dsHerdeiro.AutoEdit:=True;
{:Comandos para inserir um novo associado}
if not dsHerdeiro.DataSet.Active then
dsHerdeiro.dataset.open;
dsHerdeiro.dataset.append;
{:para que o scrollbox fique sempre no topo ao abrir}
ScrollBox1.VertScrollBar.Position:=0;
{:para sempre abrir no tabsheet2 ao incluir algum dados}
TabSheet2.Show;
end;e no botão cancel fiz assim
procedure TFHerdeiro.btncancelarClick(Sender: TObject); begin dsHerdeiro.DataSet.Cancel; (dsHerdeiro.DataSet as TClientDataSet).CancelUpdates; end;
Ta faltando algo ai para cancelar ou é assim mesmo?
Obrigado pessoal.
Adriano.
Adriano_servitec
Curtir tópico
+ 0Posts
31/10/2007
Gandalf.nho
Gostei + 0
02/11/2007
Adriano_servitec
Adriano.
Gostei + 0
03/11/2007
Sql.pedrojr
Gostei + 0
08/11/2007
Trampo
Na hora de gravar, verifica se o ID é negativo (foi pelo Insert) e aí então incrementa o trigger para substituir o número negativo pelo valor correto.
mande email em pvt que envio o codigo.
Jair
Gostei + 0
08/11/2007
Trampo
Na declaração:
private
fNomeID: Integer; /// guarda momentaneamente o ID com numero negativo
~~~~~~~~~~~~~~
no on create do datamodule e no afterApplyUpdate do dataset provider:
fNomeID := 0;
No On New RECORD do client data set) chamado pelo botão insert.
Dec( fNomeID );
cdsCliente.FieldByName(´NomeID´).asInteger := fNomeID;
no before update record do dataset provider:
procedure TDM.dspClientesBeforeUpdateRecord(Sender: TObject;
SourceDS: TDataSet; DeltaDS: TCustomClientDataSet;
UpdateKind: TUpdateKind; var Applied: Boolean);
var Qry:TSQLQuery;
begin
if UpdateKind = ukInsert then // é inserção
begin
Qry := TSQLQuery.Create(nil); {: cria uma instância do objeto}
try
Qry.SQLConnection := DM.SQLConnection1; {: componente de conexão}
if (SourceDS = QryCliente) then // é query PAI
begin
Qry.SQL.Clear;
Qry.SQL.add(´SELECT GEN_ID(SEQ_CADASTRO_NOMEID, 1) AS FNomeID_NOVO FROM rdb$database´);
Qry.Open;
try
fNomeID := Qry.Fieldbyname(´FNOMEID_Novo´).asInteger;
finally // fNOmeID é um campo static externo
Qry.Close;
end; // Atualiza no cds (poPropagateChanges = True)
DeltaDS.FieldbyName(´NomeID´).NewValue := fNomeID ;
end // Se for a tabela Mestre, acaba aqui
else // Selecionar todas tabelas detalhes
begin
{ O Provider já gravou a pai e agora gravará cada uma das filhas }
if (DeltaDS.FieldByName(´NOMEID´).asInteger < 0) then // inserção
DeltaDS.FieldByName(´NomeID´).NewValue := fNomeID; // atualiza todas as qry filhas
if ( SourceDS = QryVacinas ) then // atualiza ID em todas as filhas
begin
// Agora ajustar PK das filhas
if DeltaDS.FieldByName(´VACINAID´).asinteger < 0 then
begin // O valor do ID foi negativo
Qry.Close;
Qry.SQL.Clear;
Qry.SQL.Add(´select GEN_ID(GEN_VACINAS_ID, 1) as FID FROM rdb$database´);
Qry.Open;
try // Calcula o novo numero positivo baseado nos
fVacinaID := Qry.fieldbyname(´FID´).AsInteger;
finally // registros existentes utilizando o Sequence
Qry.Close;
end; // Passa para o cds como o novo valor
DeltaDS.FieldByName(´VACINAID´).NewValue := fVacinaID;
end;
end;
end;
finally
FreeAndNil(Qry);
end;
end; // end ukInsert
end;
O SEQ_CADASTRO_NOMEID deve ter o valor do último registro (NomeID) no arquivo de Cadastro se já contiver dados;
No exemplo uso uma tabela de cadastro e outra de vacinas tomadas pelo cadastrado (inventei esta).
Jair
Gostei + 0
09/11/2007
Adriano_servitec
Vou adaptar aqui.
Valeu.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)