Kończysz zapytanie, naciskasz „uruchom” i nagle tabela jest pusta albo zmieniły się wiersze, których nie planujesz ruszać. Polecenia SQL zwykle dzieli się na grupy według ich funkcji, ale ta klasyfikacja nie zawsze jest formalnym podziałem języka ani gwarancją, że każde polecenie zadziała tak samo w każdej bazie.

Najpierw ustal, czy polecenie czyta dane, zmienia je czy zmienia strukturę
- SELECT odczytuje dane, a INSERT, UPDATE i DELETE zmieniają wiersze.
- CREATE, ALTER i DROP dotyczą obiektów bazy, takich jak tabele.
- WHERE ogranicza zakres modyfikacji, ale jego brak może oznaczać zmianę lub usunięcie wszystkich wierszy.
- BEGIN, COMMIT i ROLLBACK pomagają kontrolować transakcję, choć zachowanie zależy od silnika bazy.
- LIMIT i niektóre inne elementy składni różnią się między systemami.
Pięć grup porządkuje polecenia, ale nie jest ścisłą klasyfikacją SQL
Gdy czytasz zestawienie poleceń, skróty DDL, DML, DQL, DCL i TCL pomagają szybko rozpoznać ich rolę. Traktuj je jednak jako praktyczny podział dydaktyczny, a nie uniwersalną taksonomię narzuconą przez standard SQL.
Przykładowo SELECT bywa opisywany jako DQL, czyli język zapytań, choć w części materiałów zalicza się go do szerszej grupy DML. Sama nazwa kategorii mniej pomaga niż odpowiedź na pytanie: czy polecenie czyta dane, zmienia rekordy, strukturę, uprawnienia czy stan transakcji?
Uważam, że początkującej osobie bardziej przyda się rozpoznawanie skutków komendy niż zapamiętywanie skrótów. W praktyce te skutki są widoczne już w nazwie polecenia i jego klauzulach.
SELECT, INSERT, UPDATE i DELETE obsługują codzienną pracę z rekordami
Najczęściej zaczynasz od odczytu. SELECT pobiera wskazane kolumny z tabeli, a WHERE zawęża wynik do wierszy spełniających warunek:
SELECT email, status
FROM users
WHERE status = 'active';
Gdy wstawiasz nowe dane, używasz INSERT INTO; gdy zmieniasz istniejące, UPDATE; gdy usuwasz wiersze, DELETE. W tych dwóch ostatnich poleceniach warunek wymaga szczególnej uwagi: bez WHERE aktualizacja lub usunięcie obejmie całą tabelę. Dokumentacja PostgreSQL wyraźnie pokazuje, że DELETE FROM products; usuwa wszystkie wiersze.
UPDATE users
SET status = 'inactive'
WHERE last_login < DATE '2024-01-01';
DELETE FROM sessions
WHERE expires_at < CURRENT_TIMESTAMP;
Przed wykonaniem zmiany możesz użyć warunku z polecenia modyfikującego w osobnym SELECT, by zobaczyć, które rekordy pasują. Przy odczycie większych zbiorów ograniczaj też liczbę zwracanych wierszy, ale pamiętaj, że składnia limitu różni się między bazami.
CREATE, ALTER i DROP zmieniają strukturę bazy
Dodanie kolumny nie zmienia pojedynczego rekordu, lecz samą tabelę. Polecenia z grupy DDL tworzą, modyfikują lub usuwają obiekty bazy, takie jak tabele, widoki i indeksy.| Polecenie | Skutek | Przykład |
|---|---|---|
CREATE | Tworzy obiekt | CREATE TABLE tasks (id INTEGER, title VARCHAR(200)); |
ALTER | Zmienia istniejący obiekt | ALTER TABLE tasks ADD COLUMN done BOOLEAN; |
DROP | Usuwa obiekt | DROP TABLE tasks; |
TRUNCATE | Opróżnia tabelę | TRUNCATE TABLE tasks; |
DROP TABLE usuwa tabelę jako obiekt, a TRUNCATE usuwa jej zawartość, pozostawiając samą tabelę. Nie zakładaj jednak, że TRUNCATE to po prostu szybszy DELETE: może inaczej działać z wyzwalaczami, kluczami obcymi i transakcjami.
COMMIT nie zawsze cofnie zmianę w strukturze tabeli
Transakcja grupuje operacje, które mają zostać zatwierdzone razem. BEGIN rozpoczyna blok, COMMIT zatwierdza zmiany, a ROLLBACK wycofuje niezakończoną transakcję; dokładne zachowanie zależy jednak od systemu bazy i rodzaju polecenia.
BEGIN;
UPDATE accounts
SET balance = balance - 50
WHERE account_id = 17;
UPDATE accounts
SET balance = balance + 50
WHERE account_id = 42;
COMMIT;
Tu oba przelewy są częścią jednej transakcji, więc nie powinien zostać zatwierdzony tylko jeden z nich. W PostgreSQL bez jawnego bloku każde poprawne polecenie działa domyślnie w osobnej transakcji. Inaczej trzeba myśleć o MySQL: w MySQL 8.4 wiele poleceń DDL, w tym ALTER TABLE, DROP TABLE i TRUNCATE TABLE, powoduje niejawne zatwierdzenie aktywnej transakcji. Opisuje to dokumentacja MySQL 8.4 Reference Manual.
Wniosek jest praktyczny: przed zmianą struktury nie polegaj na ROLLBACK jako uniwersalnym „cofnij”. Sprawdź zachowanie konkretnego silnika i rodzaju polecenia, zanim wykonasz je na ważnej bazie.
Klauzule i dialekt decydują o tym, co naprawdę wykona baza
Dwie komendy mogą wyglądać niemal identycznie, a mimo to różnić się składnią albo szczegółami działania. Na przykład do ograniczania liczby wierszy PostgreSQL i MySQL obsługują LIMIT, natomiast w Microsoft SQL Server spotkasz między innymi TOP lub składnię OFFSET ... FETCH. Dokumentacja polecenia SELECT w PostgreSQL zaznacza, że LIMIT i OFFSET są składnią specyficzną dla PostgreSQL, używaną również przez MySQL.
Równie ważna jest kolejność klauzul. WHERE filtruje wiersze przed grupowaniem, a HAVING pozwala filtrować wyniki grupowania. Jeśli zapytanie zawiera ORDER BY i ograniczenie wyników, sortowanie powinno poprzedzać limit, by wynik nie zależał od przypadkowej kolejności zwróconych rekordów.
| Sytuacja | Możliwy skutek | Co zrobić |
|---|---|---|
UPDATE lub DELETE bez WHERE | Zmiana albo usunięcie wszystkich wierszy tabeli | Uruchom najpierw SELECT z planowanym warunkiem |
LIMIT odrzucony przez bazę | Składnia nie pasuje do dialektu | Sprawdź dokumentację używanego systemu i zastosuj jego składnię limitowania |
ROLLBACK po poleceniu DDL w MySQL | Zmiana mogła już zatwierdzić wcześniejszą transakcję | Zweryfikuj zasady niejawnego zatwierdzania przed wykonaniem DDL |
Wynik z LIMIT bez stabilnego sortowania | Przy kolejnych wykonaniach mogą pojawić się inne wiersze | Dodaj ORDER BY po kolumnie zapewniającej przewidywalną kolejność |
Jeśli przenosisz zapytanie między bazami, zacznij od sprawdzenia składni limitowania, obsługi transakcji i poleceń DDL. To te różnice najłatwiej przeoczyć w kodzie, który na pierwszy rzut oka wygląda przenośnie.
Bezpieczny nawyk zaczyna się przed uruchomieniem komendy
Przed zmianą danych przeczytaj polecenie od końca: czy warunek wskazuje właściwe rekordy, czy tabela jest poprawna i czy sesja działa w oczekiwanym trybie transakcji. Przy niepewnym UPDATE lub DELETE najpierw uruchom odpowiadający mu SELECT, a przy większej zmianie sprawdź możliwość odtworzenia danych z kopii.
Najpierw rozpoznaj skutek, potem wykonuj. Gdy wiesz, czy komenda odczytuje rekordy, modyfikuje je, zmienia strukturę czy steruje transakcją, łatwiej przewidzieć zarówno wynik zapytania, jak i moment, w którym zmiany staną się trwałe.
