Erro no Autoincremento
23/07/2008
0
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.
Eduardocar83
Posts
23/07/2008
Jeancamila
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
23/07/2008
Marco Salles
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
24/07/2008
Eduardocar83
24/07/2008
Eduardocar83
24/07/2008
Marco Salles
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
24/07/2008
Eduardocar83
Clique aqui para fazer login e interagir na Comunidade :)