Ler campo autoincremento ADO/Access apos INSERT INTO

Delphi

25/11/2004

Eu estou tentando ler o resultado de uma inserção de dados em banco de dados access em uma tabela com campo autoincremento. O help do delphi fala simplesmente em:

ADODataSet1.Recordset := ADOCommand1.Execute;


mas não funcionou. O código que estou usando é o seguinte.

procedure TForm1.Button1Click(Sender: TObject);
var
   nCod : integer;
begin
   ADODataSet1.Open;
   ADOCommand1.CommandText := ´INSERT INTO Tabela1 ´+
      ´(DataHora) ´+
      ´VALUES (#´+DateToStr(Now)+´)´;

   ADODataSet1.Recordset := ADOCommand1.Execute;

   with ADODataSet1 do
   begin
      nCod := Fields.FieldByName(´CampoAutoInc´).AsInteger;
   end;
end;


com

ADODataSet1.CommandType = cmdTable
ADODataSet1.CommandText = Tabela1

Retorna erro que o dataset não está aberto

Obrigado,

Eduardo[/code]


Quadrado

Quadrado

Curtidas 0

Respostas

José Henrique

José Henrique

25/11/2004

Veja este [url=http://www.delphi3000.com/articles/article_3612.asp?SK=]link aqui[/url]


GOSTEI 0
Quadrado

Quadrado

25/11/2004

Eu ainda não testei, mas estou procurando isto ha muito tempo. Vou incluir os dados da resposta aqui pois aquele é um site de acesso restrito.

We have a table in MsAccess like : Test, Fields (id=autoinc, name=text); First we have to have a function like the one below : function GetLastInsertID : integer; begin // datResult = TADODataSet datResult.Active := False; datResult.CommandText := ´select @@IDENTITY as [ID]´; datResult.Active := True; Result := datResult.FieldByName(´id´).AsInteger; datResult.Active := False; end; Now before getting the last inserted record record id = autoincrement field, in other words calling the above function. You have to do a SQL insert like the following procedure InsertRec; begin // datCommand = TADOCommand datCommand.CommandText := ´insert into [test] ( [name] ) values ( ´Test´ )´; datCommand.Execute; end; Now if we like to know which is the last autoinc value ( notice that the getlastinsertid proc. only works after the insertrec proc) procedure Test; begin InsertRec; Showmessage(format(´lastinsertid : ¬d´,[GetLastInsertID])); end; Ronald Buster


Segundo ele, mesmo em ambiente multi-usuário, funciona bem, pois o retorno da função é referente ao próprio usuário.

Boa sorte a todos.


GOSTEI 0
Quadrado

Quadrado

25/11/2004

Eu testei e não funcionou. Ele retorna zero como resultado.

Se alguem tiver alguma sugestão para correção deste erro, agradeço.

Obrigado,

Quadrado.


GOSTEI 0
José Henrique

José Henrique

25/11/2004

De fato, não funcionou comigo também.
Veja este link da Microsoft [url]http://support.microsoft.com/default.aspx?scid=kb;EN-US;q200300[/url]


GOSTEI 0
Thomaz_prg

Thomaz_prg

25/11/2004

Uma forma, é vc utilizar o fields editor. Dando 2 cliques, adicionando todos os campos, e no campo chave primaria, definir a propriedade Autogenerate para arAutoInc e, apos a inserção, pegar o valor do campo respectivo.


GOSTEI 0
Quadrado

Quadrado

25/11/2004

Se eu usar o FieldEditor eu sou obrigado a usar o DataSet com a propriedade CoomandType = cmdTable e então a instrução SELECT não funciona. Se estou fazendo algo errado, por favor me mostre.

No site da Microsoft - Office - Access 2003 eles dizem o seguinte:

Para encontrar o último valor usado para uma coluna de incremento automático, você pode usar a seguinte instrução: SELECT @@IDENTITY. Não é possível especificar um nome de tabela. O valor retornado é proveniente da última tabela, contendo uma coluna de incremento automático, atualizada.


isto está no link:

[url]http://office.microsoft.com/pt-br/assistance/HP010322481046.aspx[/url]

Na ajuda do Delphi para o métedo ADOCommand.execute ele fala que basta atribuir diretamente o resultado do comando a um ADODataSet:

ADODataSet.RecordSet := ADOCommand.Execute;


Mas retorna erro dizendo que o recordset não esta aberto e eu não sei como fazer.

Usando a instrução ´SELECT @@IDENTITY´ funciona sem erros, mas retorna valor zero. Fiz varia modificações em propriedades do DataSet e da conexão, mas não consegui resultado.

Eu preciso resover este pepino, para parar de trabalhar com abertura e fechamento de tabelas a todo momento.

Agradeço qualquer ajuda.

Quadrado


GOSTEI 0
Thomaz_prg

Thomaz_prg

25/11/2004

Cara, vc pode usar o fields editor com comandos SQL sim. Eu utilizo e não tenho problema nenhum. Teste e verifique!


GOSTEI 0
Quadrado

Quadrado

25/11/2004

Achei uma outra informação. O comando ´SELECT @@IDENTITY´ só funciona do Access 2000 em diante e estava usando o 97.

Veja o link:

[url]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnadonet/html/manidcrisis.asp[/url]

Vou fazer outros testes, inclusive o do Fieldeditor e passo aqui depois.

Obrigado.


GOSTEI 0
José Henrique

José Henrique

25/11/2004

Quadrado,
Creio que achei a solução a partir deste informe da MS
[url=http://support.microsoft.com/default.aspx?scid=kb;en-us;221931]How To Return Record´s Autonumber Value Inserted into Access DB[/url]
Que em resumo diz o seguinte:
1 - postar a inserção;
2 - guardar o bookmark do registro postado;
3 - reconsultar (requery) o dataset.

e fiz assim no meu código:
     .
     .
     .
    DM.qryPacientes.FieldByName(´CodFuncionárioIns´).Value := Usuario.Codigo;
    DM.qryPacientes.Post;
    bkmPosicao := DM.qryPacientes.Bookmark;
    DM.qryPacientes.Requery;
    DM.qryPacientes.Bookmark := bkmPosicao;
    ShowMessage(DM.qryPacientes.FieldByName(´CodPaciente´).AsString);
     .
     .
     .

Funcionou perfeitamente!!!


GOSTEI 0
Quadrado

Quadrado

25/11/2004

José Henrique

Atualmente eu estou usando esta forma para obter o campo autoincremento. Na realidade eu nem realizo a rechamada do DataSet, simplesmente leio o campo após a inserção e funciona direito em rede com um monte de usuários.

Table1.Open;
Table1.Insert;
Table1Campo2.Value := 2;
Table1Campo3.Value := ´abc´;
Table1.Post;
nValor := Table1Campo1.Value;
Table1.Close;


O problema é fazer isto via instrução SQL INSERT INTO, pois em alguns pontos do programa, realizo aberturas e fechamentos de várias tabelas, que segundo me consta diminui a performance do sistema.

Hoje testei a chamada por ´SELECT @@IDENTITY´ no Access 2000 e no Access 2002 e também não funcionou. Na pesquisa que eu fiz na internet em varios foruns, muita gente fala que funciona, inclusive na Microsoft, porém deve ter algum detalhe de configuração do DataSet ou da Conexão que não está funcionando.

Continuo tentando.

Quadrado


GOSTEI 0
POSTAR