SQL od podstaw · część 23

UPDATE i DELETE: bezpieczna zmiana danych

Aktualizuj i usuwaj wybrane rekordy. Rozróżniaj DELETE, TRUNCATE i DROP oraz sprawdzaj skutki operacji i relacje między tabelami.

Część bazodanowa INF.03

UPDATE zmienia wartości istniejących wierszy

INSERT dodaje rekord, UPDATE zmienia wybrane rekordy, DELETE je usuwa. Przed zmianą w rzeczywistej bazie odczytaj dane z dokładnie tym samym warunkiem WHERE. Ustal docelową bazę, spodziewaną liczbę wierszy oraz możliwość cofnięcia. W przeglądarkowym edytorze działasz wyłącznie na syntetycznych danych, które odtwarza Reset bazy.

SELECT id, imie, miasto FROM klienci WHERE id = 4;
UPDATE klienci SET miasto = 'Poznan' WHERE id = 4;
SELECT id, imie, miasto FROM klienci WHERE id = 4;

Ewa miała NULL miasta, po zmianie ma Poznan. SET podaje nową wartość, WHERE wybiera wiersz. Bez WHERE polecenie zmieni miasto wszystkich klientów. To poprawna składnia, ale zwykle inny zamiar niż aktualizacja jednej osoby.

Wypróbuj zapytanie

SQLite — rzeczywisty silnik przeglądarki. MySQL / SQL Server — ograniczona emulacja składni. Wybierz tryb SQLite do natywnego LIKE. Pozostałe tryby nie są rzeczywistymi serwerami. Ścisłe typy, auto-ID i administrację ćwicz w prawdziwym SZBD.

Ładowanie edytora…

Obliczenie nowej wartości i wiele kolumn

UPDATE produkty SET cena = cena + 10 WHERE id = 4;
SELECT id, nazwa, cena FROM produkty WHERE id = 4;

UPDATE klienci
SET miasto = 'Poznan', email = '[email protected]'
WHERE id = 4;

Cena Kabla po pierwszym uruchomieniu wzrośnie z 25 do 35. Kolejne uruchomienie podniesie ją do 45. Takie polecenie nie jest idempotentne. Ustawienie cena = 35 ponowione przy niezmienionych warunkach pozostawia tę samą wartość. Po utracie połączenia nie ponawiaj automatycznie operacji „dodaj 10” bez sprawdzenia, czy pierwsza się wykonała.

Nie polegaj na kolejności przypisań między różnymi kolumnami w SET; reguły mogą zależeć od silnika. Liczba „zmienionych” lub „dopasowanych” wierszy raportowana przez klienta też nie zawsze oznacza to samo. Odczyt konkretnego rekordu jest czytelniejszym potwierdzeniem oczekiwanego stanu.

DELETE usuwa wiersz, nie kolumnę

SELECT id, imie FROM klienci WHERE id = 5;
DELETE FROM klienci WHERE id = 5;
SELECT id, imie FROM klienci ORDER BY id;

Po resecie Adam nie ma zamówień, więc można usunąć jego rekord bez naruszenia klucza obcego. Usunięcie Ali jest blokowane przez powiązane zamówienia w naszym schemacie. Nie wyłączaj kontroli FK, aby ominąć taki błąd. Ustal regułę biznesową: zakaz usunięcia, jawne uporządkowanie zależnych danych albo wcześniej zaprojektowana kaskada.

W aplikacji czasem zamiast fizycznego usunięcia stosuje się flagę aktywny lub datę usunięcia. To decyzja projektowa: wymaga odpowiednich filtrów w raportach i nie zastępuje polityki retencji danych. W zadaniu egzaminacyjnym wykonuj dokładnie wymagane polecenie na wskazanej bazie ćwiczeniowej.

DELETE, TRUNCATE i DROP

PolecenieCelWHERECo zostaje?
DELETE FROM tabelaUsunięcie rekordówMoże ograniczyć zbiórDefinicja tabeli i rekordy nieobjęte warunkiem
TRUNCATE TABLE tabelaOpróżnienie tabeli specjalną operacją silnikaNieDefinicja tabeli; szczegóły generatorów i ograniczeń zależą od silnika
DROP TABLE tabelaUsunięcie obiektu tabeliNieBrak tej tabeli; zależności mogą blokować operację

Nie ucz się hasła „TRUNCATE zawsze można/nie można cofnąć”. W MySQL/MariaDB TRUNCATE powoduje implicit commit; w Oracle 19c również nie cofniesz go zwykłym ROLLBACK. W SQL Server TRUNCATE TABLE może być cofnięte wewnątrz właściwej transakcji. W MySQL i SQL Server resetuje także licznik auto-ID/IDENTITY, ale nie przenoś tej reguły na wszystkie mechanizmy sekwencji.

Access i SQLite nie mają polecenia TRUNCATE TABLE. W edytorze jest ono odrzucane. Nie przedstawiamy DELETE jako dokładnej emulacji TRUNCATE, bo różnią się uprawnienia, dziennikowanie, wyzwalacze, transakcje i liczniki. Zwykłe DELETE nie usuwa samej struktury.

Ten sam prosty UPDATE i DELETE w czterech środowiskach

Przykłady UPDATE klienci SET miasto = 'Poznan' WHERE id = 4; oraz DELETE FROM klienci WHERE id = 5; mają wspólną podstawową składnię w MySQL/MariaDB, SQL Server, Oracle 19c i Access. Różnice pojawiają się przy aktualizacji przez JOIN, ograniczaniu liczby zmienianych wierszy i zwracaniu zmienionych rekordów (np. OUTPUT/RETURNING). Nie dodawaj LIMIT z MySQL do UPDATE SQL Server ani SELECT TOP jako przypadkowej poprawki.

W edytorze nie obsługujemy całej składni wielotabelowego UPDATE/DELETE. Prosty DML działa na własnej bazie SQLite. Po błędzie pakietu edytor przywraca stan sprzed pakietu; nie jest to dowód identycznego zachowania transakcji serwera.

Ćwiczenia

  1. Po resecie zmień status zamówienia 2 na oplacone i odczytaj rekord.
  2. Podnieś o 5 ceny produktów tańszych niż 100. Które wiersze się zmienią?
  3. Usuń klienta 5, a następnie przywróć dane przyciskiem Reset bazy. Wyjaśnij, dlaczego to nie jest odpowiednik odzyskiwania produkcyjnej bazy.
Rozwiązania
UPDATE zamowienia SET status = 'oplacone' WHERE id = 2;
SELECT id, status FROM zamowienia WHERE id = 2;
UPDATE produkty SET cena = cena + 5 WHERE cena < 100;
SELECT id, nazwa, cena FROM produkty ORDER BY id;
DELETE FROM klienci WHERE id = 5;

1. Zamówienie 2 ma nowy status. 2. Mysz 65 i Kabel 30, jeśli zaczynasz od resetu. 3. Reset ładuje znany zestaw sztucznych danych do pamięci przeglądarki. Rzeczywiste odtworzenie wymaga poprawnej kopii, odpowiedniej procedury i weryfikacji.

Źródła: MySQL UPDATE, MySQL — implicit commit, SQL Server TRUNCATE, Oracle TRUNCATE. INF.03.4: modyfikacja danych i spójność. Dalej: transakcje oraz podstawy wydajności.

Przewijanie do góry