Selecao DevMedia QUERO SER PRIME

Fórum DataSet: Como mover o cursor para o registro recém inserido? #364116

19/09/2008

0

Toda vez que você insere um registro (Insert/ApplyUpdate) o cursor move para o inicio, como move-lo para o registro recém inserido?

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

Joeyramone

Responder

Posts

19/09/2008

Paullsoftware

Normalmente não uso Grid para inserção de dados diretamente, mais talvez você resolva o seu problema guardando o Codigo do registro inserido depois dando um locate para localizar o respectivo codigo... :wink:


Responder

Gostei + 0

19/09/2008

Joeyramone

Inicialmente o que eu quero é justamente pegar o código/primary key do registro inserido , por isso preciso mover o cursor para tal registro, aliás é só por isso que o insiro e aplico o update e só depois o edito como no código que vou mostrar.É um generator então só da para pegar depois de inserido e não posso me basear pelo valor mais alto anterior pois em um ambiente multi-usuário vai dar problema.

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...


Responder

Gostei + 0

19/09/2008

Rogerioluz

Qual o banco e qual a versão. Se for Firebird 2.0 você pode usar o parâmetro Return e até inserir numa messagedlg (se estiver usando o Delphi).

O Parâmetro é usao em store Procedures.

Um Abraço...

Rogério Luz


Responder

Gostei + 0

19/09/2008

Joeyramone

Estou usando justamente o firebird 2. Pode me explicar melhor isso ai e dar um exemplo? Valeu.


Responder

Gostei + 0

19/09/2008

Marco Salles

Mas seria bom vc tentar explicar pq necessita do código/primary key do registro inserido ... Por acso seria por causa de Algum Relacionamento ??
É 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 ???


Responder

Gostei + 0

19/09/2008

Luciano.lirio

JoeyRamone,


montei um exemplo usando o ClientDataSet retornando um ID no link abaixo.

[url]www.mattos.eti.br/ClientDataSet.zip[/url]

pesquer te ajudar.

Att,


Responder

Gostei + 0

19/09/2008

Luciano.lirio

usei select @@identity que é para o SQL Server e o Access, para o FireBird acho que é o SELECT GEN_ID(nome do generator,1) FROM RDB$DATABASE.

Att,


Responder

Gostei + 0

20/09/2008

Joeyramone

Luciano, ajudou a principio, o código funciona, mas no meu caso especifico eu uso DBExpress/SqlDataSet e estou recebendo erros de campos não encontrados ao fazer este SELECT(os demais campos que não são o Generator.

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;


Responder

Gostei + 0

20/09/2008

Marco Salles

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;


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

estou recebendo erros de campos não encontrados ao fazer este SELECT

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´)



Responder

Gostei + 0

20/09/2008

Paullsoftware

vamos por parte...
como você está fazendo pra gerar o novo ID da tabela?
no evento AffterInsert do seu cds coloque:
variavelglobal_do_tipo_iteiro:=0;

no evento AffterPost faça...
if TClientDataSet(DataSet).ApplyUpDates(0)<=0 then begin TClientDAtaSet(DataSet).ApplyUpDates(-1); variavelglobal_do_tipo_Inteiro := NomeDoCDSNomeDoCampoChave.AsInteger; end; DataSet.Locate(´NomeDoCampoChave´,Variavel_do_tipo_inteiro,[]);

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:


Responder

Gostei + 0

20/09/2008

Joeyramone

Marco, fiz isso ae, agora foi, ta bonito...
Valeu ae tb paulo...


Responder

Gostei + 0

21/09/2008

Paullsoftware

[quote:165f1c69b1=´Marco Salles´]
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;


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

estou recebendo erros de campos não encontrados ao fazer este SELECT

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´)
[/quote:165f1c69b1]Marcos eu sempre disparo o gerador no evento [b:165f1c69b1]BeforedUpDateRecord[/b:165f1c69b1] do DataSetProvider, existe alguma diferença disparando ele no evento AffterInsert do CDS? acredito que não, só por curiosidade... :wink:


Responder

Gostei + 0

21/09/2008

Marco Salles

Marcos eu sempre disparo o gerador no evento BeforedUpDateRecord do DataSetProvider, existe alguma diferença disparando ele no evento AffterInsert do CDS?


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


Responder

Gostei + 0

22/09/2008

Paullsoftware

[quote:a147362d04=´Marco Salles´]
Marcos eu sempre disparo o gerador no evento BeforedUpDateRecord do DataSetProvider, existe alguma diferença disparando ele no evento AffterInsert do CDS?


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:


Responder

Gostei + 0

22/09/2008

Marco Salles

então , prepare um Modelo simples usando um relacionamento com DbExpress ... Gostaria de fazer um comparativo como vc recupera este Id, neste evento.

No Aguardo


Responder

Gostei + 0

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

Aceitar