Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][MySQL]Dodanie pierwszej oceny ucznia do bazy danych
Forum PHP.pl > Forum > Przedszkole
Userr
Będę miał panel, w którym będą podawał takie dane o uczniu:

Cytat
id ucznia
imię
nazwisko
ocena


Będą dwie tabele:

Cytat
uczniowie - pola:
id
imię
nazwisko


Cytat
oceny - pola:
id
ocena
id_ucznia

Skrypt będzie wykrywał (po id ucznia, czyli po polu id z tabeli uczniowie) czy taki uczeń jest już w tabeli. Jeżeli jest - to po prostu skrypt doda ocenę do tabeli oceny. Jeżeli nie ma, to najpierw doda imię i nazwisko do tabeli uczniowie, a następnie doda ocenę do tabeli oceny.

I właśnie o ten drugi przypadek chciałem zapytać - czy jeżeli napiszę w skrypcie PHP po sobie dwa zapytania MySQL:

  1. $sql = "INSERT INTO uczniowie (imie, nazwisko) VALUES ('Jan', 'Kowalski')";
  2.  
  3. $sql = "INSERT INTO oceny (ocena, id_ucznia) VALUES ('4', '437');
"

to czy jest gwarancja, że jako pierwsze doda się zawsze zapytanie, które jest pierwsze w kodzie (wpis do tabeli uczniowie)? Czy też może się coś zdarzyć (bardzo rzadko, ale jednak), że czasami jako pierwsze doda się zapytanie, które jest niżej w kodzie (wpis do tabeli oceny)? Jeżeli tak, to czy można się przed tym jakoś zabezpieczyć? Czy transakcje mogłyby tutaj pomóc?
woxala123
Myślę że jak będziesz używał instrukcji warunkowych to będzie Ci to robiło.
borabora
Zrób dwa widoki. jeden odpowiadający za edycję i dodawanie uczniów do klasy (skoro to ma byc dziennik, to mozesz rozbudować także o klasy, na razie z tego co widać wynika, że jest jedna). następnie drugi widok, gdzie będziesz wstawiał oceny konkretnym uczniom. Z drugiego widoku na serwer powinny polecieć 2 zmienne. Id usera i ocena. U Ciebie wyglada tak, że nauczyciel wpisuje ocenę, imię i nazwisko w jednym formularzu. W takim wypadku jeśli zrobi jakąś literówkę to zostanie dodany nowy uczeń
Userr
Cytat(woxala123 @ 12.03.2017, 16:43:30 ) *
Myślę że jak będziesz używał instrukcji warunkowych to będzie Ci to robiło.


Jakie instrukcji warunkowe masz na myśli?

Mi chodzi tylko o to, czy zapytanie MySQL, które jest w pierwsze w kodzie zawsze jako pierwsze się wykona? Bo jeżeli nie, to doszło by do sytuacji, że próbuję dodać ocenę dla ucznia, którego jeszcze nie ma w bazie.

Albo nie wiem - w momencie wykonywania pierwszego zapytania dojdzie do jakiejś chwilowej awarii czy błędu na serwerze i pierwsze zapytanie nie wykona się, a drugie już tak, bo ta awaria była tylko chwilowa - tylko czy w praktyce to jest możliwe?
viking
Tak czy inaczej grupowe inserty zależne od siebie powinny być w transakcji i rollback jeśli coś się nie powiodło.
Userr
Przykładowo te dwie powiązane transakcje:

  1. try{
  2.  
  3. //Query 1: Attempt to insert the payment record into our database.
  4. $sql = "INSERT INTO payments (user_id, amount) VALUES (?, ?)";
  5. $stmt = $pdo->prepare($sql);
  6. $stmt->execute(array(
  7. $userId,
  8. $paymentAmount,
  9. )
  10. );
  11.  
  12. //Query 2: Attempt to update the user's profile.
  13. $sql = "UPDATE users SET credit = credit + ? WHERE id = ?";
  14. $stmt = $pdo->prepare($sql);
  15. $stmt->execute(array(
  16. $paymentAmount,
  17. $userId
  18. )
  19. );
  20.  
  21. //We've got this far without an exception, so commit the changes.
  22. $pdo->commit();
  23.  
  24. }
  25. //Our catch block will handle any exceptions that are thrown.
  26. catch(PDOException $e){
  27. //An exception has occured, which means that one of our database queries
  28. //failed.
  29. //Print out the error message.
  30. echo $e->getMessage();
  31. //Rollback the transaction.
  32. $pdo->rollBack();
  33. }


http://thisinterestsme.com/php-pdo-transaction-example/

Jak dobrze rozumiem transakcje zapewniają, że jeżeli chociaż jedno z tych dwóch zapytań się nie wykona, to nie wykona się żadna z nich, ale czy jest pewność, że jeżeli wykonają się w odwrotnej kolejności (czyli najpierw aktualizacja profilu, a dopiero później dodanie pieniędzy), to też żadna z nich nie zostanie wykonana?
viking
Nie wykona się w odwrotnej kolejności.
Userr
Jeszcze jedna rzecz mnie zastanawia:
  1. /**
  2.  * Connect to MySQL and instantiate the PDO object.
  3.  * Set the error mode to throw exceptions and disable emulated prepared statements.
  4.  */
  5. $pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '', array(
  6. PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  7. PDO::ATTR_EMULATE_PREPARES => false
  8. ));


http://thisinterestsme.com/php-pdo-transaction-example/

Czy PDO::ATTR_EMULATE_PREPARES => false może jakoś wpłynąć na bezpieczeństwo? Preparowane zapytania chyba służą właśnie ochronie SQL Injection, więc skoro to wyłączę, czy nie wpłynie to na bezpieczeństwo?
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.