Erro no Autoincremento

23/07/2008

1

Boa tarde pessoal, estou fazendo cadastro de Estados, com autoincremento e utilizando dbexpress, a tabela e a seguinte

Estados
Codigo: integer not null primary key
Nome : varchar not null

na primeira vez que insiro, tudo ok, na segunda vez da um erro Violation key. Tenho que fechar e abrir denovo o programa, e so inserir um.

Estou utilizando firebird, com generator e trigger para autoincremento, e no delphi sqldataset+datasetprovider+ClientDataSet. O ClientDataSet e SqlDataSet com o campo Codigo como nao requerido. Atualizo cada vez que insiro um estado com applyupdates do ClientDataSet.

Sera que alguem me da uma luz, obrigado antecipadamente.


Responder

Posts

23/07/2008

Jeancamila

Eduardo,

Para resolver esse problema eu fiz no meu DataModule a seguinte function onde eu mando o nome do generator criado da tabela e ele me retorna o id gerado. Eu o utilizo no OnNewRecord do ClientDataSet (o OnNewRecord pode ser utilizado em qualquer componente que herde de TDataSet dentro do dbExpress).

Function TDm.RetornaChaveFirebird(Indice: String): Integer;
var
{Declarando a query que sera utilizada para pegar o valor gerado.}
QryId: TSQLQuery;
begin
{Instanciado o objeto.}
QryId := TSQLQuery.Create(nil);
try
{Preparando a query para a execução}
QryId.SQLConnection := Conexao;
{SQL que irá pegar o registro gerado, dado onome do generator da tabela.}
QryId.SQL.Add(´SELECT GEN_ID(´ + Indice +´,1) AS ID_RET FROM RDB$DATABASE´);
QryId.Open;
if QryId.IsEmpty then
{Não ocorreu geração, por isso o cadastro não pode continuar.}
raise Exception.Create(´Não foi criado nenhum valor.´)
else
{Retornando o valor gerado.}
result := QryId.FieldByName(´ID_RET´).AsInteger;
finally
{Apos o uso da query, liberando a memoria.}
QryId.Free;
end;
end;

Ja no DataSet uso assim.

procedure TFrmProduto.CdsPadraoNewRecord(DataSet: TDataSet);
begin
inherited;
{Pegando o valor incrementado no banco}
CdsPadrao.FieldByName(´PRO_CODIGO´).AsInteger := Dm.RetornaChaveFirebird(´gen_produto_id´);
end;

Espero que ajude.

JEan


Responder

23/07/2008

Marco Salles

Estou utilizando firebird, com generator e trigger para autoincremento, e no delphi sqldataset+datasetprovider+ClientDataSet. O [b:018133f02d]ClientDataSet e SqlDataSet com o campo Codigo como nao requerido[/b:018133f02d]. Atualizo cada vez que insiro um estado com applyupdates do ClientDataSet.


Teoricamente voce fez correto . Claro que tem a opção
FROM RDB$DATABASE passada anteriormente pelo amigo jeancamila

Mas o que pode estar ocorrendo com a sua ´maneira´ de fazer .

Voce por acaso disse ao DataSetProvider que a Chave Primária So será Utilizada em Updades e Delites ????
Isto porque o DataSet Provider ira procurar pela Propriedade UpdateMode para identificar como este Registro são Atualizados.
E na sua propriedade deve estar cetada como padrão upWhereAll


Responder

24/07/2008

Eduardocar83

Valeu amigos, resolvi do jeito que falou jeamcamila. Agora analizando o que falou marco salles, e verdade a propriedade datasetprovider.updatemode esta setada como upWhereAll. Mas pelo que eu entendo so vou precissar disso na hora de excluir ou modificar. O meu problema era na hora de inserir, me corrija se estou errado. Muito obrigado.


Responder

24/07/2008

Eduardocar83

Descobri outra coisa, fazendo do meu jeito, aquele primeiro que tava dando problemas, so com fechar e abrir o clientdataset resolve. Naum entendo, sera porque ficavam dois Estados com codigo NULL, dae seu fecho e abro, ja ela traz o primeiro estado com seu codigo gerado no autoincremento. ??


Responder

24/07/2008

Marco Salles

com eu disse anteriormente eduardocar83 , usando a Sql
FROM RDB$DATABASE
voce obtem em rum Time o valor do ID_Gerado

Disse tb que teoricamente seus procedimentos ( campo Codigo como nao requerido ) estão corretos e pensei [u:259523b4cf]erradamente [/u:259523b4cf]que a não configuração da [b:259523b4cf]Propriedade UpdateMode [/b:259523b4cf]do DataSetProvider de
[u:259523b4cf]upWhereAll para upWhereKeyOnly[/u:259523b4cf] poderia ser uma causa deste tipo de erro ... Ja que teoricamente o DataSet ira procurar pela Propriedade
UpdateMode para saber como esses registros saõ Atualizados
e na propriedade upWhereAll diz para Procurar por todos os Campos
Como Id_codigo não é requerido , poderia causar o ERRO .

Resolvi fazer um exemplo Rápido com os Campos de Sua Tabela e [u:259523b4cf]foi indiferente alterar ou não a propriedade UpdateMode [/u:259523b4cf]...
Também digo que comigo [b:259523b4cf]funcionou somente colocar os procedimentos
campo Codigo como nao requerido no ClientDataSet e no SqlQuery[/b:259523b4cf]
então não precisei usar o FROM RDB$DATABASE ´[color=darkred:259523b4cf] Vai entender [/color:259523b4cf]´

Porém , [b:259523b4cf]independentemente de funcionar ou não [/b:259523b4cf], a correta configuração dos ProvidersFlags e do UpdateMode da DataSetProvider , apesar de sua tabela ser pequena e aparentemente não notar diferença , é recomendado pelas biografias alegando que a astrução SQL a ser Resolvida devido parametrização é [b:259523b4cf]Otimização[/b:259523b4cf] ... Em um ambiente mais severo estas Alteraçoes podem resultar em performance e ganho


Responder

24/07/2008

Eduardocar83

Muito obrigado por sua ajuda Marco Salles, gostaria de perguntar uma coisa mais. Se minha aplicaçao estiver em redes, todos os usuarios tem um clientdataset com os Estados trazidos do servidor, se alguem adicionar um estado, como eu faço para atualizar automaticamente os clientdataset de todos??


Responder

24/07/2008

Marco Salles

é so fechar e abrir o clientDataSet


Responder
×
+1 DevUP
Acesso diário, +1 DevUP
Parabéns, você está investindo na sua carreira