Zapytanie UPDATE zmienia jeden wiersz w tabeli products
Zapytanie DELETE usuwa cały wiersz z tabeli
WHERE jest obowiązkowe - bez niego operacja trafia w całą tabelę
Ćwiczenie: strony, które zmieniają i usuwają produkt
Rozgrzewka · 3 minuty
Rozgrzewka: INSERT i bezpieczeństwo
Dlaczego do kolumny id nie wpisujemy nic, tylko NULL - kto nadaje jej właściwą wartość?
Jaką wartość zwraca mysqli_query() po udanym zapytaniu INSERT?
Czym zapytanie przygotowane różni się od zapytania sklejonego z tekstu?
Część 1 · Zmieniamy jeden wiersz
Zapytanie UPDATE: zmieniamy jeden wiersz
UPDATE nie dokłada nowego wiersza jak INSERT - poprawia wartości w wierszu, który już jest w tabeli. Bez klauzuli WHERE zmiana trafiłaby do wszystkich wierszy naraz (o tym za chwilę), dlatego WHERE id = 2 wskazuje dokładnie jeden wiersz do poprawki.
PHP Manual: mysqli.query.php („For other successful queries, mysqli_query() will return true.”, php.net/manual/en/mysqli.query.php) - UPDATE jest takim „innym” udanym zapytaniem
Część 2 · Usuwamy cały wiersz
Zapytanie DELETE: usuwamy cały wiersz
DELETE nie zmienia wartości w wierszu jak UPDATE - usuwa cały wiersz z tabeli, razem ze wszystkimi kolumnami. Wykonuje się tą samą funkcją mysqli_query(), co INSERT i UPDATE.
MariaDB Server docs: zapytanie DELETE usuwa wiersze z tabeli (mariadb.com/docs/server/reference/sql-statements/data-manipulation/delete)
Część 3 · WHERE jest obowiązkowe
WHERE jest obowiązkowe
Klauzula WHERE mówi, który wiersz (albo które wiersze) ma dotknąć UPDATE lub DELETE. Bez niej warunku nie ma wcale - operacja trafia we wszystkie wiersze tabeli naraz. To najczęstszy błąd początkującego: jedna zapomniana klauzula kasuje albo zmienia całą tabelę.
Ciekawostka: MySQL ma tryb „bezpiecznych aktualizacji” (safe updates), w którym UPDATE i DELETE bez klauzuli WHERE (albo LIMIT) od razu kończą się błędem - twórcy MySQL uznali zapomniane WHERE za tak częsty błąd, że dodali przed nim osobne zabezpieczenie.
MariaDB Server docs: bez WHERE zapytania UPDATE i DELETE działają na wszystkich wierszach tabeli (mariadb.com/docs/server/reference/sql-statements/data-manipulation/update, .../delete) · ciekawostka: „Enabling sql_safe_updates causes UPDATE and DELETE statements to produce an error if they do not specify a key constraint in the WHERE clause, or provide a LIMIT clause, or both.” (dev.mysql.com/doc/refman/8.4/en/mysql-tips.html)
Część 4 · Ile wierszy zmieniliśmy
mysqli_affected_rows(): licznik na wyjściu
Po UPDATE lub DELETE funkcja mysqli_affected_rows($db) mówi, ile wierszy naprawdę zmieniło się w bazie. Wartość 0 nie jest błędem - oznacza, że żaden wiersz nie pasował do WHERE.
PHP Manual: „An integer greater than zero indicates the number of rows affected or retrieved. Zero indicates that no records were updated […] -1 indicates that the query returned an error…” (php.net/manual/en/mysqli.affected-rows.php)
Egzamin INF.03
Tak pytają na egzaminie
1.$zapytanie="UPDATE kadra SET stanowisko='Programista' WHERE id < 10"; mysqli_query($db, $zapytanie); W kodzie PHP wykonano przedstawioną operację na bazie danych. Której funkcji należy użyć, aby pobrać liczbę zmienionych w tabeli wierszy?
mysqli_num_rows()
mysqli_use_result()
mysqli_field_count()
mysqli_affected_rows()
2.mysqli_query($db, "DELETE FROM produkty WHERE status < 0"); $x = mysqli_affected_rows($db); Jaką wartość przyjmie zmienna x po wykonaniu kodu PHP przedstawionego w ramce?
Liczby wierszy dodanych do tabeli produkty.
Liczby wierszy znajdujących się w bazie danych.
Liczby wierszy przetworzonych zapytaniem DELETE FROM
Liczby wierszy tabeli produkty, dla których pole status jest większe od zera.
CKE, EE.09, styczeń 2026, zadanie 8 · CKE, E.14, styczeń 2020, zadanie 39
Ćwiczenie przy komputerze · 15 minut
Ćwiczenie: zmieniamy i usuwamy produkt
W folderze swojego serwera (np. htdocs) utwórz plik update-product.php: połącz się z bazą tak jak w connect-database.php, odbierz $_GET["id"] i $_GET["price"].
Zbuduj i wykonaj "UPDATE products SET price = '...' WHERE id = ...", wypisz mysqli_affected_rows($db).
Utwórz delete-product.php: odbierz $_GET["id"], wykonaj "DELETE FROM products WHERE id = ...", wypisz mysqli_affected_rows($db).
Sprawdź w przeglądarce: localhost/update-product.php?id=2&price=4.20, potem localhost/delete-product.php?id=3. Za każdym razem sprawdź wynik w phpMyAdmin.
Zapisz zmiany w repozytorium: commit „Dodaje update-product.php i delete-product.php” i push.
Całe pliki
// update-product.phpmysqli_report(MYSQLI_REPORT_OFF);
$db = mysqli_connect(
"localhost", "root", "", "shop");
if (!$db) {
die("Błąd połączenia.");
}
$id = $_GET["id"];
$price = $_GET["price"];
$query = "UPDATE products
SET price = '$price'
WHERE id = $id";
mysqli_query($db, $query);
echo"Zmienionych: "
. mysqli_affected_rows($db);
// delete-product.phpmysqli_report(MYSQLI_REPORT_OFF);
$db = mysqli_connect(
"localhost", "root", "", "shop");
if (!$db) {
die("Błąd połączenia.");
}
$id = $_GET["id"];
$query = "DELETE FROM products
WHERE id = $id";
mysqli_query($db, $query);
echo"Usuniętych: "
. mysqli_affected_rows($db);
Na koniec
Sprawdź się
Czym różni się skutek zapytania UPDATE od skutku zapytania DELETE na tym samym wierszu?
Co się stanie, jeśli wykonasz DELETE FROM products bez klauzuli WHERE?
Co oznacza wynik 0 zwrócony przez mysqli_affected_rows() - błąd czy poprawną odpowiedź bazy?
Na następnej lekcji: powtórka całego tematu - connect, SELECT, INSERT, UPDATE, DELETE i obsługa błędów.
Poza szkołą
A jak to wygląda w produkcji?
Na lekcji
W produkcji
Status
UPDATE/DELETE sklejone z $_GET wprost w tekście zapytania
Zapytania przygotowane (mysqli_prepare + bind_param, albo PDO - PHP Data Objects, inny sposób łączenia PHP z bazą) - dane nigdy nie wchodzą wprost do tekstu zapytania.
nadal w użyciu (dobra praktyka)
Kasowanie wiersza usuwa go z tabeli na zawsze
„Miękkie usuwanie” (soft delete) - wiersz dostaje znacznik deleted_at zamiast znikać, dane zostają do odzyskania.
nadal w użyciu (w wielu frameworkach)
Brak potwierdzenia przed DELETE
Interfejs pyta „na pewno usunąć?” i loguje, kto i kiedy usunął wiersz - to dziennik operacji (audit log).
nadal w użyciu
Ręczne sprawdzanie mysqli_affected_rows() po każdej operacji
ORM (ang. Object-Relational Mapping - kod, który sam zamienia dane PHP na zapytania SQL) zwraca gotowy obiekt i rzuca wyjątkiem, gdy operacja się nie powiedzie.