Duvida com Chave primaria + DBEDIT

Delphi

17/11/2012

Galera seguinte, tenho no meu form 2 dbedits ligados cada um ao seu campo pelo datasource um deles é o código e outro é o nome, o campo código é auto incremento e chave primaria.

quando eu estou dentro do IBExpert dentro da Tabela na aba Data e vou preencher o campo nome somente, deixando o campo código vazio e dou um Commit o auto incremento funciona beleza.

No Delphi quando eu clico no botão novo ele executa o seguinte comando

DM1.ClientDataSet1.Insert;

e no botão Gravar ( depois de preencher somente o Nome, pois o Código é auto incremento eu deixo vazio)

o seguinte código DM1.ClientDataSet1.Post;
DM1.ClientDataSet1.ApplyUpdates(0);

quando clico em gravar ele me retorna um erro dizendo que o campo Código precisa ser inserido um valor.

se eu inserir esse valor manualmente ele grava beleza, porém gostaria de saber da maneira correta como que deixaria funcionando esse auto incremento sem precisar eu mesmo inserir o campo Código.

Caso alguém pergunte utilizo os seguintes componentes ( sqlconnection, sqlDataSet, DataSetProvider, ClientDataSet, DataModule )

Desde já agradeço.
Sublixo

Sublixo

Curtidas 0

Respostas

Claudia Nogueira

Claudia Nogueira

17/11/2012

No IbExpert o código é criado ao gravar e não quando insere por causa do trigger.
No delphi se você usa Query você tem que tirar o campo da sentença SQL do Insert e exluir o DBedit. Se usa Table tem que excluir dos fields e excluir o DBedit.
Desculpe os erros de digitação, pois estou no celular.
GOSTEI 0
Carlos Bernardo

Carlos Bernardo

17/11/2012

Amigo, olha a propriedade REQUIRED do field no SqlDataset e no ClientDataSet, e muda para false...
GOSTEI 0
Sublixo

Sublixo

17/11/2012

No IbExpert o código é criado ao gravar e não quando insere por causa do trigger.
No delphi se você usa Query você tem que tirar o campo da sentença SQL do Insert e exluir o DBedit. Se usa Table tem que excluir dos fields e excluir o DBedit.
Desculpe os erros de digitação, pois estou no celular.


Claudia, deu certinho, mais uma vez me salvando rsrsrsr obrigado, porém eu gostaria de mostrar apenas o registro que estaria sendo cadastrado, tem algum jeito?
GOSTEI 0
Sublixo

Sublixo

17/11/2012

Amigo, olha a propriedade REQUIRED do field no SqlDataset e no ClientDataSet, e muda para false...


Acabei descobrindo isso sem querer, deu certo tmb, porém ainda não consegui um método pra fazer aparecer o registro que sera inserido

ja tentei puxar o prox num do generator, mais ele faz certo da primeira vez, da segunda ele repete a da primeira, ja tentei puxar o .Last do ClientDataSet porem se eu excluir o ultimo vai dar Key Violation tmb
GOSTEI 0
Alisson Santos

Alisson Santos

17/11/2012

Poderia me explicar melhor o que está tentando fazer para eu ver o que posso fazer para auxiliar?
GOSTEI 0
Carlos Bernardo

Carlos Bernardo

17/11/2012

function Generator_ID(str_generator: string): integer;
var
QRY :TSqlQuery;
begin
Qry := TSQLQuery.Create(self);
Qry.SQLConnection := SuaConexao;
Qry.sql.Add('Select Gen_ID('+str_generator+',1) from RDB$DATABASE');
QRY.Open;
Result := Qry.Fields[0].AsInteger;
end;

No evento NewRecord do ClientDataSet vc usa:

CDS_Codigo.Value := Generator_ID(GEN_TABELA_ID);
GOSTEI 0
Sublixo

Sublixo

17/11/2012

Poderia me explicar melhor o que está tentando fazer para eu ver o que posso fazer para auxiliar?


Explico, ao dar o insert eu gostaria que o campo DBEdtCodigo que esta ligado ao campo COD_TIPO dentro da tabela mostrasse o prox numero de registro.
GOSTEI 0
Sublixo

Sublixo

17/11/2012

function Generator_ID(str_generator: string): integer;
var
QRY :TSqlQuery;
begin
Qry := TSQLQuery.Create(self);
Qry.SQLConnection := SuaConexao;
Qry.sql.Add('Select Gen_ID('+str_generator+',1) from RDB$DATABASE');
QRY.Open;
Result := Qry.Fields[0].AsInteger;
end;

No evento NewRecord do ClientDataSet vc usa:

CDS_Codigo.Value := Generator_ID(GEN_TABELA_ID);


me apresentou erro no Self da linha " Qry := TSQLQuery.Create(self); "

outra duvida a function eu coloco no datamodule?
GOSTEI 0
Claudia Nogueira

Claudia Nogueira

17/11/2012

Provavelmente você tem uma Trigger + generator, pois quando você grava ele gera automaticamente o valor para chave primária. Então pra você conseguir fazer isso você deve desativar a trigger, pois se deixar ela ativa, quando você ter um post no IbTable ou usar um comando INSERT com uma Query, será ignorado o parâmetro e sempre vai gerar um por causa do trigger.
Primeiro passo é desativar o trigger.
Depois você pode fazer igual o colega sugeriu, implementar uma função e depois do comando Insert se usar IbTable, ou antes do Execute se usar IbQuery pegar o próximo generator:

function Generator_ID(str_generator: string): integer;
var
QRY :TSqlQuery;
begin
Qry := TSQLQuery.Create(self);
Qry.SQLConnection := SuaConexao;
Qry.sql.Add('Select Gen_ID('+str_generator+',1) from RDB$DATABASE');
QRY.Open;
Result := Qry.Fields[0].AsInteger; 
end;

CDS_Codigo.Value := Generator_ID(GEN_TABELA_ID);
GOSTEI 0
Carlos Bernardo

Carlos Bernardo

17/11/2012

Adiciona essa unit na clausula uses : SqlExpr
GOSTEI 0
Sublixo

Sublixo

17/11/2012

Adiciona essa unit na clausula uses : SqlExpr


Estou usando Delphi XE2 e la ainda persiste o erro do (self)

e la esta declarado assim

uses
System.SysUtils, System.Classes, Data.DBXFirebird, Data.FMTBcd,
Datasnap.DBClient, Datasnap.Provider, Data.DB, Data.SqlExpr;
GOSTEI 0
Carlos Bernardo

Carlos Bernardo

17/11/2012

troca essa linha Qry := TSQLQuery.Create(self);
por essa Qry := TSQLQuery.Create(nil);
GOSTEI 0
Sublixo

Sublixo

17/11/2012

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


Agora não apresentou mais o erro, porém, se eu apertar botão novo ".Insert" e depois cancelar ".Cancel", quando eu apertar o botão novo novamente ele já pula para o próximo valor, seria por causa da trigger?
GOSTEI 0
Deivison Melo

Deivison Melo

17/11/2012

Seria por causa disso:

--> No evento NewRecord do ClientDataSet vc usa:

--> CDS_Codigo.Value := Generator_ID(GEN_TABELA_ID);


GOSTEI 0
Sublixo

Sublixo

17/11/2012

Galera, agradeço a todos que me responderam, todos vceis são nota 10.

Moderadores podem encerrar o tópico como RESOLVIDO
GOSTEI 0
POSTAR