Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php][mysql]Jak zakodować to w php?
Forum PHP.pl > Forum > PHP
lamcpp
Witam, próbuje zakodować funkcjonalność usuwania słówek z bazy danych.

Baza danych ma 3 tabele (problemem jest tu to że trzecia tabela to powiązanie pomiędzy dwoma poprzednimi tabelami i ją trzeba najpierw usunąć)

Oto tabele:
  1. CREATE TABLE tlumaczenie(
  2. id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  3. id_slowo_ang INT NOT NULL,
  4. id_slowo_pl INT NOT NULL,
  5. FOREIGN KEY(id_slowo_ang) REFERENCES slowo_ang(id),
  6. FOREIGN KEY(id_slowo_pl) REFERENCES slowo_pl(id)
  7. )ENGINE=InnoDB;
  8.  
  9. CREATE TABLE slowo_pl(
  10. id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  11. nazwa VARCHAR(40)
  12. )ENGINE=InnoDB;
  13.  
  14. CREATE TABLE slowo_ang(
  15. id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  16. wymowa VARCHAR(40),
  17. nazwa VARCHAR(40)
  18. )ENGINE=InnoDB;


i teraz żeby usunąć slowo_pl musze najpierw znaleźć id tego słowa w tabeli "tlumaczenie" usunąć rekord z tym id, a następnie znaleźć w tabeli slowo_pl to słowo i usunąć, próbuje wykonać to za pomocą następującego kodu (niestety nie wystepuje zaden błąd ale słowo nie usuwa się z bazy):
  1. <?php
  2. if($_POST['submit'])
  3. {
  4. require_once("baza.php");
  5. $slowko_ang = $_POST['slowko_ang'];
  6. $slowko_pl = $_POST['slowko_pl'];
  7. $query = "DELETE FROM tlumaczenie WHERE id_slowo_pl=(SELECT id FROM slowo_pl WHERE nazwa='$_slowko_pl')";
  8. $objekt -> query($query);
  9.  
  10. $query = "DELETE FROM slowo_pl WHERE nazwa='$slowko_pl'";
  11. $objekt -> query($query);
  12. echo "Słówko zostało usunięte.<br />";
  13. }
  14. ?>
  15.  
  16.  
  17. <h1>Usuń słówko</h1>
  18. <form action="usun_slowko.php" method="post">
  19. Wpisz słowko do usunięcia:<br />
  20. w języku polskim: <input type="text" name="slowko_pl" /><br />
  21. <input type="submit" name="submit" value="usuń"><br />
  22. </form>



czy ktoś mógłby doradzić jak to zrobić, albo chociaż co tu skopałem, ze nie działa tak jak trzeba?

JoShiMa
Tego nie musisz kodować w php. MySQL daje możliwość tworzenia powiązań między tabelami z opcją kasowania kaskadowego. Jak się to dobrze rozegra, to usunięcie rekordu z jednej tabeli spowoduje usunięcie odpowiednich rekordów z innych tabel.

Aha. Twoje zapytanie się nie wykonuje z tej prostej przyczyny, że używasz zmiennej $_slowko_pl, której nie nadajesz żadnej wartości.
thek
@JoShiMa: nie ma tak łatwo. Użycie ON DELETE CASCADE w tym przypadku to podcinanie gałęzi na jakiej się siedzi. Przy tłumaczeniach masz bowiem złączenia także inne niż 1-do-1 bo występują słowa mające wiele znaczeń, czasem w zależności od kontekstu. Prosty przykład: szczyt. W zależności od tego czy chodzi o szczyt góry, konferencję czy też coś innego, masz różne odpowiedniki w angielskim. Kaskadowa kasacja pozbawiła by Cię szybko wieloznaczności. W przypadku słownika musi usuwając klucz sprawdzać, czy do obu ze słów istnieją powiązania z innymi słowami. Dopiero ich brak pozwala na usunięcie słowa z bazy. Czasem może się okazać, że usunięcie tłumaczenia kończy się tylko na tym, innym razem pozwoli na usunięcie tłumaczenia i obu wyrazów, a czasem tylko jednego z nich. Nie można w takiej sytuacji zdać się tylko na bazę.
cojack
  1. CREATE TABLE tlumaczenie(
  2. id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  3. id_slowo_ang INT NOT NULL,
  4. id_slowo_pl INT NOT NULL,
  5. FOREIGN KEY(id_slowo_ang) REFERENCES slowo_ang(id) ON DELETE CASCADE,
  6. FOREIGN KEY(id_slowo_pl) REFERENCES slowo_pl(id) ON DELETE CASCADE
  7. )ENGINE=InnoDB;
  8.  
  9. CREATE TABLE slowo_pl(
  10. id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  11. nazwa VARCHAR(40)
  12. )ENGINE=InnoDB;
  13.  
  14. CREATE TABLE slowo_ang(
  15. id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  16. wymowa VARCHAR(40),
  17. nazwa VARCHAR(40)
  18. )ENGINE=InnoDB;


I wystarczy:
  1. $query = "DELETE FROM slowo_pl WHERE nazwa='$slowko_pl'";


lamcpp
Joshima:
poszedłem za Twoimi słowami i zastosowałem kaskadowe usuwanie robiąc tak:
alter table tlumaczenie add constraint foreign key(id_slowo_pl) REFERENCES slowo_pl(id) ON DELETE CASCADE;
alter table tlumaczenie add constraint foreign key(id_slowo_ang) REFERENCES slowo_ang(id) ON DELETE CASCADE;

czyli dokładnie to co napisał w ostatnim poście Cojack.
Tyle ze wadą takiego rozwiązania jest to, że usuwa mi tylko słówko polskie oraz tłumaczenie, a więc rekordy z dwoch tabel powiązane ze sobą, nie usuwa natomiast słowka angielskiego, które to również powinno zostać usunięte.

Dodatkowo nowe spojrzenie naświetlił thek, że odpowiedniki słówek mają różne znaczenia i tu tez problem jak to zakodować, żeby usunęło się własciwe tłumaczenie,
oraz jak zmienić moj kod(ponizej) aby usuwało się nie tylko słówko polskie i powiązanie ( z tabeli tłumaczenie) ale tez słowko angielskie które jest z nim powiązane)

Obecny kod:
  1. <?php
  2. if($_POST['submit'])
  3. {
  4. require_once('baza.php');
  5. $slowko_pl = $_POST['slowko_pl'];
  6. $query = "delete FROM slowo_pl WHERE nazwa='$slowko_pl'";
  7. $objekt -> query($query);
  8. echo "Usunięto słówko<br />";
  9. }
  10. ?>
  11.  
  12. <form action="usun_slowko.php" method="post">
  13. Podaj słówko do usnięcia(w j. polskim):<input type="text" name="slowko_pl" /><br />
  14. <input type="submit" name="submit" value="Usuń" /><br />
  15. </form>


Jedyne co mi przychodzi do głowy aby jednocześnie usunęło się słowko angielskie to dodać w formularzu pole, by użytkownik wpisał też słowko w języku angielskim a w kodzie dodać jeszcze jedno DELETE by usunąć to słowko. Wada jest taka, że przecież użytkownik nie zawsze zna słówko i jego odpowiednik w j. angielskim a więc rozwiązanie to nie jest dobre...

thek
Przecież możesz mu pokazać co może usunąć w przypadku niejednoznaczności. Jeśli masz tylko jedno dowiązanie, znaczenie, to usuwasz od razu. Jeśli więcej to zwracasz na ekran kombinacje możliwen i pytasz usera, o które mu chodzi. Dopiero to usuwasz.
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.