Fórum Ajuda em montar código #429711

26/11/2012

0

Ola galera do DevMedia....estou eu novamente aqui pedindo ajuda em montar um código para evitar Key Violation. O banco de dados é PIRADOX, o campo de código é alfanumérico, o sistema funciona em rede e dá Key Violation quando duas máquinas tentam cadastrar um serviço ao mesmo tempo. Uma grava e a outra dá erro. Tentei montar de varias formas (sou iniciante e to aprendendo na raça mesmo) mas nenhuma me deu um resultado satisfatório, o que chegou mais perto fica saltando um valor tipo, pula do 000130 para o 000132 e assim vai.

O código, se possível, seria para reconhecer se vai dar o erro, se sim, pegaria o último valor da tabela e adicionaria 1 e gravaria. Na internet achei esse código e tentei coloca-lo funcional para mim, mas dá erro de compatibilidade entre String e Integer já que o campo de código é alfanumerico.

try
dm01.tbl_servico.Post;
except
on E:EDBEngineError do
if E.Errors[0].ErrorCode = 9729 then
dm01.tbl_servicoOS_COD.AsInteger := dm01.tbl_servicoOS_COD.AsInteger + 1;
end;


Alguém pode me ajudar?
Carlos Magno

Carlos Magno

Responder

Posts

26/11/2012

Luiz Menin

Tu poderia realizar uma consulta ao clicar no botão salvar, por exemplo.
Adicione um TQuery.
SQLQuery.Close;
SQLQuery.SQL.Clear;
SQLQuery.SQL.Add('SELECT MAX(CODIGO) AS TOTAL FROM TABELA');
SQLQuery.ExecSQL();
SQLQuery.Open;
iMaxCod := SQLQuery.FieldByName('TOTAL').AsInteger + 1;


Atribui o valor da variavel criada (iMaxCod) ao campo código.
Espero ter ajudado.
Responder

Gostei + 0

26/11/2012

Carlos Magno

Luis...não testei o seu modo, mas tentei esse outro modo. Criei um dataset para a mesma tabela nomeando-a para servaux. Na compilação ele passou, mas quando cliquei no botão salvar congelou tudo. Veja o código e me diz onde posso estar errando:

var
codi:String[6];
begin
dm01.tbl_servaux.Last;
dm01.tbl_servicoOS_COD.AsString := inttostr(dm01.tbl_servauxOS_COD.AsInteger + 1);
while Length(dm01.tbl_servicoOS_COD.AsString) <6 do
codi:='0' + dm01.tbl_servicoOS_COD.AsString;
dm01.tbl_servico.Post;
Responder

Gostei + 0

26/11/2012

Luiz Menin

Pode informar que tipo de erro ocorreu?
Responder

Gostei + 0

26/11/2012

Luiz Menin

Não recomendo utilizar este seu método, pois caso você utilize qualquer tipo de ordenação diferente da por chave primaria, você provavelmente vai enfrentar problemas.
Responder

Gostei + 0

26/11/2012

Carlos Magno

O erro que ocorreu foi justamente que congelou a compilação, tive de encerrar usando o Ctrl-Alt-Del, e o Delphi, mesmo dando o stop, não retornou para o modo de codificação.
Responder

Gostei + 0

26/11/2012

Claudia Nogueira

Esse while está em loop infinito, pois você usou o length no dm01.tbl_servicoOS_COD.AsString e ele não altera dentro do while.

codi := dm01.tbl_servicoOS_COD.AsString;
while Length(codi ) <6 do
codi:='0' + dm01.tbl_servicoOS_COD.AsString;


Luis...não testei o seu modo, mas tentei esse outro modo. Criei um dataset para a mesma tabela nomeando-a para servaux. Na compilação ele passou, mas quando cliquei no botão salvar congelou tudo. Veja o código e me diz onde posso estar errando:

var
codi:String[6];
begin
dm01.tbl_servaux.Last;
dm01.tbl_servicoOS_COD.AsString := inttostr(dm01.tbl_servauxOS_COD.AsInteger + 1);
while Length(dm01.tbl_servicoOS_COD.AsString) <6 do
codi:='0' + dm01.tbl_servicoOS_COD.AsString;
dm01.tbl_servico.Post;
Responder

Gostei + 0

27/11/2012

Carlos Bernardo

try
dm01.tbl_servico.Post;
except
on E:EDBEngineError do
if E.Errors[0].ErrorCode = 9729 then
dm01.tbl_servicoOS_COD.AsInteger := dm01.tbl_servicoOS_COD.AsInteger + 1;
end;


Amigo vamos tentar assim :

Cria uma funcao que retorne o proximo numero livre...

function retorna_maxCodigo : string;
var
  QRY :TQuery;
begin
  Qry := TQuery.Create(self);
  with qry do
  TRY
    DatabaseName := SEU_ALIAS;
    sql.Add('Select max(OS_COD) as CODMAX from nomedatabela');
    Open;
    Result := formatfloat('000000',Qry.FieldByName('CODMAX').Asfloat + 1);
  FINALLY
    QRY.free;
  END; 
end;



antes de dar o POST vc usa assim

dm01.tbl_servicoOS_COD.AsString := retorna_maxCodigo;
dm01.tbl_servicos.POST;

A unit DBTables, tem que estar declarada na clausula Uses
Responder

Gostei + 0

27/11/2012

Alisson Santos

Bom vamos a regra, o campo que vai receber esse valor é inteiro.
Se ele for campo inteiro como creio que seja ele não vai gravar os zeros na frente então ao invés de ficar 000123 ele vai aparecer apenas o 123, para que ele apareça os zeros na frente o campo tem que ser string.

Da maneira que nosso amigo acima está informando não precisa colocar os zeros e sim apenas trazer como resultado o campo adicionando +1.
Responder

Gostei + 0

27/11/2012

Carlos Magno

Carlos, ou diria, xará, rsrsrs.....deu erro na linha abaixo:
Qry := TQuery.Create(self);

Erro reportado: Undeclared indentifier: 'self';
Responder

Gostei + 0

27/11/2012

Carlos Magno

Alisson....o campo não é inteiro...é alfanumérico
Responder

Gostei + 0

27/11/2012

Carlos Magno

Galera, achei uma forma de chegar mais perto onde eu quero. Usei uma TQuery para pegar o MAX, adicionar mais um 1 e gravar. Só que ao gravar, só vai o número gerado, tipo assim, se é para gerar o número 000025, só vai o 25 sem os 0000.

Como faço para adicionar os zeros?

Segue o código, favor verificar se esta certo:
dm01.qr_servcodMAXOFOS_COD.AsString;
dm01.tbl_servicoOS_COD.AsString := IntToStr(dm01.qr_servcodMAXOFOS_COD.AsInteger + 1);
dm01.tbl_servico.Post;
Responder

Gostei + 0

27/11/2012

William

Tenta assim:

dm01.tbl_servicoOS_COD.AsString := FormatFloat('0000', dm01.qr_servcodMAXOFOS_COD.AsInteger + 1);
Responder

Gostei + 0

27/11/2012

Carlos Bernardo

Desculpa

troca essa linha Qry := TQuery.Create(self);
por essa Qry := TQuery.Create(nil);
Responder

Gostei + 0

28/11/2012

Carlos Magno

William, sua dica funcionou legal, agora so falta fazer o teste em rede com duas máquinas efetuando cadastros ao mesmo tempo e ver se não dá erro de KEY VIOLATION.

Assim que concluir os testes eu retorno para dizer se deu certo ou não.
Responder

Gostei + 0

28/11/2012

Carlos Magno

William...gravou, mas ainda deu erro de KEY VIOLATION.
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar