Chave composta e sequence no oracle. help

9 respostas
T

Olá pessoal!

No meu exemplo eu tenho 2 tabelas. cliente e contato.

Cliente possui uma chave primária simples com auto-incremento.
Contato possui uma chave composta com dois campos, onde o primeiro campo é a chave estrangeira de cliente e o segundo campo é um id sequencial para o contato.

Problema: Se eu cadastrar 2 clientes e 1 contato diferente para cada um deles teríamos 2 contatos na tabela de contato. O valor da chave composta para os dois contatos ficariam por exemplo assim:

id_cliente_fk id_contato 1 1 2 1

Pergunta: Como eu crio uma sequence que saiba que para o cliente 2 deve começar a contar novamente? Ou no caso se fosse mais um contato para o cliente 1 a sequence deveria saber que deveria incrementar 2 e assim por diante. Como seria a criação dessa sequence? Qual a melhor solução?

Muito Obrigado!

Atualização:

Pesquisando descobri que preciso usar trigger, achei um exemplo de uma trigger que pega o valor seguinte da sequence. mas não sei o jeito melhor pra ficar essa trigger… alguma ideia?

9 Respostas

J

Qual a importância dessa numeração para o usuário? Seria a ordem de importância dos contatos? Dependendo do que for ele mesmo iria escolher a ordem e você gravar o numero programaticamente conforme a ordem. Se for só meramente ilustrativo você enumera só na exibicao ou nao faz nada, nao precisando ter chave composta, so Fk do cliente e a sequence sozinha como chave primaria.

T

Entendi, mas nesse caso um contato não poderá pertencer a 2 clientes ao mesmo tempo, por isso a chave composta.

F

Cara, nem sei se tem como fazer isso com sequence pq a sequence não se baseia em um campo.
Ela simplesmente incrementa o valor dela.
Acho melhor não utilizar sequence nesse caso. Verifique o id do ultimo contato para aquele cliente e incremente “na mão”.

T

Eu pensei nessa hipótese, porém se fosse numa rede com muito acesso resultaria em um problema. Eu usei trigger e funcionou:

create trigger contato_cliente_trigger before insert on contato_cliente for each row when (new.sequencia is null) begin select contato_sequence.nextval into :new.sequencia from dual; end;

porém não atende o que eu quero, pois não vai gerar os ids de forma correta como especifiquei acima… :frowning:

F

Cara, pq vc não faz algo mais simples ?

Tipo isso:

Cliente:
id
nome

Contato:
id
tel
email
id_cliente

Dessa forma não importa o número do contato e vc sempre saberá a quem aquele contato pertence

T

Eu até poderia fazer assim, mas o meu objetivo com este exemplo é aprender como eu faria para gerar os números caso ocorresse uma chave composta desta forma. Este caso é bem normal de acontecer e eu preciso saber como fazer.

F

Bem… se o caso é apenas estudo e não uma necessidade real, ok.
Mas não acho um exemplo válido para esse cenário cliente + contato e nem consigo pensar em um cenário q utilizaria dessa forma q vc quer.

Mas ao meu ver (não sou nenhum especialista em BD) seria impossível fazer como vc qr.
Pq a sequence é “burra” e só incrementa a sí própria.
Não tem como vc fazer a mesma sequence ser 1, 2, 3 e depois voltar pra 1 ou 2 ou 3.
Como o proprio nome diz, é uma sequencia.

Pode até conseguir fazer de outra forma utilizando funções do próprio banco, mas não sequence.

Pelo menos eu desconheço.
Se alguém mais experiente puder confirmar…

T

Compreendo, eu também vi que a sequence só faz incrementos. Se alguém tiver alguma de como solucionar este problema, no caso de talvez uma trigger cuidar desses ids, por favor me ajudem. valeu!

J

Ok ser é por estudo, mas eu nunca passei por uma situação dessa profissionalmente, de ter que arrumar solução automática e obscura para um caso simples por simplesmente querer que seja assim mais complicado. Supondo então ter que ter a numeração no banco, simplesmente seta o valor programaticamente, sem trigger, sem nenhum complicador automágico. Agora mesmo me lembrei de uma tabela do sistema que trabalho que tem uma numeração, e isso é numerado programaticamente antes de mandar persistir no banco de dados, sem complicação nenhuma. Tem que caminhar conforme a necessidade, se ela não chegou ainda espera chegar, quando chegar o sentimento para a solução vai ser diferente do que ficar pensando de forma abstrata demais.

Se você está querendo fazer muito para muitos não precisa de sequencia numérica agrupada, é só referenciar o id do contato. Logicamente deverá ter três tabelas: Contato (IdContato, Nome), ContatoCliente (IdCliente, IdContato) e Cliente (IdCliente, Nome).

Criado 9 de junho de 2013
Ultima resposta 11 de jun. de 2013
Respostas 9
Participantes 3