Prever o futuro no SQL insert

Bom dia pessoal,

Olha o problema, sei que muitas pessoas ja passou por isso, vou salvar um registro e queria saber com qual PK o registro vai ser salvo! Considerando que outras pessoas tambem podem inserir outros registros,

Acho que seria um sequencia assim:
1- salvo um registro e logo faço um update
assim o registro fica bloqueado.

mas a tabela tem relacionamento e eu vou precisar de um registro da tabela que tem relacionamento,
e se atabela nao tiver registro ?, …, …, … .

Essa solucão nao é boa

Algum pode me ajudar ?

Qual o banco de dados ?

Qual banco ?

Que rapido!

PostgresSQL

Utilize a sequence…

Dai vc já insere o registro com o ID.

Como assim a sequence ?

Mostra um pequeno exemplo, please.

É isso ?
Examples

Create an ascending sequence called serial, starting at 101:

CREATE SEQUENCE serial START 101;

Select the next number from this sequence:

SELECT nextval(‘serial’);

nextval

 114

Use this sequence in an INSERT command:

INSERT INTO distributors VALUES (nextval(‘serial’), ‘nothing’);

Update the sequence value after a COPY FROM:

BEGIN;
COPY distributors FROM ‘input_file’;
SELECT setval(‘serial’, max(id)) FROM distributors;
END;

Como vc gera as chaves unicas em suas tabelas ?

http://www.postgresql.org/docs/7.4/interactive/functions-sequence.html

Quase…
Dai vc faria algo como…

int i = consultanoBanco("SELECT nextval('serial');"); //a variável i agora tem a chave do registro;
inserteNobanco("INSERT INTO distributors VALUES ("+i+", 'nothing')");

Claro que não dessa maneira terrível que eu apresentei…
Apenas para exemplificar

As chaves estao auto_increment,

Cara inicialmente o banco usado é o PostgreSQL , nao sei se vai mudar !

Mas autoincrement são exatamente as sequences do postgree não?

Sim, mas ve so .

Eu abro um formulario que me traz o numero do Protocolo que é o numero da PK da Tabela,
Outro pessoa abre um outro formulario que me traz o numero do Protocolo que é o numero da PK da Tabela.

Qunado os dois forem salvar, alguem vai ter o numero de protocolo trocado.

Quem fez o sistema pegou a proxima PK e apresentou como numero de protocolo.

Vixi… posso dar apenas um conselho…
Refactoring: Improving the Design of Existing Code (Fowler)

Acho que vc não vai conseguir resolver esse problema sem mexer nisso.

Um Sequence trabalha exatamente esse problema recorrente, a concorrência das chaves unicas.

Uma sequence nunca (eu disse nunca) vai liberar um mesmo id em consulta com nextval.

Logo, já pode prever o que vai ter que trabalhar… boa sorte…

O que voce acha disso:

quando eu chamar o jsp ele execulta isso

SELECT setval(‘seq_protocolo’, <>);
select nextval(‘seq_protocolo’);

entao salvo com o numero do select nextval(‘seq_protocolo’);

Salvo.

não precisa do setval…

Ola!

Tente utilizar o currval(‘nome_sequence’), ele pega o registro que está sendo inserido no momento.
Por exemplo:

[code]//Insere na tabela Evento
stm = conn.prepareStatement(“INSERT INTO Evento (idCadastroPessoa, idTipoEvento, dataEvento, valorEvento, obs) VALUES (?, ?, ?, ?, ?)”);

//Insere na tabela MatriculaRenovacao com a PK da tabela Evento
stm = conn.prepareStatement(“INSERT INTO MatriculaRenovacao (idEvento, horaMatricula, tipo) VALUES (currval(‘evento_idevento_seq’), ?, ?)”);[/code]

Não sei se era isto q vc precisava

O currval não vai garantir a concorrência.

E se colocar dentro de uma transação?

Eu utilizo assim e aparentemente funciona…

Mesmo em uma transação.
Se tiver concorrência terá problemas.

Para isto existem sequences.
Consultando o id (único) antes de inserir, é impossível problemas de concorrência (teoricamente é claro, nunca sabemos o improvável).

:smiley:

Até…

Cara, apenas dê um insert com nextval(‘sequence_da_tabela’) . Ele não dá dois inserts com o mesmo ID se usar nextval e ponto.

Nunca vi usar select com nextval. Pra que vc tah fazendo isso?