Dúvida em relacionamento N:N (terceira tabela)

AndreLC

Power Member
Boa noite,
Tenho uma dúvida na questão de relacionamento de muitos para muitos.
Tenho a tabela imóveis com a informação relativa ao imóvel e tenho a tabela divisao com a informação relativa às divisões que poderá existir para um imóvel.
Pela lógica criei a tabela imovel_divisoes que possui ambos os ids das tabelas imoveis e divisao juntamente com a descricao e metros quadrados, pois necessito desta informação também.
Código:
CREATE TABLE IF NOT EXISTS `imoveis` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `estado` varchar(50) DEFAULT NULL,
  `area_util` varchar(255) DEFAULT NULL,
  `area_bruta` varchar(255) DEFAULT NULL,
  `area_terreno` varchar(255) DEFAULT NULL,
  `montante` varchar(255) DEFAULT NULL,
  `morada` varchar(255) DEFAULT NULL,
  `codpostal` varchar(4) DEFAULT NULL,
  `codpostal_ind` varchar(3) DEFAULT NULL,
  `localidade` varchar(255) DEFAULT NULL,
  `id_distrito` int(11) DEFAULT NULL,
  `id_concelho` int(11) DEFAULT NULL,
  `freguesia` varchar(50) DEFAULT NULL,
  `mini_descricao` varchar(255) DEFAULT NULL,
  `descricao` varchar(800) DEFAULT NULL,
  `Imagem1` varchar(255) DEFAULT NULL,
  `Imagem2` varchar(255) DEFAULT NULL,
  `Imagem3` varchar(255) DEFAULT NULL,
  `Imagem4` varchar(255) DEFAULT NULL,
  `Imagem5` varchar(255) DEFAULT NULL,
  `estado` tinyint(1) NOT NULL DEFAULT '2',
  `data_insercao` date NOT NULL,
  PRIMARY KEY (`id`),
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;

INSERT INTO `imoveis` (`id`, `id_estado`, `area_util`, `area_bruta`, `area_terreno`, `montante`, `morada`, `codpostal`, `codpostal_ind`, `localidade`, `id_distrito`, `id_concelho`, `freguesia`, `mini_descricao`, `descricao`, `Imagem1`, `Imagem2`, `Imagem3`, `Imagem4`, `Imagem5`, `estado`, `data_insercao`) VALUES
(1, 'Novo', 'n/a', 'n/a', 'n/a', '144.000', 'Rua D. Afonso henriques', '5454', '565', 'Castelo Branco', 5, 149, 'Castelo Branco', 'Garagem, com acesso a casa pelo exterior. Piscina interior.', 'Moradia composta por R/C, 1º Andar e Sotão. R/C - Sala 20m², acesso ao terraço, cozinha 14m², móveis em carvalho e bancada em granito, acesso ao terraço e WC. 1º Andar - Quarto 14m², varanda, quarto 15m², roupeiro e varanda, suite 16m², 2 roupeiros. Garagem e piscina.', 'Imagem0001.jpg', 'Imagem002.jpg', 'Imagem03.jpg', 'Imagem004.jpg', 'Imagem005.jpg', 1, '2012-02-02'),

CREATE TABLE IF NOT EXISTS `divisao` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nome` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=32 ;

INSERT INTO `divisao` (`id`, `nome`) VALUES
(1, 'Arrecadação'),
(2, 'Alpendre'),
(3, 'Biblioteca'),
(4, 'Casa de Banho'),
(5, 'Casa de Banho'),
(6, 'Casa de Banho'),
(7, 'Casa de Banho'),
(8, 'Casa de Banho'),
(9, 'Casa de Banho Partilhada'),
(10, 'Casa de Banho Privativa'),
(11, 'Closet'),
(12, 'Corredor'),
(13, 'Cozinha'),
(14, 'Cozinha Equipada'),
(15, 'Cozinha semi-equipada'),
(16, 'Despensa'),
(17, 'Escritório'),
(18, 'Hall'),
(19, 'Hall de Quartos'),
(20, 'Quarto'),
(21, 'Quarto'),
(22, 'Quarto'),
(23, 'Quarto'),
(24, 'Quarto'),
(25, 'Quarto Visitas'),
(26, 'Sala Comum'),
(27, 'Sala de Estar'),
(28, 'Sala de Jantar'),
(29, 'Sotão'),
(30, 'Suite'),
(31, 'Suite');

CREATE TABLE IF NOT EXISTS `imovel_divisoes` (
  `imovel_id` int(11) NOT NULL,
  `divisao_id` int(11) NOT NULL,
  `descricao` varchar(255) NOT NULL,
  `metros_quadrados` int(11) NOT NULL,
  PRIMARY KEY (`imovel_id`,`divisao_id`),
  KEY `imovel_id` (`imovel_id`),
  KEY `divisao_id` (`divisao_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Acrescentei as divisões com checkboxes utilizando:

PHP:
    <?php
  
  $q = mysql_query("SELECT * from divisao");
  while($nomes = mysql_fetch_array($q)){
    ?>
     <input type="checkbox" name="divisoes[]" id="<?php echo $nomes["id"]; ?>" value="<?php echo $nomes["nome"]; ?>" onClick="chckd()"><?php echo $nomes["nome"]; ?>
     <div id="div_<?php echo $nomes["id"]; ?>" style="display: none;">
         <input name="desc_<?php echo $nomes["nome"]; ?>" type="text" id="desc_<?php echo $nomes["nome"]; ?>" size="61" value="Digite aqui a descrição" onfocus="if (this.value == 'Digite aqui a descrição') {this.value = '';}" onblur="if (this.value == '') {this.value = 'Digite aqui a descrição';}" class="form_pesquisa" />
         <input name="area_<?php echo $nomes["id"]; ?>" type="text" id="area_<?php echo $nomes["id"]; ?>" size="2" /> <label>m²</label></div>
       
    <?php
        };
    ?>
E conforme a imagem:
img01ui.jpg

À medida que clico na checkbox surge a caixa de texto para introdução da descrição e dos metros quadrados.

A minha dúvida é que eu estava a fazer um simples INSERT INTO para a tabela imóveis, mas agora como tenho a terceira tabela, tenho que fazer outro INSERT INTO para esta terceira tabela (imovel_divisões), ficando com 2 INSERT INTO ou há outra maneira mais eficiente de fazer?
Desculpem a pergunta, mas ainda não tinha necessidade de efectuar a gestão de registos com relacionamento N:N.
Obrigado pela ajuda.
Cumprimentos,
AndreLC
 
Crias uma stored procedure =)

Exemplo:
Código:
CREATE PROCEDURE sp_add_imovel
 @var1_tbl1 int,
 @var2_tbl1 int,
 @var3_tbl1 int,
 @var1_tbl2 int,
 @var2_tbl2 int
AS
 Begin

  Set Nocount On
  
  DECLARE @chave int
  
  INSERT INTO tbl1(var1, var2, var3) 
  VALUES (@var1_tbl1, @var2_tbl1, @var3_tbl1)
  
  SELECT @chave=@@IDENTITY
  
  INSERT INTO tbl2(fk_id, var1, var2)
  VALUES (@chave, @var1_tbl2, @var2_tbl2)
  
 End
 
Já insere na tabela de associação, mas agora há um pequeno problema...

Fazendo um echo à query, reparo que me retorna 31 (que é o número de checkboxes que tenho) INSERT INTO, contudo adiciona somente na tabela uma vez como se esperava, mas queria colocar isto correctamente.

A imagem do echo à query:

abclq.jpg


Sei que é por estar dentro do ciclo, mas se retirar dentro do ciclo, se eu seleccionar 3 checkboxes, por exemplo, apenas grava-me a informação da última checkbox na tabela.

Queria corrigir essa situação. Poderiam ver o que se passa?

Tenho assim:

Código:
//INSERT de Imoveis - Aqui tudo bem
$query_imoveis = "INSERT INTO imoveis (...) VALUES (...)";
mysql_query($query_imoveis);
$id_imovel = mysql_insert_id();
//INSERT de imovel_divisoes na tabela de associação (DÚVIDA)
// obter a lista de divisões
$rs = mysql_query("SELECT * from divisao");
while (($divisoes = mysql_fetch_array($rs)) != null) {
    // verificar se a info/id do registo vem assinalada pelos checkboxes
    if (isset($_POST['divisoes'])) {
        foreach ($_POST['divisoes'] as $key => $id_divisao) {
            $desc_divisao = $_POST['desc'][$id_divisao];
            $metros       = $_POST['area'][$id_divisao];
            
            $query_imoveisdivisoes = "INSERT INTO `imovel_divisoes` (imovel_id, divisao_id, descricao, metros_quadrados) VALUES ('$id_imovel', '$id_divisao', '$desc_divisao', '$metros')";
            mysql_query($query_imoveisdivisoes);
            //echo $query_imoveisdivisoes;
        } //foreach
    } //if
} //while

Obrigado pela ajuda.
 
Podem dar uma vista de olhos, por favor?

Agora tendo o adicionar como faço o actualizar e o apagar?

Pois, por exemplo, no actualizar se escolher mais outra checkbox terá que inserir um novo registo na terceira tabela, mas se quiser desmarcar uma checkbox que já tivesse inserido terá que apagar o registo na terceira tabela, então não vai ser bem um update não é verdade?

A ideia seria como este exemplo: http://examples.codecharge.com/ExamplePack/ManyToManyCheckbox/ManyToManyCheckbox.php

Obrigado pela ajuda e atenção.
 
Última edição:
Back
Topo