[Resolvido] Novo valor do campo indisponível depois do post
Olá pessoal,
Não achei nada no fórum, então estou criando esse tópico novo.
Tenho o seguinte cenário:
- Aplicação em Delphi 7
- BD Firebird 1.5
- Componentes de acesso da aba Interbase (do próprio Delphi 7)
- Estou criando um cadastro de fornecedores
- Tabela de fornecedores com campo-chave autoincremental (feito por um Generator e por uma Trigger)
BOTÃO INCLUIR
dm.ibtFornecedores.insert;
dm.ibtFornecedoresFORDATACADASTRO.AsString := datadosistema;
dm.ibtFornecedoresFORDATAATUALIZACAO.AsString := datadosistema;
dm.ibtFornecedoresFORSTATUS.AsString := 'A';
BOTÃO GRAVAR
// Operações
try
if not dm.itrTransa.InTransaction then
dm.itrTransa.StartTransaction;
dm.ibtFornecedores.post;
// LOG
codigo := dm.ibtFornecedoresFORCODIGO.Value;
insereLog ('Inclusão do fornecedor nº '+inttostr(codigo));
dm.itrTransa.CommitRetaining;
except
MessageDlg('ATENÇÃO!!! Ocorreu um erro na operação.'+#13+
'Comunique imediatamente o suporte técnico.'+#13#13+
'Será gravado um arquivo de log contendo maiores informações.',mtError,[mbOK],0);
CriarLogErro(datadosistema, horadosistema, sExceptionAcao, 'Tentou incluir o fornecedor nº '+inttostr(codigo));
dm.itrTransa.Rollback;
end;
Acontece que, no Botão GRAVAR, na linha onde a variável 'codigo' recebe o FORCODIGO, dm.ibtFornecedoresFORCODIGO.Value chega como 0 (zero). Ou seja, não consigo pegar o valor de FORCODIGO que foi gerado automaticamente para usa-lo no meu sistema de Log. Olhei no IBExpert e a Trigger e o Generator estão funcionando certinhos, o campo FORCODIGO recebe o valor de maneira correta se eu incluo um registro pelo IBExpert.
Na minha TIBTable, tenho todos os campos adicionados. No campo referente ao FORCODIGO, as propriedades são Required = false, AutoGenerateValue = arNone (já tentei com arAutoInc), ProviderFlags = [pfInUpdate,pfInWhere] (já tentei com [pfInWhere]).
Percebi, também, uma coisa. Quando navego com os comandos First, Prior, Next e Last, percebo que o novo registro que inclui aparece na segunda posição (pois usei o Insert) e TAMBÉM na última posição!!! Depurando, detectei que a primeira cópia do registro tem FORCODIGO = 0 e a segunda cópia tem o FORCODIGO correto. Troquei o Insert por Append e aparece apenas uma cópia do registro, mas com FORCODIGO = 0.
Testes que eu fiz: forcei um commit (com o Evaluate/Modify, CTRL+F7) mas não fez nada. Forcei um Refresh na tabela e aí deu certo, mas o ponteiro volta pro primeiro registro. E mesmo assim, não consigo pegar o código do registro inserido, pra usar no Log.
E aí, alguém pode me dar uma luz? :(
Olá pessoal,
Identifiquei que se trata de um problema conhecido no Firebird e em outros bancos. O SGBD não retorna nada para a aplicação depois do Post, com isso só consigo recuperar o ID através de um Refresh e um Last na IBTable. Mas isso é gambiarra e pode gerar erros, por exemplo, quando muitos usuários estiverem usando o sistema e mais de um registro for incluído simultâneamente. No intervalo de tempo, 2 registro poderiam ser gravados e um mesmo "ULTIMO_ID" poderia ser informado para os 2 usuários que fizeram a gravação. Pra mim seria um problema, pois furaria meu sistema de Log.
No SQL Server, eu resolveria com um "SELECT @@IDENTITY". Já com o MySQL, eu resolveria com um "SELECT LAST_INSERT_ID()". Para ambos, o "ULTIMO_ID" seria retornado por conexão, impedindo o problema de concorrência. Mas não tô achando nada desse tipo para Firebird. Alguém conhece algo assim?
Uma alternativa menos "improvisada" seria forçar o GENERATOR a fornecer o novo ID e atribuí-lo diretamente ao campo, antes do post. Mas vocês devem concordar comigo que isso não é o ideal, né? Senão, pra que serviria a TRIGGER? Praticamente não seria mais usada.
E aí, alguém pode me ajudar?
:)
Discussão (1)
Carregando comentários...