Ir para conteúdo
Fórum Script Brasil
  • 0

Como Recuperar Um Campo Gravado


Wagner Medeiros

Pergunta

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 : wam1@bol.com.br

Link para o comentário
Compartilhar em outros sites

7 respostass a esta questão

Posts Recomendados

  • 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 : wam1@bol.com.br

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 para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...