Problemas com Foreign Key no MySQL [RESOLVIDO]  XML
Índice dos Fóruns » Java Básico
Autor Mensagem
Yky Mattshawn
Virtual Machine Man
[Avatar]
Membro desde: 18/12/2006 03:34:14
Mensagens: 652
Localização: São Sebastião do Caí / RS
Offline

Estou com um pequeno problema: tenho duas tabelas no MySQL, uma chama-se clientes e a outra vendedores. A tabela clientes tem um campo chamado Vendedor (INTEGER) que é uma Foreign Key para o campo ID da tabela vendedores. O problema é que na tabela clientes pode ocorrer de o usuário não querer definir um vendedor para aquele cliente, logo o campo Vendedor da tabela clientes deverá ficar vazio/nulo. Aí é que começa o problema: na hora da inserção o banco de dados lança um erro acusando que a chave estrangeira falhou e etc. Eu não posso remover o relacionamento entre as tabelas pois isso me sujeitaria a erros de integridade referencial, onde um vendedor poderia por acidente ser excluído e então os clientes tornaríam-se registros órfãos.

Alguém tem uma idéia de como eu posso sanar este problema? Desde já agradeço.


Yky Mattshawn [ Compusoft - Desenvolvimento de Sistemas Empresariais ]
"Tudo que é ortodoxo ou heterodoxo demais gera heresia."
[Email] [MSN] [ICQ]
dicabeca
JavaEvangelist
[Avatar]

Membro desde: 12/05/2007 23:28:48
Mensagens: 458
Localização: Rio de Janeiro - RJ
Offline

nao entendi muito oq vc quis dizer, mais c o campo Vendedor no cliente e um FK nao pode ser nulla,no caso c no seu sistema o campo vendedor possa ser nullo nao coloque ele como Fk na tabela Cliente vlw.

"Quem um dia experimentou a emoção de ser Flamengo, nunca mais vai viver outra que se equipare"
[MSN]
alansto
Thread.start()
[Avatar]

Membro desde: 22/05/2006 23:48:26
Mensagens: 46
Localização: Florianópolis
Offline

eu sou da opnião do rapaz aqui de cima! acredito eu que se vc chegou em um caso como oq vc citou seu problema está no projeto do banco! tente rever as tabelas e tentar encontrar onde vc errou, pois tem alguma coisa estranha aí amigo!
[Email] [MSN]
Giulliano
GUJ Master
[Avatar]

Membro desde: 14/11/2006 19:29:38
Mensagens: 1704
Localização: São Paulo
Offline

Cara seja bem vindo ao conceito de CHAVE NATURAL e CHAVE ARTIFICIAL...


Explicando...para controle de Banco de Dados sempre usamos um campo do tipo ID....ele sempre é PK e não pode ser nulo, além de ser auto increment....esta é a chave NATURAL

Porém em alguns casos é interessante que vc use o conceito acima e crie uma segunda ID....e essa nova ID será a chave ARTIFICIAL ou seja ela esta relacionada à parte funcional do seu sistema e não do Banco de Dados...


espero que vc tenha entendido o conceito ( pra falar a verdade eu nem sei se existe... Mas também não sei de onde tirei isso )


[/]'s

Oracle Certified Master, Java EE 5 Enterprise Architect
Oracle Certified Professional Java Programmer
GiuLLianO MoRRoNi



?The creation of genuinely new software has far more in
common with developing a new theory of physics than
it does with producing cars or watches on an assembly
line



<UnTouChAbLe>
[Email] [WWW] [MSN]
gtagawa
What is classpath?

Membro desde: 21/03/2007 18:22:47
Mensagens: 9
Localização: Mogi das Cruzes - SP
Offline

eu acho que entendi... aqui uso algo parecido, mais os checks ficam dentro do programa.... não sei se tem como fazer isso via tabela... a não ser que vc crie um registro 0 na tabela de vendedores... ae para de dar o erro....
[Yahoo!]
Yky Mattshawn
Virtual Machine Man
[Avatar]
Membro desde: 18/12/2006 03:34:14
Mensagens: 652
Localização: São Sebastião do Caí / RS
Offline

Giulliano, o que você falou faz sentido, talvez seja a solução do meu problema.

didabeca e alansto, não há nada errado no banco, acho.

É mais ou menos assim:


table clientes
ID INTEGER AUTO INCREMENT NOT NULL,
Vendedor INTEGER FOREIGN KEY vendedores->ID

table vendedores
ID INTEGER AUTO INCREMENT NOT NULL

// OBS: o texto acima Não compreende uma instrução SQL funcional


Notem que na tabela clientes há um campo que aponta para a tabela vendedores, uma chave estrangeira, portanto. O problema é que, às vezes, pode não ser de vontade do usuário escolher um vendedor para o cliente, então a chave estrangeira na tabela clientes deverá ficar nula. O problema é que o banco não permite isso. A solução seria então eu remover a chave estrangeira, mas aí minha integridade referencial vai pro espaço, hehe. O que preciso é que:

-> Para cada cliente cadastrado pode ou não haver um vendedor. Caso haja a escolha de um vendedor, este vendedor deverá "existir" na tabela vendedores.

Ou seja, preciso manter uma chave estrangeira pra garantir que não será escolhida uma ID inválida e também para evitar que um vendedor seja excluído e registros de clientes fiquem com valores órfãos em seus campos.

Não vejo de que outra forma posso fazer isso. Acredito que o banco de dados não esteja incorreto (no seu projeto).

Obrigado a todos pelas respostas.


Yky Mattshawn [ Compusoft - Desenvolvimento de Sistemas Empresariais ]
"Tudo que é ortodoxo ou heterodoxo demais gera heresia."
[Email] [MSN] [ICQ]
Giulliano
GUJ Master
[Avatar]

Membro desde: 14/11/2006 19:29:38
Mensagens: 1704
Localização: São Paulo
Offline

E se vc criasse uma terceira tabela só de relacionamentos....




Tabela de Clientes



Tabela Vendedor



E aí vc salvaria na tabela de associação somente valores validos nas tabelas cliente e vendedor

a verdade é que existem diversas formas de se fazer isso...só estou te dando uma pequena luz mesmo...boa sorte ae...

[/]s

obs.: código SQL para MySQL 5.0

Oracle Certified Master, Java EE 5 Enterprise Architect
Oracle Certified Professional Java Programmer
GiuLLianO MoRRoNi



?The creation of genuinely new software has far more in
common with developing a new theory of physics than
it does with producing cars or watches on an assembly
line



<UnTouChAbLe>
[Email] [WWW] [MSN]
Yky Mattshawn
Virtual Machine Man
[Avatar]
Membro desde: 18/12/2006 03:34:14
Mensagens: 652
Localização: São Sebastião do Caí / RS
Offline

Giulliano wrote:...


Ae cara, valew pelo help, foi de muita utilidade.

Entretanto, acredito que o que vou fazer mesmo é excluir a chave estrangeira e torná-la comum. Então, para manter a integridade referencial, terei de fazer um trigger after delete na tabela vendedores para, após algum registro ser excluído, a tabela clientes seja atualizada, setando nulo para os registros que referenciavam (funcionalmente, não tecnicamente) o vendedor excluído.

O fato de eu não fazer nenhuma manobra muito ousada com o banco é que a aplicação aqui na empresa é programada a partir de uma ferramenta RAD, de modo que, se eu quisesse usar uma tabela auxiliar, muito provavelmente acarretar-se-ía uma boa parcela de código adicional nisso.

Mesmo assim, agradeço mais uma vez a ajuda.

Até mais!


Yky Mattshawn [ Compusoft - Desenvolvimento de Sistemas Empresariais ]
"Tudo que é ortodoxo ou heterodoxo demais gera heresia."
[Email] [MSN] [ICQ]
ehimura
Entusiasta Java

Membro desde: 30/10/2006 18:11:18
Mensagens: 22
Offline

Bom, não sei se dá tempo de respoder ainda... mas.. aí vai.

Tente criar a chave estrangeira desta forma:

create table vendedor(
id int not null auto_increment,
...
... ,
constraint pk_vendedor primary key (id)
);

create table cliente(
id int not null auto_increment,
id_vendedor int,
...
... ,
constraint pk_cliente primary key (id),
constraint fk_cliente2vendedor foreign key(id_vendedor) references vendedor(id) on update restrict on delete restrict
);

Espero ter ajudado...

Evandro Giachetto
Sistemas de Informação - Barretos-SP
[Email] [MSN]
 
Índice dos Fóruns » Java Básico
Ir para:   
Powered by JForum 2.1.8 © JForum Team