[php+mysql]Lista wyboru i zlączenie dwóch tabel

0

Cześć

Założmy że mamy dwie tabele

przy_film

SQL

CREATE TABLE IF NOT EXISTS przy_film (
id_film int(11) NOT NULL auto_increment,
tytul varchar(80) character set utf8 collate utf8_polish_ci NOT NULL,
PRIMARY KEY (id_film)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=203 ;

prz_gatunek

SQL

CREATE TABLE IF NOT EXISTS `przy_gatunek` (
`id_gatunek` int(11) NOT NULL auto_increment,
`gatunek` varchar(30) character set utf8 collate utf8_polish_ci NOT NULL,
PRIMARY KEY (`id_gatunek`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;

przy_film_has_przy_gatunek

SQL

CREATE TABLE IF NOT EXISTS `przy_film_has_przy_gatunek` (
`id_film` int(11) NOT NULL,
`id_gatunek` int(11) NOT NULL,
PRIMARY KEY (`id_film`,`id_gatunek`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

Każdemu filmowi przyporządkowany jest dokladnie jeden gatunek - jeden gatunek może być przyporządkowany wielu filmom - RELACJA 1:n

dla tabeli przy_film_has_przy_gatunek rekordy wyglądaj następująco

id_film/id_gatunku
1, 4
2, 4
3, 1
4, 2
5, 3

O ile w wypadku wyświetlania w formularzu rozwijanej listy z gatunkami wszystko jest OK to nie potrafie uporać się z zapisem do bazy.

Mała Legenda:

$aDBC - ustanawia połączenie do bazy
$SQL - zmienna przechowuje zapytanie SQL
FieldByName(); - pobiera rekordy z bazy
ExecSQL($SQL); - wykonuje zapytanie do bazy SQL
Next(); - zwraca kolejne rekordy

zapytanie SQL zostalo przerobione z zupełnie innego przykladu, a zmienne dostosowane do moich potrzeb...

Formularz wynik pliku php

HTML

<tr>
<td>Gatunek</td>
<td>
<select name="gatunek">
<option value="4">aaa</option>
<option value="2">fabularny</option>
<option value="3">horror</option>
<option value="1">komedia</option>
</select>
</td>
</tr>

plik php tworzący formularz

Kod PHP

    <tr><td>Gatunek</td><td>
    <?php
    $SQL  = " select pg.id_gatunek as id_g, gatunek, pfhpg.id_gatunek as id_check_g";
    $SQL .= " from przy_gatunek pg left outer join przy_film_has_przy_gatunek pfhpg on (pg.id_gatunek=pfhpg.id_gatunek";    
    $SQL .= " and pfhpg.id_film=".$ID_FILM .")";
    $SQL .= " order by gatunek";
    $aDBC->ExecSQL ($SQL);
    do{
     $lista .= '<option value="'.$aDBC->FieldByName ("id_g") .'">'.$aDBC->FieldByName ("gatunek") .'</option>';
    // if ($aDBC->FieldByName ('id_gatunek') == 
    // if ($aDBC->FieldByName ('id_g') == 'id_gatunek')
    // print (" checked ");
    }while ($aDBC->Next());
    echo '<select name="gatunek">'.$lista.'</select>';
           ?>
   </td></tr>

fragment pliku zapisu

Kod PHP

<?php
include ("define.php");

if (empty ($aDBC))
    {
    include ("dbmysql.php");
    $aDBC = new DBMySQL($MySQLServer,$MySQLDB,$MySQLUser,$MySQLPass);
    }
if (empty ($aDBC1))
    {
    $aDBC1 = new DBMySQL($MySQLServer,$MySQLDB,$MySQLUser,$MySQLPass);
    }        

    $ID_FILM     = $_REQUEST['ID_FILM'];
    $ID_GATUNEK     = $_REQUEST['ID_GATUNEK'];
    $_POST['gatunek'];

//(..)

//wybieramy gatunek z listy

        $SQL = "delete from przy_film_has_przy_gatunek where id_film=". $ID_FILM;
        $aDBC->ExecSQL ($SQL);
        $SQL = " select pg.id_gatunek as id_g, gatunek, pfhpg.id_gatunek as id_check_g";
        $SQL .= " from przy_gatunek pg left outer join przy_film_has_przy_gatunek pfhpg on (pg.id_gatunek=pfhpg.id_gatunek";    
        $SQL .= " and pfhpg.id_film=".$ID_FILM .")";
        $SQL .= " order by gatunek";
        $aDBC->ExecSQL ($SQL);
    do{
            $SQL = "insert into przy_film_has_przy_gatunek (id_gatunek, id_film) values (";
            $SQL .= $aDBC->FieldByName ("id_g");
            $SQL .= "," . $ID_FILM;
            $SQL .= ")";
            $aDBC->ExecSQL ($SQL);
        }while ($aDBC->Next());

$_REQUEST['ID_FILM'] = "0";
header('Location: lista_film.php');
include ("index.php");
?>

W rezultacie skrypt zapisze tylko pierwsze pole do bazy danych w liście rozwijanej, a ma zapisać wybrane.

Pozdrawiam

0

Jak jest relacja 1..n, to dlaczego masz tabele pomocniczą dla n..n??
Nie milej zaminić to na InnoDB i wrzucić klucz obcy do przy_film, bardzo ładnie wtedy to wyciągasz, dodajesz, usuwasz

Nie koniecznie tez musisz to robić dla InnoDB, po prostu do myisam dodajesz pole z gatunkiem.

0

Więc tabela wygląda tak:

CREATE TABLE IF NOT EXISTS `przy_film` (
  `id_film` int(11) NOT NULL auto_increment,
  `tytul` varchar(30) collate utf8_polish_ci NOT NULL,
  PRIMARY KEY  (`id_film`),
  KEY `id_gatunek` (`id_gatunek`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci COMMENT='przechowuje dane filmów' AUTO_INCREMENT=1 ;

Tabeli przy_film_has_przy_gatunek już nie ma

a moje zapytanie SQL wygląda na tą chwilę tak.

Ktoś potwierdzi czy poprawnie?

$SQL = "SELECT gatunek,id_gatunek FROM przy_gatunek, przy_film WHERE przy_gatunek.id_gatunek=przy_film.id.gatunek AND przy_film.id_gatunek = ".$ID_FILM ." ";
0

Użyj joina

SELECT  * FROM przy_film LEFT JOIN przy_gatunek ON przy_gatunek.id=przy_film.id_gatunek WHERE [....]

Dlaczego u ciebie id_gatunek jest kluczem, to musi byc int albo klucz obcy. http://www.forumweb.pl/viewtopic.php?p=238337 - tu jest cos o kluczach obcych.

A bliżej do twojego problemu to tam join nie jest potrzebny, opcje selecta z htmla tworzysz na podstawie tabeli przy_gatunek, jako value nadajesz ich id i później juz prosty select zostaje.

0
mephir napisał(a)

Użyj joina
A bliżej do twojego problemu to tam join nie jest potrzebny, opcje selecta z htmla tworzysz na podstawie tabeli przy_gatunek, jako value nadajesz ich id i później juz prosty select zostaje.

Spoko on jest kluczem tylko zapomniałem wkleić id_gatunek w zapytaniu :P

Plik set_film

//(..)
$SQL = "delete from przy_film where id_gatunek=". $ID_GATUNEK;
$aDBC->ExecSQL ($SQL);
$SQL = "SELECT  * FROM przy_film LEFT JOIN przy_gatunek ON przy_gatunek.id=przy_film.id_gatunek AND przy_film.id_gatunek = ".$ID_GATUNEK ." ";
$SQL .= " order by gatunek";
$aDBC ->ExecSQL ($SQL);

    do{
            $SQL = "insert into przy_film (id_gatunek) values (";
            $SQL .= $aDBC->FieldByName ("id");
            $SQL .= "," . $ID_GATUNEK;
            $SQL .= ")";
            $aDBC->ExecSQL ($SQL);
        }while ($aDBC->Next());
mephir napisał(a)

Użyj joina
A bliżej do twojego problemu to tam join nie jest potrzebny, opcje selecta z htmla tworzysz na podstawie tabeli przy_gatunek, jako value nadajesz ich id i później juz prosty select zostaje.

Czyli na podstawie tego co powiedziałeś formularz bedzie wyglądał tak ? :)

Skrypt tworzący formularz


//(..)
    //$SQL = "SELECT id_gatunek FROM przy_film LEFT JOIN przy_gatunek ON przy_gatunek.id=przy_film.id_gatunek AND przy_film.id_gatunek = ".     $ID_GATUNEK ." ";
    $SQL = "SELECT * FROM przy_gatunek";
    $SQL .= " order by gatunek";
    $aDBC ->ExecSQL ($SQL);
    do{
     $lista .= '<option value="'.$aDBC->FieldByName ("id_gatunek") .'">'.$aDBC->FieldByName ("gatunek") .'</option>';
    }while ($aDBC->Next());
    echo '<select name="gatunek">'.$lista.'</select>';

Pozdrawiam

0

up

problem aktualny

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0