Jump to content
Fórum Script Brasil
  • 0

Como Recuperar Um Campo Gravado


Wagner Medeiros
 Share

Question

Olá pessoal,

Tenho um campo (codigo) em uma tabela access (tb01) que é do tipo "Numeração Automática" e um campo descricao (texto).

Tento fazer o seguinte :

Var r : _recordset;

Begin

r:=adoconnection1.Execute('insert into tb01 (descricao) values ("teste")');

end;

Isso funciona perfeitamente,

mas quando tento pegar os dados gravados com :

Var r : _recordset;

s : integer;

Begin

r:=adoconnection1.Execute('insert into tb01 (descricao) values ("teste")');

s:=r.Fields['codigo'].Value;

end;

Erro : O item não pode ser encontrado na coleção correspondenre ao nome ou ao ordinal solicitado.

alguém tem uma ajuda ? o que quero é pegar o numero que foi gravado no meu campo de auto incremento. não posso pegar depois já que aoutro usuário pode ter incluido um registro imediatamente após o meu, etc. . .

qualquer coisa : [email protected]

Link to comment
Share on other sites

7 answers to this question

Recommended Posts

  • 0
Olá pessoal,

Tenho um campo (codigo) em uma tabela access (tb01) que é do tipo "Numeração Automática" e um campo descricao (texto).

Tento fazer o seguinte :

Var r : _recordset;

Begin

r:=adoconnection1.Execute('insert into tb01 (descricao) values ("teste")');

end;

Isso funciona perfeitamente,

mas quando tento pegar os dados gravados com :

Var r : _recordset;

s : integer;

Begin

r:=adoconnection1.Execute('insert into tb01 (descricao) values ("teste")');

s:=r.Fields['codigo'].Value;

end;

Erro : O item não pode ser encontrado na coleção correspondenre ao nome ou ao ordinal solicitado.

alguém tem uma ajuda ? o que quero é pegar o numero que foi gravado no meu campo de auto incremento. não posso pegar depois já que aoutro usuário pode ter incluido um registro imediatamente após o meu, etc. . .

qualquer coisa : [email protected]

Wagner,

não sei bem como você esta utilizado esta aplicação. Porém não seria mais simples utilizar um componente adoquery e utilizar as setenças sql para inserir e depois realizar um select com um parametro do tipo :descrição em que você passa valores para pesquisa e tera como retorno o código incrementado.

tipo:

with adoquery do

begin

close;

sql.clear;

sql.text :='insert into tb01 (descricao) values ("teste")';

execsql;

close;

sql.clear;

sql.text :='select codigo from tb01 where descricao =:desc';

parambyname('desc').asstring := edit1.text;

open;

end;

edit2. text := inttostr(adoquery.fieldbyname('codigo').asinteger);

espero ter ajudado.

Link to comment
Share on other sites

  • 0

Obrigado pela dica, mas neste caso não posso fazer isso.

o campo codigo é o único que não pode repetir (chave) os outros não posso confiar e pode ser incluido um com mesmo valor imediatamente por outro usuário.

se alguém me ajudar, eu vi no help do delphi que o adocommand retorna o registro incluido para um recordset, mas não consigo acessá-lo.

r:=adoconnection1.Execute('insert into tb01 (descricao) values ("teste")');

OU

adocommand1.CommandText:='insert into titulares (codigo, nome) values ("'+edit1.text+'","'+edit2.text+'")';

r:=adocommand1.Execute;

Link to comment
Share on other sites

  • 0

Olá.

Veja se isso serve de pista:

O MySQL tem a função

LAST_INSERT_ID(), LAST_INSERT_ID(expr)

Retorna o mais recente valor gerado automaticamente em um campo auto_increment, pelo mais recente Insert ou Update.

Exemplo:

mysql> SELECT LAST_INSERT_ID();

-> 195

O "id" gerado é mantido no servidor para cada conexão... assim, o valor não é "afetado" pelos outros usuários, que podem (e tem) seus próprios valores para o campo auto_increment, assegurando que cada um consiga obter seu próprio "id", sem necessidade de bloqueios ("locks") ou transações.

E se você fizer multiplos "insert", Last_insert_id() só retornará o valor do último (isto é, o mais recente).

Creio que no banco de dados que você está usando deve haver algo do tipo...

Ok?

Espero ter ajudado!

Link to comment
Share on other sites

  • 0
O que é esse quote ?

Interessante, mas uso o ACCESS. Não exeste essa função, estou procurando por outras que façam a mesma coisa, se alguém souber . . .

Mas observem que no Help do Delphi diz que ele retorna o último registro gravado, em forma de recordset.

De qualquer maneira seria interessante saber usar esse recurso.

Mas tá valendo a dica, o mySQL é uma boa opção também, não é verdade ? nste caso é que já tenho um banco e um sistema que o utiliza e não tenho como "mexer" no sistema de terceiros . . .

Obrigado . . .

Link to comment
Share on other sites

  • 0

Wagner, já que a opção do colega Recife não lhe atende, então a sugestão é que você mude o campo para integer e faça a auto-numeração na mão (select MAX(codigo) from ...).

Se você testar no seu código quantas colunas seu recorset retorna:

if r.Fields.Count > 0 then
    s:=r.Fields['codigo'].Value;

vai verificar que o erro não ocorre mais.

Isto porque INSERT (DELETE, UPDATE) é uma instrução SQL que não retorna resultados (como o SELECT).

No help do componente ADOConnection, método Execute, está escrito assim na descrição:

Execute returns a recordset if the command executed is one that generates a recordset.

Se você alterar sua instrução para um SELECT provavelmente conseguirá acessar os dados como imaginado. Dê uma confirmada nisto.

Abraços

Link to comment
Share on other sites

  • 0
Guest --wagnercabeca --
Wagner, já que a opção do colega Recife não lhe atende, então a sugestão é que você mude o campo para integer e faça a auto-numeração na mão (select MAX(codigo) from ...).

Se você testar no seu código quantas colunas seu recorset retorna:

if r.Fields.Count > 0 then
    s:=r.Fields['codigo'].Value;

vai verificar que o erro não ocorre mais.

Isto porque INSERT (DELETE, UPDATE) é uma instrução SQL que não retorna resultados (como o SELECT).

No help do componente ADOConnection, método Execute, está escrito assim na descrição:

Execute returns a recordset if the command executed is one that generates a recordset.

Se você alterar sua instrução para um SELECT provavelmente conseguirá acessar os dados como imaginado. Dê uma confirmada nisto.

Abraços

(...) The Execute method is, however, capable of returning a recordset. A separate ADO dataset component must be supplied to use that recordset, though.

(...)

Eu não consegui usá-lo com odescrito, mas no help do ADOCommand, diz que ele serve exatamente para as expressoes de SQL que NÃO retornam diretamente um recordset, mas que devemos utilizar com com um store ou com om dataset.

Sabem como fazer isso ?

Link to comment
Share on other sites

  • 0
(...) The Execute method is, however, capable of returning a recordset. A separate ADO dataset component must be supplied to use that recordset, though.

(...)

Eu não consegui usá-lo com odescrito, mas no help do ADOCommand, diz que ele serve exatamente para as expressoes de SQL que NÃO retornam diretamente um recordset, mas que devemos utilizar com com um store ou com om dataset.

Acho que é uma questão de interpretação. Vejamos o parágrafo completo:

"TADOCommand is most often used for executing data definition language (DDL) SQL commands or to execute a stored procedure that does not return a result set. For SQL statements that return a result set, TADODataSet, TADOQuery, or TADOStoredProc is better suited. The Execute method of TADOCommand is, however, capable of returning a recordset. To use that recordset, however, you will need a separate ADO dataset component."
- O início do texto cita que este "componente" é frequentemente utilizado para execução de comandos SQL como CREATE, ALTER, DROP (ref. What are the difference between DDL, DML and DCL commands?).

- Na parte em vermelho, há a recomendação de que para comandos SQL que retornem um conjunto de resultados sejam utilizados TADODataSet, TADOQuery ou TADOStoredProc.

- Por fim, está dito: entretanto, o método execute do TADOCommand é capaz de retornar um recordset. Mas isso ocorre se não seguirmos as indicações mencionadas e executarmos um comando como SELECT.

Bom, tratando do seu questionamento, o qual está relacionado a última parte do parágrafo acima, o uso de um ADO dataset separado para receber os dados retornados seria algo assim (faça o teste):

No form, além do TADOCommand, adicione um TADODataSet (conforme orientado na nota do help), em seguida coloque o código:

...
  ADOCommand1.ConnectionString := ... // você já deve ter ela inicalizada
  ADOCommand1.CommandText := 'select codigo, descricao from tb01';
  ADODataSet1.Recordset := ADOCommand1.Execute;
  if ADODataSet1.Active then
    ShowMessage('Descrição do 1º registro retornado: ' +
                ADODataSet1.Fields['Descricao'].Value);
Observe que ao ser chamado Execute, haverá sim o retorno de um conjunto de registros (recordset), o qual será atribuído a propriedade RecordSet do ADODataSet, que por sua vez já se encontrará aberto. Entretanto, se utilizar o mesmo método para a aplicação que você quer fazer:
...
  ADOCommand1.ConnectionString := ... // você já deve ter ela inicalizada
  ADOCommand1.CommandText := 'insert into tb01 (descricao) values ("teste")';
  ADODataSet1.Recordset := ADOCommand1.Execute;
  if ADODataSet1.Active then
    ShowMessage('Descrição do 1º registro retornado: ' +
                ADODataSet1.Fields['Descricao'].Value);
não funciona pois, como já mencionei antes, o comando INSERT é um dos que não retorna "algo". Você vai observar que no momento da chamada a Execute, ocorrerá uma exception com a mensagem: "ADORectSet1: Recordset is not open". E se lá no código inicial que você postou, você fizer o teste do estado do recordset retornado:
...
  r := adoconnection1.Execute('insert into tb01 (descricao) values ("teste")');
  if r.State = adStateOpen then
    s:=r.Fields['codigo'].Value;

você vai ver que ele é retornado fechado (adStateClosed) após a execução do comando.

Espero ter ajudado a esclarecer esta situação

Abraços

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Forum Statistics

    • Total Topics
      149.8k
    • Total Posts
      646.6k
×
×
  • Create New...