Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][MYSQL]Zapis do bazy danych z listy wyboru - dalszy ciąg
Forum PHP.pl > Forum > Przedszkole
Czapla
Cześć

Założmy że mamy dwie tabele

przy_film

  1. CREATE TABLE IF NOT EXISTS `przy_film` (
  2. `id_film` int(11) NOT NULL AUTO_INCREMENT,
  3. `tytul` varchar(80) character SET utf8 collate utf8_polish_ci NOT NULL,
  4. PRIMARY KEY (`id_film`)
  5. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=203 ;


prz_gatunek

  1. CREATE TABLE IF NOT EXISTS `przy_gatunek` (
  2. `id_gatunek` int(11) NOT NULL AUTO_INCREMENT,
  3. `gatunek` varchar(30) character SET utf8 collate utf8_polish_ci NOT NULL,
  4. PRIMARY KEY (`id_gatunek`)
  5. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;


przy_film_has_przy_gatunek

  1. CREATE TABLE IF NOT EXISTS `przy_film_has_przy_gatunek` (
  2. `id_film` int(11) NOT NULL,
  3. `id_gatunek` int(11) NOT NULL,
  4. PRIMARY KEY (`id_film`,`id_gatunek`)
  5. ) 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

  1. <tr>
  2. <td>Gatunek</td>
  3. <td>
  4. <select name="gatunek">
  5. <option value="4">aaa</option>
  6. <option value="2">fabularny</option>
  7. <option value="3">horror</option>
  8. <option value="1">komedia</option>
  9. </select>
  10. </td>
  11. </tr>



plik php tworzący formularz

[php]Gatunek
    
MMX3
Gatunek trzymany jest tu:
  1. <?php
  2. $_POST['gatunek']
  3. ?>


Chyba lepiej zamiast nazwy gatunku w value trzymać jego id
  1. <?php
  2. $lista .= '<option value="'.$aDBC->FieldByName ("gatunek") .'">'.$aDBC->FieldByName ("gatunek") .'</option>';
  3. ?>

na:
  1. <?php
  2. $lista .= '<option value="'.$aDBC->FieldByName ("id_gatunku") .'">'.$aDBC->FieldByName ("gatunek") .'</option>';
  3. ?>


Wtedy user wie co wybiera. A baza ma odrazu id.
Czapla
EDIT: PATRZ POST 1
JoShiMa
wyświetl sobie ten formularz w przeglądarce zobacz źródło strony, skopiuj ten kawałek, gdzie jest select/option i pokaż nam tu.
Czapla
EDIT: PATRZ POST 1
JoShiMa
Nie rozumiem tego:
  1. <?php
  2. $_REQUEST[$lista] == "gatunek";
  3. ?>
Czapla
bump, problem wciąż aktualny


V

ok poprawiłem ale wciąż nie działa tongue.gif
matx132
jedyne co tu widze i nie rozumiem to to:)

$POST['gatunek'];

czy nie powinno być
$_POST['gatunek'];
Czapla
W dalszym ciągu czekam na pomoc, napisałem trochę jaśniej i wytłuściłem caly problem, a kod który jest nie aktualny wyrzuciłem, aktualny kod w pierwszym poście.

UWAGA! SZCZEGÓŁY W PIERWSZYM POŚCIE
erix
Cytat
W rezultacie skrypt zapisze tylko pierwsze pole do bazy danych w liście rozwijanej, a ma zapisać wybrane.

Ale pole które? W bazie (a.k.a. kolumna), inny select, czy może masz na myśli wartość selecta, a może po prostu jednego select, bo po kodzie można wywnioskować, że pól wyboru jest trochę więcej.

Napisz jaśniej, co chcesz mieć wstawione do bazy, a co zapisuje obecnie (konkretniej!).
Czapla
Przerobiłem troche ten skrypt i pozbyłem się tabeli przy_film_has_przy_gatunek wrzuciłem do tabeli przy_film klucz obcy z tabeli przy_gatunek. Być może jeszcze zapytanie jest źle skonstruowane ponieważ skrypt teraz wogujle nie działa smile.gif wciąż pracuje nad tym smile.gif.

ZAPYTANIA DO TABEL

przy_film

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


przy_gatunek

  1. CREATE TABLE IF NOT EXISTS `przy_gatunek` (
  2. `id_gatunek` int(11) NOT NULL AUTO_INCREMENT,
  3. `gatunek` varchar(30) character SET utf8 collate utf8_polish_ci NOT NULL,
  4. PRIMARY KEY (`id_gatunek`)
  5. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;


NOWE ZAPYTANIE DO LĄCZENIA TABEL WYGLĄDA TAK (proszę o sprawdzenie czy jest poprawne):

  1. SELECT * FROM przy_film LEFT JOIN przy_gatunek ON przy_gatunek.id=przy_film.id_gatunek AND przy_film.id_gatunek = ".$ID_GATUNEK ."


Skrypt zapisujący do bazy danych

  1. <?php
  2. //(..)
  3. $SQL = "delete from przy_film where id_gatunek=". $ID_GATUNEK;
  4. $aDBC->ExecSQL ($SQL);
  5. $SQL = "SELECT * FROM przy_film LEFT JOIN przy_gatunek ON przy_gatunek.id=przy_film.id_gatunek 
    AND przy_film.id_gatunek = "
    .$ID_GATUNEK ." ";
  6. $SQL .= " order by gatunek";
  7. $aDBC ->ExecSQL ($SQL);
  8.  
  9. do{
  10. $SQL = "insert into przy_film (id_gatunek) values (";
  11. //$SQL .= $aDBC->FieldByName ("id");
  12. $SQL .= $ID_GATUNEK;
  13. $SQL .= ")";
  14. $aDBC->ExecSQL ($SQL);
  15. }while ($aDBC->Next());
  16. ?>


Skrypt tworzący formularz

  1. <?php
  2. //(..)
  3. $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 ." ";
  4. //$SQL = "SELECT * FROM przy_gatunek";
  5. $SQL .= " order by gatunek";
  6. $aDBC ->ExecSQL ($SQL);
  7. do{
  8.  $lista .= '<option value="'.$aDBC->FieldByName ("id_gatunek") .'">'.$aDBC->FieldByName ("gatunek") .'</option>';
  9. }while ($aDBC->Next());
  10. echo '<select name="gatunek">'.$lista.'</select>';
  11. ?>


Cytat
Ale pole które? W bazie (a.k.a. kolumna), inny select, czy może masz na myśli wartość selecta, a może po prostu jednego select, bo po kodzie można wywnioskować, że pól wyboru jest trochę więcej.


Tak pól wyboru było więcej ponieważ tamto zapytanie było złożone ale już je przerobiłem.
[quote]
Napisz jaśniej, co chcesz mieć wstawione do bazy, a co zapisuje obecnie (konkretniej!).
[,/quote]
Chce zapisywać do tabeli przy_film, id_gatunek, wartość selecta id_gatunek z tabeli przy_gatunek, następnie wyświetlać go po tym właśnie id w polu edycji w selectie jako gatunek [ rekord w tabeli przy_gatunek ] oraz w przeglądzie.


Edit a to zapytanie jest źle, po wrzuceniu do phpMyAdmin wypisuje mi że występuje duplikat id_gatunku w dwóch tabelach

Ktoś może mi udzielić odpowiedzi co mam nie tak?

EDIT: Naniesione poprawki
erix
A nie masz przypadkiem jakiegoś babola w tym miejscu?
  1. <?php
  2. $SQL = "insert into przy_film (id_gatunek) values (";
  3. $SQL .= $aDBC->FieldByName ("id");
  4. $SQL .= "," . $ID_GATUNEK;
  5. ?>


Chcesz wstawić dwa pola do bazy, a definiujesz tylko jedno...
Czapla
racja zarymowałem tą pierwszą linijkę

byłbym wdzięczny gdyby ktoś rzucil okiem na to zapytanie, kod i powiedzial mi co jest nie tak, bo męcze to już od "patrz data pierwszego postu smile.gif"...
erix
Przyjrzyj się polom, jakie deklarujesz w INSERT i wartościom, jakie podajesz. Jaka jest składnia INSERT? tongue.gif
Czapla
teraz to ja nie czaje o.O co jest źle?

składnia insert jest taka tongue.gif

INSERT INTO nazwa tabeli (nazwa kolumny1) values (wartości kolumny1)
erix
No właśnie. A w tamtym Twoim jest: nazwaKolumny1 => wartość1, wartość2.

Ta kluczowa jest pomijana. tongue.gif
eKuba
masz 3 kolumny
|NOT NULL auto_increment | NOT NULL | NOT NULL |
a zapytanie wstawia jedną wartość ID_GATUNEK
wydaje mi się ze powinno być
  1. INSERT INTO przy_film VALUES(NULL, '$id_gatunek', '$tytul');

a najlepiej zrób echo z tego inserta echo $SQL;
i wynik zapytania wykonaj bezpośrednio w bazie, tam wywali ci jaki to błąd.
Czapla
Tak? laugh.gif

  1. <?php
  2. $SQL = "delete from przy_film where id_gatunek=". $ID_GATUNEK;
  3. $aDBC->ExecSQL ($SQL);
  4. $SQL = "SELECT * FROM przy_film LEFT JOIN przy_gatunek ON przy_gatunek.id=przy_film.id_gatunek 
    AND przy_film.id_gatunek = "
    .$ID_GATUNEK ." ";
  5. $SQL .= " order by gatunek";
  6. $aDBC ->ExecSQL ($SQL);
  7.  
  8. do{
  9. $SQL = "insert into przy_film (id_gatunek, tytul) values ('";
  10. $SQL .= $ID_GATUNEK;
  11. $SQL .= "','";
  12. $SQL .= $TYTUL;
  13. $SQL .= "'";
  14. $SQL .= ")";
  15. $aDBC->ExecSQL ($SQL);
  16. $ID_FILM = mysql_insert_id ();
  17. }while ($aDBC->Next());
  18. ?>


Wyświetlanie mi w dalszym ciągu nie działa...

Ktoś może mi napisać jak powinno wyglądać poprawnie skonstruowane zapytanie i skrypt, Jedna satysfakcjonująca odpowiedź sad.gif To by mi bardzo pomogło i mogłbym skupić się na inne części projektu....
erix
Cały czas ktoś próbuje. ;]

Cytat
Wyświetlanie mi w dalszym ciągu nie działa...

A masz tu wyświetlanie? Uporządkuj wszystko w całość (mam na myśli tłumaczenie) logicznie, to wtedy będzie można szybciej dojść do rozwiązania.

Poza tym, IMHO, trochę jesteś niekonsekwentny; w jednym miejscu używasz funkcji ze swojej klasy abstrakcji DB, a w drugim już funkcji dotyczących obsługi konkretnej bazy.

Cytat
  1. <?php
  2. do{
  3. $SQL = "insert into przy_film (id_gatunek, tytul) values ('";
  4. $SQL .= $ID_GATUNEK;
  5. $SQL .= "','";
  6. $SQL .= $TYTUL;
  7. $SQL .= "'";
  8. $SQL .= ")";
  9. $aDBC->ExecSQL ($SQL);
  10. $ID_FILM = mysql_insert_id ();
  11. }while ($aDBC->Next());
  12. ?>


Nie rozumiem tu np. sensu pobierania ID ostatnio wstawionego rekordu, skoro go nigdzie nie używasz oraz w ogóle wstawiania wielokrotnie tych samych (!) danych; w końcu nie zmieniasz za każdym przebiegiem pętli zmiennych $ID_GATUNEK i $TYTUL. No chyba, że ta Twoja klasa tworzy takie zmienne, to by się zgadzało, ale tak, czy tak - trochę chaotycznie.
Czapla
To jeszcze raz:

mamy dwie tabele:
przy_film z koumnami id_film [PK], tytul [VARCHAR], id_gatunek [FK]
przy_gatunek z kolumnami id_gatunek [PK], gatunek

teraz chce aby id_gatunek z przy_film przechowywał wartość id_gatunek z przy_gatunek i na podstawie tego id wyświetlał gatunek z tabeli przy_gatunek w liście rozwijanej.

Na podstawie wszystkich informacji można to zrobić tak że opcje z rozwijanej listy wyświetlam selectem z tabeli przy_gatunek, każdej opcji nadaje wartość po id. W pliku set zapisuje to id do id_gatunku w tabeli przy_film.
Tylko co jeśli bede chciał ponownie zedytować rekord filmu - będe musial wykonać odwrotne zapytanie?

Kod jakim dysponuje:

Formularz
  1. <tr><td>Gatunek</td><td>
  2. <?php
  3. $SQL = " ]ZAPYTANIE";
  4. $aDBC->ExecSQL ($SQL);
  5. do{
  6.  $lista .= '<option value="'.$aDBC->FieldByName ("id_gatunek") .'">'.$aDBC->FieldByName ("gatunek") .'</option>';
  7. }while ($aDBC->Next());
  8. echo '<select name="gatunek">'.$lista.'</select>';
  9. ?> 
  10. </td></tr>

Plik zapisu set_
  1. <?php
  2. $SQL = "delete from przy_film where id_gatunek=". $ID_GATUNEK;
  3. $aDBC->ExecSQL ($SQL);
  4. $SQL = "ZAPYTANIE[";
  5. $aDBC ->ExecSQL ($SQL);
  6. do{
  7. $SQL = "insert into przy_film (id_gatunek) values ('";
  8. $SQL .= $ID_GATUNEK;
  9. $SQL .= "'";
  10. $SQL .= ")";
  11. $aDBC->ExecSQL ($SQL);
  12. $ID_FILM = mysql_insert_id ();
  13. }while ($aDBC->Next());
  14. ?>


Czyli właściwie cały problem sprowadza się do skonstruowania prawidlowych ZAPYTAŃ do bazy danych...
Mam nadzieje że wszystko jasno napisałem tongue.gif

Pozdrawiam
erix
Nie odpowiedziałeś mi na jedno.

Cytat
Nie rozumiem tu np. sensu pobierania ID ostatnio wstawionego rekordu, skoro go nigdzie nie używasz oraz w ogóle wstawiania wielokrotnie tych samych (!) danych; w końcu nie zmieniasz za każdym przebiegiem pętli zmiennych $ID_GATUNEK i $TYTUL. No chyba, że ta Twoja klasa tworzy takie zmienne, to by się zgadzało, ale tak, czy tak - trochę chaotycznie.


A "czepiam się" tego kawałka kodu:

Cytat
  1. <?php
  2. do{
  3. $SQL = "insert into przy_film (id_gatunek) values ('";
  4. $SQL .= $ID_GATUNEK;
  5. $SQL .= "'";
  6. $SQL .= ")";
  7. $aDBC->ExecSQL ($SQL);
  8. $ID_FILM = mysql_insert_id ();
  9. }while ($aDBC->Next());
  10. ?>


Wstawisz n takich samych rekordów... $ID_GATUNEK Ci się przecież nie zmienia...

Cytat
teraz chce aby id_gatunek z przy_film przechowywał wartość id_gatunek z przy_gatunek i na podstawie tego id wyświetlał gatunek z tabeli przy_gatunek w liście rozwijanej.

Cytat
Tylko co jeśli bede chciał ponownie zedytować rekord filmu - będe musial wykonać odwrotne zapytanie?

Nie. ;] Poszukaj sobie o JOIN LEFT i Twój problem z głowy. ;]
Czapla
Ok wałkujemy dalej ten temat smile.gif będe męczył póki nie otrzymam satysfakcjonującej odpowiedzi, albo mod nie zamknie ... sad.gif

Skrypt wyświetla rozwijaną listę w polu edycji ale nie zapisuje danych do bazy.

Zapytanie o  liste 
 
  1. $SQL = " SELECT pg.id_gatunek as id_g, gatunek FROM przy_gatunek pg LEFT OUTER JOIN przy_film on (pg.id_gatunek=przy_film.id_gatunek and przy_film.id_film =" .$ID_FILM .")";
  2. $SQL .= " order by gatunek";


Przyklad wyświetlania dla pola id=27



Skrypt SET - zapisu

  1. <?php
  2. $SQL = "delete from przy_film where id_gatunek=". $ID_GATUNEK;
  3. $aDBC->ExecSQL ($SQL);
  4. $SQL = " SELECT pg.id_gatunek as id_g, gatunek FROM przy_gatunek pg LEFT OUTER JOIN
     przy
  5. film on (pg.id_gatunek=przy_film.id_gatunek and przy_film.id_film =" .$ID_FILM .")";
  6. //$SQL .= " order by gatunek";
  7. $aDBC ->ExecSQL ($SQL);
  8.   $SQL = "insert into przy_film (id_gatunek, id_film) values (";
  9.   $SQL .= $aDBC->FieldByName ("id_g");
  10.   $SQL .= "," . $ID_FILM;
  11.   $SQL .= ")";
  12.   $aDBC->ExecSQL ($SQL);
  13. $_REQUEST['ID_FILM'] = "0";
  14. ?>

Formularz
 
  1. <tr><td>Gatunek</td><td>
  2.  <?php
  3.  $SQL = " SELECT pg.id_gatunek as id_g, gatunek FROM przy_gatunek pg LEFT OUTER JOIN
     przy
  4. film on (pg.id_gatunek=przy_film.id_gatunek and id_film =" .$ID_FILM .")";
  5.  $SQL .= " order by gatunek";
  6.  $aDBC->ExecSQL ($SQL);
  7.  do{
  8.   $lista .= '<option value="'.$aDBC->FieldByName ("id_g") .'">'.$aDBC->FieldByName ("gatunek") .'</option>';
  9.  }while ($aDBC->Next());
  10.  echo '<select name="gatunek">'.$lista.'</select>';
  11.   ?> 
  12.  </td></tr>


Co jest nie tak?

edit: naniesione poprawki
-Czapla-
BUMP
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.