PostgreSQL-də funksiyalar — kodun avtomatlaşdırılması, biznes-məntiqin yaradılması və serverə daha çox ağıllılıq vermək üçün güclü bir alətdir. Funksiyaları elə bil ki, bazanın içində işləyən mini-proqramlar kimi təsəvvür et. Onlar aşağıdakılar üçün rahatdır:
- Kodun təkrar istifadəsi. Əgər eyni sorğunu bir neçə dəfə yazırsansa, onu funksiyaya bük və lazım olanda çağır.
- Tapşırıqların avtomatlaşdırılması. Məsələn, işçilərin maaşını onların iş saatlarına görə hesablamaq lazımdırsa, funksiya bunu rahatlıqla edəcək.
- Məntiqin inkapsulyasiyası. Çətin hesablamaları server tərəfində saxlamağa imkan verir ki, client-lər SQL sorğuları ilə baş sındırmasın.
Ümumi CREATE FUNCTION sintaksisi
Funksiya yaratmaq üçün ümumi struktur belədir:
CREATE FUNCTION function_name(parameters) RETURNS return_type AS $$
BEGIN
-- Funksiyanın gövdəsi (məntiq)
RETURN nəticə;
END;
$$ LANGUAGE plpgsql;
Əsas hissələrə baxaq:
CREATE FUNCTION function_name(parameters):
Bu sətrdə biz funksiyanın adını function_name və parametrləri (əgər lazımdırsa) göstəririk.
Parametrlər ad və data tipini ehtiva edə bilər: my_param INTEGER, another_param TEXT.
RETURNS return_type:
Funksiyamızın nə qaytaracağını göstəririk: bir dəyər (INTEGER, TEXT və s.) və ya data seti (TABLE, RECORD).
BEGIN ... END:
Bu açar sözlərin içində funksiyanın "gövdəsi" yerləşir, bütün sehr burada baş verir.
RETURN nəticə:
Funksiyanın icrasının nəticəsini qaytarır. Diqqətli ol: nəticənin tipi RETURNS-də göstərdiyin tipə uyğun olmalıdır.
LANGUAGE plpgsql:
PL/pgSQL dilindən istifadə etdiyimizi göstəririk. PostgreSQL başqa dilləri də dəstəkləyir, amma indi bizə bu lazımdır.
Sadə nümunə: iki ədədin toplanması
Gəlin iki tam ədədin cəmini qaytaran funksiya yaradaq.
CREATE FUNCTION add_numbers(a INT, b INT) RETURNS INT AS $$
BEGIN
RETURN a + b;
END;
$$ LANGUAGE plpgsql;
İndi onu çağıraq:
SELECT add_numbers(5, 7); -- Nəticə: 12
Burada nə baş verir?
- Funksiya iki parametr qəbul edir:
avəbtipiINT. - Funksiyanın içində sadəcə onları toplayırıq (
a + b) və nəticəni qaytarırıq. - Hər şey kalkulyator kimi sadədir!
Dəyişənlərdən istifadə ilə nümunə
Təsəvvür et ki, universitet bazamız var və neçə tələbənin qeydiyyatdan keçdiyini bilmək istəyirik.
Funksiya yaradaq:
CREATE FUNCTION count_students() RETURNS INT AS $$
DECLARE
total INT; -- Nəticəni saxlamaq üçün dəyişən elan edirik
BEGIN
SELECT COUNT(*) INTO total FROM students; -- Cədvəldəki sətrlərin sayını hesablayırıq
RETURN total; -- Nəticəni qaytarırıq
END;
$$ LANGUAGE plpgsql;
Funksiyanı çağırmaq:
SELECT count_students(); -- Tutaq ki, nəticə: 120
Burada görürük:
- SQL sorğusunun nəticəsini saxlamaq üçün
totaldəyişənindən istifadə. SELECT ... INTOkomandası sorğunun nəticəsini dəyişənə yazır.
Bu yanaşma xüsusilə rahatdır, əgər əvvəlcə datanı emal edib sonra qaytarmaq lazımdırsa.
Bir neçə dəyərin qaytarılması: RETURNS TABLE
Əvvəlki nümunədə biz yalnız bir dəyər qaytardıq. Amma bəs funksiya data seti, məsələn, tələbələrin siyahısını qaytarmalıdırsa? Məhz burada RETURNS TABLE faydalı olur.
Nümunə:
CREATE FUNCTION get_students() RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
RETURN QUERY SELECT id, name FROM students;
END;
$$ LANGUAGE plpgsql;
Funksiyanı çağırmaq:
SELECT * FROM get_students();
Mümkün nəticə:
| id | name |
|---|---|
| 1 | Alice |
| 2 | Bob |
| 3 | Charlie |
Funksiya içində sorğular üçün RETURN QUERY-nin faydası
RETURN QUERY bizə SQL sorğusunun nəticəsini birbaşa funksiyadan qaytarmağa imkan verir. Bu, aralıq addımları azaldır və funksiyaları sadələşdirir.
Yalnız aktiv olan tələbələri qaytaran funksiya yaradaq:
CREATE FUNCTION get_active_students() RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
RETURN QUERY SELECT id, name FROM students WHERE active = TRUE;
END;
$$ LANGUAGE plpgsql;
get_active_students() funksiyasını çağırmazdan əvvəl students cədvəlini yaratmaq və test dataları ilə doldurmaq lazımdır. Bunu belə edə bilərsən:
-- Tələbələr cədvəlini yaradırıq
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
active BOOLEAN DEFAULT TRUE
);
-- Bir neçə qeyd əlavə edirik
INSERT INTO students (name, active) VALUES
('Alice', FALSE),
('Bob', TRUE),
('Charlie', TRUE),
('Dana', FALSE);
Cədvəl:
| id | name | active |
|---|---|---|
| 1 | Alice | false |
| 2 | Bob | true |
| 3 | Charlie | true |
| 4 | Dana | false |
İndi çağırış:
SELECT * FROM get_active_students();
Nəticə:
| id | name |
|---|---|
| 2 | Bob |
| 3 | Charlie |
İcra etməzdən əvvəl datanın düzgünlüyünü yoxlamaq
Funksiyalarda IF yoxlamaları ola bilər ki, datanın düzgünlüyünə əmin olasan. Məsələn, tələbəni növbəti kursa keçirmək üçün o, bütün imtahanları verməlidir.
Nümunə:
CREATE FUNCTION promote_student(student_id INT) RETURNS TEXT AS $$
DECLARE
passed_exams INT;
BEGIN
-- Tələbənin verdiyi imtahanların sayını hesablayırıq
SELECT COUNT(*) INTO passed_exams
FROM exams
WHERE student_id = promote_student.student_id AND status = 'keçib';
-- Şərti yoxlayırıq
IF passed_exams < 5 THEN
RETURN 'Tələbə kifayət qədər imtahan verməyib';
END IF;
-- Tələbənin kursunu artırırıq
UPDATE students
SET course = course + 1
WHERE id = promote_student.student_id;
RETURN 'Tələbə kursa keçirildi!';
END;
$$ LANGUAGE plpgsql;
Funksiya yaradarkən tipik səhvlər
Nəticə tipinin olmaması. PostgreSQL həmişə tələb edir ki, funksiyanın hansı nəticəni qaytaracağını göstərəsən. Məsələn:
CREATE FUNCTION fail() AS $$ -- Səhv: RETURNS yoxdur
BEGIN
RETURN 1;
END;
$$ LANGUAGE plpgsql;
Düzəliş:
CREATE FUNCTION succeed() RETURNS INT AS $$
BEGIN
RETURN 1;
END;
$$ LANGUAGE plpgsql;
Nəticə tipinin uyğun olmaması. Əgər RETURNS INT göstərmisənsə, mütləq rəqəm qaytarmalısan. Bu halda sətir qaytarmaq — pis fikirdir.
Funksiya içində SQL sorğularında səhv. Sorğuları funksiyalarda istifadə etməzdən əvvəl həmişə yoxla. Ən yaxşısı onları "əllə" psql və ya pgAdmin-də test elə.
GO TO FULL VERSION