Różnice między funkcjami a procedurami
W wielu językach programowania między funkcjami a procedurami prawie nie ma różnicy. W SQL już tak. W PostgreSQL funkcje i procedury to nie tylko dwa różne sposoby uruchamiania kodu. To dwie różne filozofie myślenia.
Funkcja w SQL nie może zmieniać danych w bazie. Powinna działać tylko na przekazanych danych i zwracać wynik na ich podstawie. Tworzy się ją po to, żeby używać wewnątrz zapytań SELECT.
Procedura w SQL została stworzona do zmiany bazy. Dlatego może pracować z transakcjami (w przeciwieństwie do funkcji), zapisywać coś do bazy. I nie może być używana wewnątrz zapytań SELECT.
Oto krótkie porównanie:
| Charakterystyka | Funkcja (FUNCTION) | Procedura (PROCEDURE) |
|---|---|---|
| Zwraca dane | ✅ Tak (RETURNS ...) |
❌ Nie (może tylko wykonywać akcje) |
| Wywoływana przez | SELECT, PERFORM |
CALL |
| Można w zapytaniach | ✅ Tak | ❌ Nie |
Może być w DO |
✅ Tak | ❌ Nie |
Obsługuje COMMIT, ROLLBACK |
❌ Nie | ✅ Tak |
| Obecne w PostgreSQL | Od początku | Od wersji 11 |
Różnice w SQL
W zwykłym SQL funkcja przypomina wyrażenie: oblicza i zwraca wartość. Procedura to instrukcja: robi coś, ale nie bierze udziału w wyrażeniach.
Funkcja w SQL
SELECT calculate_discount(200);
- Może być używana w
WHERE,ORDER BY,INSERT,UPDATEitd. - Musi być czysta: nie powinna zmieniać stanu bazy (jeśli IMMUTABLE/STABLE).
Procedura w SQL
CALL process_order(123);
- Nie zwraca wyniku.
- Może robić
COMMIT,ROLLBACK, wywoływaćRAISE, uruchamiać pętle.
Różnice w PL/pgSQL
Funkcje w PostgreSQL można traktować jako grupę obliczeń. Są bardzo elastyczne: można przekazywać parametry, używać instrukcji warunkowych, pętli, kursory, podzapytania, zwracać wiersze, skalary, tabele.
Funkcje w PL/pgSQL
CREATE FUNCTION square(x INT) RETURNS INT AS $$
BEGIN
RETURN x * x;
END;
$$ LANGUAGE plpgsql;
Cechy:
- Wymagane
RETURNS - Może używać
DECLARE,BEGIN,END,LOOP,IF,CASE - Nie można wykonywać
COMMIT/ROLLBACK - Można wywoływać w
SELECT,UPDATE,CHECK,WHERE,RETURNING
Wywołanie:
SELECT square(5); -- zwróci 25
Procedury w PL/pgSQL
Procedury to mechanizm zarządzania akcjami. Są idealne, gdy trzeba:
- wykonać wiele kroków z logiką;
- aktualizować i wstawiać duże ilości danych;
- używać zarządzania transakcjami:
COMMIT,ROLLBACK,SAVEPOINT.
CREATE PROCEDURE log_event(msg TEXT) AS $$
BEGIN
INSERT INTO logs(message) VALUES (msg);
COMMIT;
END;
$$ LANGUAGE plpgsql;
Cechy:
- Brak
RETURNS - Wywoływana tylko przez
CALL - Można używać
COMMIT,ROLLBACK,SAVEPOINT - Idealna do przetwarzania wsadowego, migracji, ETL
Wywołanie:
CALL log_event('Przetwarzanie zakończone');
Dlaczego funkcje i procedury są rozdzielone
Bo mają różne cele w SQL:
| Funkcje | Procedury |
|---|---|
| "Coś obliczyć i zwrócić" | "Coś zrobić i nie zwracać wyniku" |
| Wywołanie z SQL | Wywołanie jako komenda |
| Nie mogą zarządzać transakcjami | Mogą zarządzać transakcjami |
Używane w SELECT, JOIN, WHERE |
Używane w CALL, skryptach |
Kluczowa zaleta procedury — COMMIT
Procedury mogą zarządzać transakcjami wewnątrz siebie. Czyli bezpośrednio w procedurze można robić:
BEGIN;
-- logika
SAVEPOINT point1;
-- próba aktualizacji
ROLLBACK TO point1;
COMMIT;
A w funkcji COMMIT i ROLLBACK są zabronione. Jeśli spróbujesz — dostaniesz: ERROR: invalid transaction termination in function
To oznacza, że funkcja musi być deterministyczna i bezpieczna, a procedura może robić "brudną robotę" — czyścić, logować, wstawiać.
Tabela porównawcza
| Cechy | FUNCTION |
PROCEDURE |
|---|---|---|
| Zwraca wartość | ✅ RETURNS |
❌ |
Używana w SELECT |
✅ | ❌ |
| Wywołanie | SELECT, PERFORM, DO |
Tylko CALL |
| Może być w triggerze | ✅ | ❌ (tylko funkcje) |
Transakcje wewnątrz (COMMIT) |
❌ Zabronione | ✅ Dozwolone |
| Użycie OUT-parametrów | Przez RETURNS TABLE, RECORD |
Przez OUT-parametry bezpośrednio |
| Do obliczeń | ✅ | 🚫 nie przeznaczona |
| Do ETL, ładowania | 🚫 ograniczone | ✅ idealna |
| Można używać kursory | ✅ Tak | ✅ Tak |
Kiedy czego używać?
Użyj funkcji, jeśli:
- chcesz zwracaną wartość;
- wywołujesz w
SELECT, filtrujesz dane; - to prosty rachunek, sprawdzenie lub wrapper dla SQL.
Użyj procedury, jeśli:
- chcesz wykonać złożone akcje;
- potrzebujesz kontroli transakcji;
- przetwarzasz batch'e, przenosisz dane, archiwizujesz, logujesz.
GO TO FULL VERSION