GARANTIR DESCONTO

Fórum Delphi x Postgre (Problema com auto incremento) #27003

10/12/2008

0

[b:b408d8992f]Pessoal, estou com problema na inserção de registro em tabelas com campo autoincremento[/b:b408d8992f]

Minha tabela é a mais simples possivel:
create table teste (ID serial, descricao varchar(20))

Utilizo:
- Delphi 2007 com Update 3
- PostgreSQL Database Server 8.3
- PostgreSQL ODBC Driver ´psqlodbc_08_03_0400´
- Windows XP SP3

O problema ocorre quando insiro um registro qualquer nessa tabela, e logo após o Post, ela não me retorna o novo ID incluído. Segue abaixo meu código:

[color=green:b408d8992f][i:b408d8992f] ADOConnection1.Close;
ADOConnection1.LoginPrompt:= False;
ADOConnection1.ConnectionString:= ´Driver={PostgreSQL ANSI};Server=localhost;Port=5432;Database=meudb;Uid=postgres;Pwd=minhasenha´;
ADOConnection1.Connected:= True;

ADOQuery1.Close;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add(´SELECT * FROM TESTE´);
ADOQuery1.Open;

ADOQuery1.Append;
ADOQuery1.FieldByName(´DESCRICAO´).AsString:= ´XXX´;
ADOQuery1.Post;[/i:b408d8992f][/color:b408d8992f]

Neste momento, eu deveria obter o valor do campo ID, mas ele só me retorna o valor ZERO. O mesmo não ocorre com o MySQL ou SQL Server.

Obs.: Passei pela mesma situação no Oracle, porém consegui resolver ajustando um parâmetro na query, mas no postgre não obtive êxito. O parâmetro ajustado foi o seguinte:

[i:b408d8992f]ADOQuery1.Properties[´Update Resync´].Value:= adResyncInserts + adResyncAutoIncrement;[/i:b408d8992f]

Obs.: Esse parâmetro é passado após o ADOQuery1.Open;


Edunascimento

Edunascimento

Responder

Posts

26/12/2008

Andersonscinfo

amigo, não uso a mesma forma de conexão como vc esta usando, no momento eu to usando dbexpress+odbc, nas minhas aplicações eu sempre uso sql cru que fica mais facil de controlar....segue um exemplo se quizer.....

procedure TForm_cadcategoria.btn_salvaClick(Sender: TObject);
Var
  TD : TTransactionDesc; // requer init dbxpress
begin
  with DataModule1 do
    begin
      if tp_salva = 0 then
        begin
          TD.TransactionID := 1;
          TD.IsolationLevel := xilREADCOMMITTED;
          try
            SQLC_con.StartTransaction(TD);
            Qry_geral.Close;
            Qry_geral.SQL.Clear;
            Qry_geral.SQL.Add(´INSERT INTO public.tb_categoria(nome, obs) ´+
            ´VALUES (:nm, :os);´);
            Qry_geral.ParamByName(´nm´).AsString:=Ed_nome.Text;
            Qry_geral.ParamByName(´os´).AsString:=M_obs.Text;
            Qry_geral.ExecSQL(False);
            SQLC_con.Commit(TD);
            ShowMessage(´Operação Realizada com Sucesso!´);
            botaos1;
          except
            SQLC_con.Rollback(TD);
            ShowMessage(´Erro! Operação Cancelada!´);
          end;  
        end;
      if tp_salva = 1 then
        begin
          TD.TransactionID := 1;
          TD.IsolationLevel := xilREADCOMMITTED;
          try
            SQLC_con.StartTransaction(TD);
            Qry_geral.Close;
            Qry_geral.SQL.Clear;
            Qry_geral.SQL.Add(´UPDATE public.tb_categoria SET nome=:nm, obs=:os ´+
            ´WHERE codigo=:cd;´);
            Qry_geral.ParamByName(´nm´).AsString:=Ed_nome.Text;
            Qry_geral.ParamByName(´os´).AsString:=M_obs.Text;
            Qry_geral.ParamByName(´cd´).Value:=StrToInt(Ed_cod.Text);
            Qry_geral.ExecSQL(False);
            SQLC_con.Commit(TD);
            ShowMessage(´Operação Realizada com Sucesso!´);
            botaos1;
          except
            SQLC_con.Rollback(TD);
            ShowMessage(´Erro! Operação Cancelada!´);
          end;
        end;
    end;
    //atualiza
    CDS_con_cat.Active:=False;
    CDS_con_cat.Active:=True;
    select_str;
end;


no seu caso acho que depois do post vc deveria colocar um applyupdates(-1); não tenho bem certeza, mas acho que seria...

abraços e boa sorte


Responder

Gostei + 0

16/01/2009

Reunix

é isso mesmo apos o post vc pega o ultimo ID(Serial) gerado pelo Postgres, segue como fazer isso:

ADOQuery1.Sql.Clear;
ADOQuery1.Sql.Add(´Select currval(´´teste_id_seq´´) as Cod from teste´);
ADOQuery1.Open;

cCodigo.Text := ADOQuery1.FieldByName(´Cod´).AsString;



lembrando.... q o proprio postgres gera no objeto (sequencias) as variaveis de sequencia como no exemplo acima (teste_id_seq), q vai depender do nome do seu campo.

espero ter ajudado,


Responder

Gostei + 0

17/02/2009

Edunascimento

Caro amigo, toda ajuda é sempre válida e agradeço por todas elas, porém as respostas enviadas ainda não atendem as minha necessidades.

Eu preciso desse ID (obviamente) logo após o post, porém não posso fazer outra consulta para obtê-lo.

Desenvolvi uma classe na qual eu posso trabalhar a alguns bancos via OLEDB ou ODBC, basta mudar apenas 1 variável, e por esse motivo nao posso sair modificando todos os meus sistemas para fazer isso. Trabalho com Oracle, SQL Server 2000-2005-2008 e MySQL, e todos esses bancos funcionam perfeitamente com a minha necessidade, porém no POSTGRE estou com esse impedimento.

Testei o driver PgOleDb, mas tem muitos bugs. Ele foi descontinuado em 2006, até hoje não sofreu modificações. Se alguem conhecer outros driver Free, gostaria que me indicassem.


Responder

Gostei + 0

02/10/2009

Pedroviol

Se eu entendi... Vc quer criar um próximo código?
Cria uma sequence:

CREATE SEQUENCE ´nome_sequence´
INCREMENT 1 MINVALUE 1

Quando for chamá-la:

Select NEXTVAL(´NOME_SEQUENCE´).
Espero ter ajudado.


Responder

Gostei + 0

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

Aceitar