Jump to content
Fórum Script Brasil
  • 0

Ajuda! Duvida sobre relacionamento M para M no mysql


Elaine Mendes

Question

:rolleyes:

Bom Dia!

Gente eu sou novata em BD e estou precisando de ajuda.... MYSQL

Estou criando um banco de dados de uma escola infantil e estou com a seguinte situação:

Tenho as seguintes tabelas:

-aluno

-pai

-empresa_pai

-mae

-empresa_mae

Como tenho que ter os dados dos pais, inclusive da empresa onde trabalham, então criei tabelas separadas, pois há casos em que os pais podem estar separados, e os dados do pai e mae na mesma tabela iriam virar uma bagunca.. Bem mas a minha duvida esta nas tabelas "pai" e "empresa_pai", pois o relacionamento de ambas na minha concepção é M para M, pois um pai pode trabalhar em 0 ou N empresas, e uma empresa pode ter 1 ou N pais....(Bem se eu estiver errada no raciocinio por favor me digam!).

Como o relacionamento ficou de M para M então criei uma terceira tabela a "pai_emp_pai" que recebeu a PK das tabelas pai e empresa_pai, porem quando faço um insert nas tabelas, a pai_emp_pai não recebe os valores. Como eu faço para que a cada inserção feita nas duas tabelas a terceira tabela receba os valores automaticamente?

Ah! Os campos na terceira tabelas estao como FK..

Por favor me ajudem...

Obrigada!!

Link to comment
Share on other sites

5 answers to this question

Recommended Posts

  • 0
:rolleyes:

...

Como o relacionamento ficou de M para M então criei uma terceira tabela a "pai_emp_pai" que recebeu a PK das tabelas pai e empresa_pai, porem quando faço um insert nas tabelas, a pai_emp_pai não recebe os valores. Como eu faço para que a cada inserção feita nas duas tabelas a terceira tabela receba os valores automaticamente?

Ah! Os campos na terceira tabelas estao como FK..

Por favor me ajudem...

Obrigada!!

Oi 'Elaine Mendes',

Creio que existem tabelas de mais. Você precisaria somante de quatro tabelas físicar para suportar seu modelo.

Tabela Alunos, Tabela Pais (com um atributo indicador de pai ou mae), Tabela Empresas e Tabela Relacionamento_Empresas_Pais.

A tabela pais seria o lado muitos de um relacionamento um para muitos entre aluno e pais

O relacionamento entre Pais e Empresas é M:N (muitos para muitos) e, por isto, existe a tabela Relacionamento_Empresas_Pais

A insersão de dados na tabela de relacionamento deve ser feita na mesma transação em que você está inserindo dados em Pais e Empresas antes do COMMIT para fechar toda a transação. Não é um processo automático. Você deverá escrever um código para isto.

Link to comment
Share on other sites

  • 0

Ola Denis,

Entendi o que você explicou, mas tenho mais uma dúvida, de que forma eu posso criar o codigo para inserir os dados na tb pais, empresa e empresa_pais? Entendi a logica, mas não sei como fazer a inserção das chaves pk (pais, empresa) na tabela empresa_pais de uma forma automatizada não perdendo a integridade dos dados. Tentei criar uma trigger mas não deu certo.. Pelo que entendi a trigger pode ser executada antes, ou depois de uma ação (insert, update ou delete), mas em uma unica tabela. Pensei em criar uma trigger para executar a inserção das chaves na tabela (empresa_pais) após a realização do insert nas tabelas pais e empresa, mas não funcionou. Pensei em procedure mas eu vou ter q executá-la toda vez, e eu queria um processo automatico para evitar erros..

Bem você sabe como eu posso fazer isso??

Grata,

Elaine

Link to comment
Share on other sites

  • 0
Ola Denis,

Entendi o que você explicou, mas tenho mais uma dúvida, de que forma eu posso criar o codigo para inserir os dados na tb pais, empresa e empresa_pais? Entendi a logica, mas não sei como fazer a inserção das chaves pk (pais, empresa) na tabela empresa_pais de uma forma automatizada não perdendo a integridade dos dados. Tentei criar uma trigger mas não deu certo.. Pelo que entendi a trigger pode ser executada antes, ou depois de uma ação (insert, update ou delete), mas em uma unica tabela. Pensei em criar uma trigger para executar a inserção das chaves na tabela (empresa_pais) após a realização do insert nas tabelas pais e empresa, mas não funcionou. Pensei em procedure mas eu vou ter q executá-la toda vez, e eu queria um processo automatico para evitar erros..

Bem você sabe como eu posso fazer isso??

Grata,

Elaine

Oi Elaine,

Para este tipo de processo você deverá criar uma rotina que pode ser uma storage procedure (o que não recomando pois o MySQL ainda carece de mensagem de retorno em caso de ABEND de transação) ou através de linguagem de programação que você usa.

Você deverá seguir a seguinte logica:

Cadastrar Empresa

Cadastrar Pais

Gravar relacionamento Empresa_x_Pais.

Os cadastros de empresa e pais podem ser independentes pois suas gravações não afetam nada.

Eu coloquei a empresa primeiro poque deverá haver uma quantidade menor de empresa do que de pais. Então sua gravação será independente.

Coloquei o cadastro de pais em segundo lugar porque dentro dele já vou buscar a empresa que ele trabalha.

Quando for gravar a informação dos pais e do relacionamento entre empresa e pais usarei uma unica transação seguindo a logica abaixo para executála:

A lógica abaixo é usada quando você define que seu MySQl NÃO possuirá COMMIT automático

Iniciar transação
Gravar Pais
Gravar Relacionamento Empresa_x_Pais
Commitar transação
Se houver erro
    dar rollback na transação
Fim de transação
Uma outra forma que segue lógica parecida é usada quando você define seu MySQl com COMMIT automático
Gravar Pais
COMMIT
Gravar Relacionamento Empresa_x_Pais
COMMIT

Link to comment
Share on other sites

  • 0

Oi, Denis.

Entendi o processo que voce mostrou, mas na pratica fiz assim:

- Procedures criadas para inserir os dados nas tabelas: empresas, pais.

Em seguida tentei criar uma trigger para que cada inserção realizada na tabela "pais", seja realizado um insert na tabela empresas_pais com o ID dos pais, mas gerou erro.

Pensei em criar uma trigger para cada tabela (pais, empresas) mas naõ deu certo a trigger que eu fiz.

1ª Trigger criada>>>

DELIMITER $$

CREATE TRIGGER inserir_p_emp1 AFTER INSERT ON pais

FOR EACH ROW

BEGIN

DECLARE _pais_cpf int;

select pais_cpf_cnpj from pais;

BEGIN

INSERT INTO pais_empresas values (_pais_cpf);

END;

END$$

Gera o seguinte erro ao tentar inserir dados na tabela pais: Error Code: 1415. Not allowed to return a result set from a trigger *****

2ª Trigger criada>>>

DELIMITER $$

CREATE TRIGGER inserir_p_emp1 AFTER INSERT ON pais

FOR EACH ROW

BEGIN

IF (pais_cpf_cnpj is not null) THEN

INSERT INTO pais_empresas set pais_cpf_cnpj = pais_cpf_cnpj;

END IF;

END$$

Quando vou fazer um insert na tabela pais gera o seguinte erro:

Error Code: 1054. Unknown column 'pais_cpf_cnpj' in 'field list'

Bem queria criar uma rotina que fizesse um select nas duas tabelas e inserisse os dados na terceira.

Fiz este select, que retornou o cod dos pais e o codigo da empresa..

select pais.pais_cpf_cnpj, emp_id from pais, empresas

where pais.emp_nome = empresas.emp_nome;

Como eu posso fazer isso? Pensei na trigger mas não consegui chegar colocar em pratica esse raciocinio.

Grata,

Elaine

Link to comment
Share on other sites

  • 0
Entendi o processo que voce mostrou, mas na pratica fiz assim:

- Procedures criadas para inserir os dados nas tabelas: empresas, pais.

Em seguida tentei criar uma trigger para que cada inserção realizada na tabela "pais", seja realizado um insert na tabela empresas_pais com o ID dos pais, mas gerou erro.

Pensei em criar uma trigger para cada tabela (pais, empresas) mas naõ deu certo a trigger que eu fiz.

...

Oi Elaine,

Você entendeu, mas não fez o que falei.

Ao escrever sua trigger você cometeu alguns erros.

1º Você está tentando misturar banana com laranja.

Veja sua trigger:

...
      DECLARE _pais_cpf int;
        select pais_cpf_cnpj from pais;
    BEGIN
        INSERT INTO pais_empresas values (_pais_cpf);
    END;
    END$$
Você declarou uma variável, não a usou para receber nenhum valor e, quando fez o insert usou a variável vazia. 2º Ao fazer uma trigger assim você corre o risco de criar uma inconsistencia de dados na tabela pais_empresas, pois ela só estará recebendo dados da tabela pais. 3º Este é menos grave mas não mais importante que os outros. Um CPF pode ser uma chave única mas não deve ser nunca a chave primária. Chaves primárias são feitas única e exclusivamente para ligar uma tabela a outra. Normalmente eu evito - esta é uma prática minha - colocar mais mais de um atributo (campo) como chave primária em uma tabela. Vendo o código da segunda trigger que você mostrou
DELIMITER $$

CREATE TRIGGER inserir_p_emp1 AFTER INSERT ON pais
    FOR EACH ROW 
    BEGIN
     IF (pais_cpf_cnpj is not null) THEN
        INSERT INTO pais_empresas set pais_cpf_cnpj = pais_cpf_cnpj;
         END IF;
    END$$
Os seguintes erros foram cometidos: 1º O comando insert está errado. ele não usa o SET nem o sinal de igual. Veja a documentação do MySQL para saber como é o comando http://scriptbrasil.com.br/forum/index.php...st&p=478131 Já que você insiste em colocar seu código para alimentação da tabela pais_empresas em uma trigger vou escrever uma rotina abaixo para que você possa ter uma idéia. Supondo que anteriormente você fez a instrução de inserção de empresa e que a chave primária da tabela empresa é IDEMPRESA e que IDEMPRESA é INTEGER NOT NULL AUTO_INCREMENT Supondo que o atributo que representa a empresa na tabela pais_empresas também se chama IDEMPRESA, então teremos:
DELIMITER $$;
CREATE TRIGGER inserir_p_emp1 AFTER INSERT ON pais
    FOR EACH ROW 
    BEGIN
         DECLARE vIDEMPRESA INTEGER NOT NULL DEFAULT 0;
         SET vIDEMPRESA = (SELECT MAX(IDEMPRESA) FROM EMPRESA); /*Pega o ultimo registro inserido na tabela empresa*/
         INSERT INTO pais_empresas(IDEMPRESA, pais_cpf_cnpj)
         VALUES(vIDEMPRESA, NEW.pais_cpf_cnpj); /* o NEW na frente do atributo pais_cpf_cnpj, diz ao trigger para pegar o valor que ele acabou de inserir para este atributo na tabela pais*/
    END$$
DELIMITER;$$

Faça a modificação necessária para atender sua necessidade e reporte se tiver mais dúvidas.

Não deixe de ler o Manual do MySQL. É muito importante como referência. Eu o uso sempre.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Forum Statistics

    • Total Topics
      152.2k
    • Total Posts
      652k
×
×
  • Create New...