Təsəvvür elə ki, səndə mürəkkəb hesablamalar və ya məlumatların işlənməsi üçün funksiya var. Əgər funksiyanı SQL-sorğulara inteqrasiya etmək imkanı olmasaydı, belə işləyərdin:
- Funksiyanı hansısa proqramlaşdırma dilindən (məsələn, Python və ya JavaScript) çağırırsan.
- Nəticəni SQL-sorğusuna ötürürsən.
Bu artıq addımdır! PostgreSQL-də funksiyaları birbaşa SQL-sorğunun içində istifadə etmək olar, kodun həcmini azaldır, əməliyyatları sürətləndirir və serverə müraciətlərin sayını azaldır. Bu xüsusilə aşağıdakılar üçün faydalıdır:
- Hesablamaların avtomatlaşdırılması.
- Məlumatların əlavə olunmazdan əvvəl yoxlanılması.
- Mövcud məlumatların dəyişdirilməsi.
SELECT-də funksiyaların çağırılması
Əsaslardan başlayaq və funksiyaları adi SELECT sorğusunda necə istifadə etmək olar baxaq. Deyək ki, səndə students adlı cədvəl var və orada tələbələr haqqında məlumat saxlanılır. Biz elə funksiya yazmaq istəyirik ki, tələbənin doğum tarixindən onun indiki yaşını qaytarsın.
Addım 1: funksiyanın yazılması
calculate_age funksiyasını yaradaq, hansı ki, doğum tarixini qəbul edir və yaşı qaytarır:
CREATE OR REPLACE FUNCTION calculate_age(birth_date DATE) RETURNS INT AS $$
BEGIN
RETURN DATE_PART('year', AGE(NOW(), birth_date))::INT;
END;
$$ LANGUAGE plpgsql;
Addım 2: funksiyanı SELECT-də istifadə etmək
İndi bu funksiyanı cədvəldəki hər bir sətrə tətbiq edə bilərik:
SELECT id, name, calculate_age(birth_date) AS age FROM students;
Nə baş verir?
studentscədvəlindəki hər bir sətr üçüncalculate_agefunksiyası yaş hesablayır.- Qaytarılan dəyər
agesütununda göstərilir.
Nümunə nəticə:
| id | name | age |
|---|---|---|
| 1 | Otto | 21 |
| 2 | Anna | 25 |
| 3 | Aleks | 22 |
Gördüyün kimi, heç bir çətinlik yoxdur, nəticə isə həm səliqəli, həm də peşəkar görünür.
INSERT-də funksiyaların çağırılması
Funksiyalar məlumat əlavə edəndə də çox faydalıdır. Məsələn, deyək ki, səndə logs adlı cədvəl var və orada istifadəçi hərəkətləri qeyd olunur. Biz istəyirik ki, log-mesajı əlavə edəndə, mətn avtomatik generasiya olunsun və bunu funksiya etsin.
Addım 1: funksiyanın yaradılması
generate_log_message funksiyasını yazırıq, hansı ki, istifadəçi adını və hərəkəti qəbul edir və mesaj mətnini qaytarır:
CREATE OR REPLACE FUNCTION generate_log_message(username TEXT, action TEXT) RETURNS TEXT AS $$
BEGIN
RETURN username || ' performed action: ' || action || ' at ' || NOW();
END;
$$ LANGUAGE plpgsql;
Addım 2: funksiyanı INSERT-də istifadə etmək
İndi logs cədvəlinə sətir əlavə edəndə funksiyanı çağırırıq:
INSERT INTO logs (message)
VALUES (generate_log_message('Otto', 'sayta daxil oldu'));
Nəticə:
| id | message |
|---|---|
| 1 | Otto performed action: sayta daxil oldu at 2023-10-26 12:00:00 |
Funksiya hər şeyi özü edir: mətnin formatlanmasına və zaman nişanının əlavə olunmasına baxır. Bu, funksiyaların gündəlik işləri necə avtomatlaşdıra biləcəyinə əla nümunədir.
UPDATE-də funksiyaların çağırılması
Funksiyalardan cədvəldəki məlumatları dəyişmək üçün də istifadə etmək olar. Deyək ki, səndə students cədvəli var və biz tələbələrin qrup adını yeni kursa keçid üçün dəyişmək istəyirik, bunu da funksiya ilə edəcəyik.
Addım 1: funksiyanın yaradılması
promote_student funksiyasını yazırıq, hansı ki, köhnə qrupu (məsələn, 101) qəbul edir və yenisini qaytarır (məsələn, 201):
CREATE OR REPLACE FUNCTION promote_student(old_group TEXT) RETURNS TEXT AS $$
BEGIN
RETURN '2' || RIGHT(old_group, LENGTH(old_group) - 1);
END;
$$ LANGUAGE plpgsql;
Addım 2: funksiyanı UPDATE-də istifadə etmək
Bütün tələbələrin qrupunu yeniləyirik:
UPDATE students
SET group_name = promote_student(group_name);
Nəticə:
| id | name | group_name |
|---|---|---|
| 1 | Otto | 201 |
| 2 | Anna | 202 |
| 3 | Aleks | 203 |
Bax, çağırılan funksiya necə yeniləmə magiyasını edir: köhnə qruplar yeni sətrlərə çevrilir.
WHERE şərtlərində funksiyaların çağırılması
Funksiyalardan filtrasiya şərtlərində də istifadə etmək olar. Gəlin tələbələrin yaşı ilə bağlı nümunəni genişləndirək.
Addım 1: yaşa görə filtrasiya
Artıq yaratdığımız calculate_age funksiyasını istifadə edirik ki, 20 yaşdan yuxarı tələbələri seçək:
SELECT id, name, birth_date
FROM students
WHERE calculate_age(birth_date) > 20;
Nəticə:
| id | name | birth_date |
|---|---|---|
| 2 | Anna | 1998-05-15 |
| 3 | Aleks | 1999-11-09 |
Burada əsas yük funksiyanın üzərinə düşür, hansı ki, hər tələbə üçün yaşı yerindəcə hesablayır.
Aggregat funksiyalarla birlikdə istifadə
Gəlin tapşırığı bir az çətinləşdirək. Bizə 22 yaşdan kiçik tələbələrin ümumi sayını hesablamaq lazımdır. Funksiyalar aggregat funksiyalarla, məsələn, COUNT() ilə əla işləyir.
SELECT COUNT(*)
FROM students
WHERE calculate_age(birth_date) < 22;
Nə baş verir?
calculate_agefunksiyası filtrasiya üçün istifadə olunur.COUNT(*)şərtə uyğun sətrlərin sayını hesablayır.
Real istifadə nümunələri
Məlumatların yoxlanmasının avtomatlaşdırılması. Tutaq ki, istəyirsən yoxlayasan ki, cədvəldəki bütün tələbələrin yaşı tipik aralıqdadır (məsələn, 18-dən 30-a qədər). Bunun üçün funksiya yaz və WHERE şərtində istifadə et.
SELECT id, name
FROM students
WHERE NOT (calculate_age(birth_date) BETWEEN 18 AND 30);
Məlumat əlavə etmənin optimallaşdırılması. Təsəvvür elə ki, sən onlayn mağazada işləyirsən. Sifarişin ümumi qiymətini client tərəfdə hesablamaq əvəzinə, funksiya yaz ki, onu birbaşa orders cədvəlinə əlavə edəndə hesablasın.
INSERT INTO orders (user_id, total_price)
VALUES (1, calculate_total_price(ARRAY[5, 10, 15]));
Funksiyaların çağırılmasında tipik səhvlər
Funksiyaları sorğularda aktiv istifadə etməyə başlayanda, bəzi səhvlərlə rastlaşa bilərsən. Budur, ən çox rast gəlinən hallar və onların həlli:
Tələb olunan hüquqların olmaması. Əgər sən funksiyanın və ya cədvəlin sahibi deyilsənsə, PostgreSQL çağırmanı qadağan edə bilər. Əmin ol ki, funksiyanı icra etmək üçün hüquqların var.
Tip uyğunsuzluğu. Funksiyaya arqument ötürəndə, məlumat tiplərinə diqqət et. Məsələn, funksiya DATE gözləyir, amma sən string ötürürsən, onda səhv alacaqsan. Açıq tip çevirmədən istifadə et:
SELECT calculate_age('2000-01-01'::DATE);
Funksiya daxilində sintaksis səhvləri. Əgər funksiya səhv qaytarırsa, bu bütün sorğunun dayanmasına səbəb ola bilər. Funksiyaları istifadə etməzdən əvvəl yaxşıca test et.
GO TO FULL VERSION