Fórum DataSet: Como mover o cursor para o registro recém inserido? #364116
19/09/2008
0
Ps: não posso usar clientdataset.last; pois os dados usam uma query order by, então o registro novo não é necessáriamente o último na ordem do DataSet.
Joeyramone
Curtir tópico
+ 0Posts
19/09/2008
Paullsoftware
Gostei + 0
19/09/2008
Joeyramone
Eu fazia o seguinte quando o order by era ascendente e pelo generator:
ClientDataSet1.Insert; ClientDataSet1.ApplyUpdates(0); ClientDataSet1.Refresh; ClientDataSet1.Last; // Aqui o cursor estava no registro criado e podia então pegar a primary key ClientDataSet1.Edit; // E em seguida editar o registro coisa que também preciso na sequência
Mas como o order by agora é por outro campo, isso não funciona mais. o novo registro pode aparecer em qualquer parte...
Gostei + 0
19/09/2008
Rogerioluz
O Parâmetro é usao em store Procedures.
Um Abraço...
Rogério Luz
Gostei + 0
19/09/2008
Joeyramone
Gostei + 0
19/09/2008
Marco Salles
É bom pensar nisso pq vc diz que :
´insiro e aplico o update e só depois o edito como no código que vou mostrar´ mas tb vc tem um incoveniente que é o fato de estar trabalhando em um ambiente multi-usuário.
Logo Aplicar Update apos cada inserção vc terá uma queda de performance muito grande
eu não sei se o BookMark ira funcionar com a Estrutura OrderBy, Acredito que sim... Logo seria melhor Guardar a Posição usando a StringOpaca. Isto ate guarda a Posição do Registro, mas o Updates
a cada Inserção continuo sem entender ???
Gostei + 0
19/09/2008
Luciano.lirio
montei um exemplo usando o ClientDataSet retornando um ID no link abaixo.
[url]www.mattos.eti.br/ClientDataSet.zip[/url]
pesquer te ajudar.
Att,
Gostei + 0
19/09/2008
Luciano.lirio
Att,
Gostei + 0
20/09/2008
Joeyramone
Marcos, já tentei o bookmark, não funciona, quanto ao ApplyUpdates eu que não entendi, qual seria o seu procedimento??
Eu sempre fiz assim:
-ClienteDataset.MODO(Insert,Edit etc)
-faço oq tem q ser feito
-ApplyUpdates;
-Refresh;
Gostei + 0
20/09/2008
Marco Salles
Desse modo , em ambiente de rede não é recomendado. Vc a cada Insert/Edit Trafega Dados na Rede.
O certo é fazer Tudo o que tem que ser feito <Varias Inserções, Varrios Edits> e no fim dar o Applyupdates. Assim os Dados são empacotados e enviados no mesmo Pacote
Vc deve estar Usando o memso SqlQuery ou ClientDataSet para Fazer o Select , e ´eles´ Devem estar com os Fileds Definidos. Ou Talves oS Fileds
estão como Requeridos Logo na Montagem do Sql irá Reclamar
Geralmente neste tipo de problema uma Boa Prática de Programação
é o Uso de uma Função Genérica: Tipo esta
{O parâmetro TableName indica o nome da tabela da qual deseja-se
pegar o valor do generator que está associado a ela, sendo
que os generators criados no banco devem seguir o padrão
GEN_NomeTable_ID. Caso os generators do seu banco
não estejam neste padrão, altere o código desta função
para o formato do nome do seu generator. O nome do generator
poderia ser passado via parâmetro, ao invés de o nome
da tabela, porém, fica mais fácil simplesmente passar
o nome da tabela e a função montrar o nome do generator
a partir daí. Assim, o desenvolvedor não precisa
ficar pensando em como é o formato do nome
dos generators.
O parâmetro Incremento é um parâmetro Default. Se ele
for omitido na chamada da função, seu valor será 1.
Este valor indica que, antes de retornar o valor do generator,
este é incrementado com o valor do parâmetro Incremento, e é retornado
o valor do generator depois de incrementado. Se Incremento for passado
como zero, a função apenas devolve o valor atual do generator, sem
incremetá-lo.}function TSeuDataModulo.PrimaryKeyValue(TableName: ShortString;
Incremento: Byte): Integer;
var
dts: TSQLDataSet;
begin
//Cria um objeto local da classe TSQLDataSet
dts:= TSQLDataSet.Create(nil);
try
//Associa o dts à conexão SQLConnection1
dts.SQLConnection := SQLConnection1;
{gera um select para pegar o valor do generator
associado à tabela informado em TableName.
A tabela rdb$database é uma tabela de sistema, ou seja,
uma tabela interna do Firebird. Ela está sendo utilizada aqui
para executar selects que não trazem dados de nenhuma
tabela criada pelo desenvolvedor, e sim para executar
a função gen_id do Firebird. Como no Firebird, e em muitos outros bancos,
todo select deve possuir um "from NOME_TABELA"
(diferente do Microsoft SQL Server), então é usada
esta tabela interna do Firebird que sempre retorna apenas um registro
e permite a execuçã de função como gen_id, current_date, current_time, etc.}
dts.CommandText :=
´select gen_id(GEN_´ +
TableName + ´_ID, ´+IntToStr(Incremento)+´) from rdb$database´;
dts.Open;
//Pega o valor do generator
result:= dts.Fields[0].AsInteger;
dts.Close;
finally
dts.Free;
end;
end;Agora no Evento AfterInsert dos seu Cds voce coloque o Codigo
DataSet[´Seu_ID´]:=SeuDataModulo.PrimaryKeyValue(´NomeDaSuaTabela´)
Gostei + 0
20/09/2008
Paullsoftware
como você está fazendo pra gerar o novo ID da tabela?
no evento AffterInsert do seu cds coloque:
no evento AffterPost faça...
não sei vai funcionar é só uma ideia, nos passe mais detalhes de como está fazendo, como ta gerando a ID da tabela etc.. :wink:
Gostei + 0
20/09/2008
Joeyramone
Valeu ae tb paulo...
Gostei + 0
21/09/2008
Paullsoftware
Desse modo , em ambiente de rede não é recomendado. Vc a cada Insert/Edit Trafega Dados na Rede.
O certo é fazer Tudo o que tem que ser feito <Varias Inserções, Varrios Edits> e no fim dar o Applyupdates. Assim os Dados são empacotados e enviados no mesmo Pacote
Vc deve estar Usando o memso SqlQuery ou ClientDataSet para Fazer o Select , e ´eles´ Devem estar com os Fileds Definidos. Ou Talves oS Fileds
estão como Requeridos Logo na Montagem do Sql irá Reclamar
Geralmente neste tipo de problema uma Boa Prática de Programação
é o Uso de uma Função Genérica: Tipo esta
{O parâmetro TableName indica o nome da tabela da qual deseja-se
pegar o valor do generator que está associado a ela, sendo
que os generators criados no banco devem seguir o padrão
GEN_NomeTable_ID. Caso os generators do seu banco
não estejam neste padrão, altere o código desta função
para o formato do nome do seu generator. O nome do generator
poderia ser passado via parâmetro, ao invés de o nome
da tabela, porém, fica mais fácil simplesmente passar
o nome da tabela e a função montrar o nome do generator
a partir daí. Assim, o desenvolvedor não precisa
ficar pensando em como é o formato do nome
dos generators.
O parâmetro Incremento é um parâmetro Default. Se ele
for omitido na chamada da função, seu valor será 1.
Este valor indica que, antes de retornar o valor do generator,
este é incrementado com o valor do parâmetro Incremento, e é retornado
o valor do generator depois de incrementado. Se Incremento for passado
como zero, a função apenas devolve o valor atual do generator, sem
incremetá-lo.}function TSeuDataModulo.PrimaryKeyValue(TableName: ShortString;
Incremento: Byte): Integer;
var
dts: TSQLDataSet;
begin
//Cria um objeto local da classe TSQLDataSet
dts:= TSQLDataSet.Create(nil);
try
//Associa o dts à conexão SQLConnection1
dts.SQLConnection := SQLConnection1;
{gera um select para pegar o valor do generator
associado à tabela informado em TableName.
A tabela rdb$database é uma tabela de sistema, ou seja,
uma tabela interna do Firebird. Ela está sendo utilizada aqui
para executar selects que não trazem dados de nenhuma
tabela criada pelo desenvolvedor, e sim para executar
a função gen_id do Firebird. Como no Firebird, e em muitos outros bancos,
todo select deve possuir um "from NOME_TABELA"
(diferente do Microsoft SQL Server), então é usada
esta tabela interna do Firebird que sempre retorna apenas um registro
e permite a execuçã de função como gen_id, current_date, current_time, etc.}
dts.CommandText :=
´select gen_id(GEN_´ +
TableName + ´_ID, ´+IntToStr(Incremento)+´) from rdb$database´;
dts.Open;
//Pega o valor do generator
result:= dts.Fields[0].AsInteger;
dts.Close;
finally
dts.Free;
end;
end;Agora no Evento AfterInsert dos seu Cds voce coloque o Codigo
DataSet[´Seu_ID´]:=SeuDataModulo.PrimaryKeyValue(´NomeDaSuaTabela´)
Gostei + 0
21/09/2008
Marco Salles
O Seu Modelo eu não conheço e não o Utilizo. Vc poderia passar mais detalhes para Fazermos Um comparativo pequeno. Por exemplo tente entender a Minha dúvida abaixo:
Em relacionamentos como voce recupera esta Chave . Pois pelo modelo [b:46ca4fd734][u:46ca4fd734]proposto por voce[/u:46ca4fd734][/b:46ca4fd734] a cada Inserção , será necessário dar Um ApplyUpdates apos cada Insert. Pois o Evento [u:46ca4fd734]BeforedUpDateRecord[/u:46ca4fd734] so é disparado qnd os Dados são enviados
então vejo um inconveniente-> Dar applyupdates em cada Insert caso necessite da Chave para Relaconamentos
Gostei + 0
22/09/2008
Paullsoftware
O Seu Modelo eu não conheço e não o Utilizo. Vc poderia passar mais detalhes para Fazermos Um comparativo pequeno. Por exemplo tente entender a Minha dúvida abaixo:
Em relacionamentos como voce recupera esta Chave . Pois pelo modelo [b:a147362d04][u:a147362d04]proposto por voce[/u:a147362d04][/b:a147362d04] a cada Inserção , será necessário dar Um ApplyUpdates apos cada Insert. Pois o Evento [u:a147362d04]BeforedUpDateRecord[/u:a147362d04] so é disparado qnd os Dados são enviados
então vejo um inconveniente-> Dar applyupdates em cada Insert caso necessite da Chave para Relaconamentos[/quote:a147362d04][u:a147362d04][b:a147362d04]não exatamente[/b:a147362d04][/u:a147362d04], mais vou preparar um exemplo e postar aqui :wink:
Gostei + 0
22/09/2008
Marco Salles
No Aguardo
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)