Delphi x Postgre (Problema com auto incremento)
[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;
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
Curtidas 0
Respostas
Andersonscinfo
10/12/2008
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.....
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
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
GOSTEI 0
Reunix
10/12/2008
é isso mesmo apos o post vc pega o ultimo ID(Serial) gerado pelo Postgres, segue como fazer isso:
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,
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,
GOSTEI 0
Edunascimento
10/12/2008
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.
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.
GOSTEI 0
Pedroviol
10/12/2008
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.
Cria uma sequence:
CREATE SEQUENCE ´nome_sequence´
INCREMENT 1 MINVALUE 1
Quando for chamá-la:
Select NEXTVAL(´NOME_SEQUENCE´).
Espero ter ajudado.
GOSTEI 0