Təsəvvür elə ki, sən tələbələr və kurslar üçün idarəetmə app yazırsan və səndə students adlı cədvəl var. Bu cədvəldə last_modified adlı bir sahə var və bu sahə hər dəfə qeyd dəyişəndə (məsələn, tələbənin adını və ya yaşını dəyişəndə) avtomatik yenilənməlidir.
Hər dəfə SQL sorğusunda last_modified sahəsini əl ilə yeniləmək əvəzinə, biz trigger yaradacağıq ki, bunu bizim yerimizə etsin.
students cədvəlinin strukturu
Əvvəlcə gəlin students cədvəlini yaradaq, bu nümunədə istifadə olunacaq. Bu cədvəldə tələbələr haqqında əsas məlumatlar saxlanılır:
CREATE TABLE students (
student_id SERIAL PRIMARY KEY, -- Tələbənin unikal identifikatoru
name VARCHAR(100) NOT NULL, -- Tələbənin adı
age INT, -- Tələbənin yaşı
last_modified TIMESTAMP NOT NULL DEFAULT NOW() -- Son dəyişiklik vaxtı
);
last_modifiedsahəsi qeyd yaradılarkən avtomatik olaraq indiki vaxtla (NOW()) doldurulur.- Bu sahə tələbə məlumatı dəyişəndə avtomatik yenilənəcək.
Cədvəli bir neçə test dataları ilə dolduraq:
INSERT INTO students (name, age)
VALUES
('Otto Lin', 20),
('Mariya Chi', 22),
('Aleks Song', 19);
İndi cədvəldəki məlumatlar belə görünür:
| student_id | name | age | last_modified |
|---|---|---|---|
| 1 | Otto Lin | 20 | 2023-10-15 12:00:00 |
| 2 | Mariya Chi | 22 | 2023-10-15 12:00:00 |
| 3 | Aleks Song | 19 | 2023-10-15 12:00:00 |
last_modified sahəsini yeniləmək üçün funksiya yaradılması
PL/pgSQL-də funksiya trigger tərəfindən last_modified sahəsinin dəyərini yeniləmək üçün istifadə olunacaq. O, qeyd dəyişməzdən əvvəl avtomatik çağırılacaq.
update_last_modified funksiyasını yaradaq:
CREATE OR REPLACE FUNCTION update_last_modified()
RETURNS TRIGGER AS $$
BEGIN
-- last_modified sahəsini indiki vaxta yeniləyirik
NEW.last_modified := NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
NEW— bu xüsusi dəyişəndir, qeyd dəyişəndən sonra yeni məlumatları saxlayır.- Biz
NEW.last_modifiedüçünNOW()(indiki tarix və vaxt) dəyərini təyin edirik. - Funksiya yenilənmiş
NEWdəyişənini qaytarır, bu trigger-in düzgün işləməsi üçün lazımdır.
Trigger yaradılması
İndi trigger yaradacağıq ki, students cədvəlində hər dəfə qeyd yenilənəndə update_last_modified funksiyasını avtomatik çağırsın.
CREATE TRIGGER set_last_modified
BEFORE UPDATE ON students
FOR EACH ROW
EXECUTE FUNCTION update_last_modified();
Burada nə baş verir:
BEFORE UPDATEgöstərir ki, trigger yeniləmə əməliyyatından əvvəl işləyir.FOR EACH ROWo deməkdir ki, trigger hər dəyişən sətr üçün işləyir.EXECUTE FUNCTION update_last_modified()göstərir ki,update_last_modifiedfunksiyası çağırılmalıdır.
Trigger-in test edilməsi
İndi gəlin trigger-in necə işlədiyini yoxlayaq. students cədvəlindən cari məlumatları seçirik:
SELECT * FROM students;
Nəticə:
| student_id | name | age | last_modified |
|---|---|---|---|
| 1 | Otto Lin | 20 | 2023-10-15 12:00:00 |
| 2 | Mariya Chi | 22 | 2023-10-15 12:00:00 |
| 3 | Aleks Song | 19 | 2023-10-15 12:00:00 |
İndi student_id = 1 olan tələbənin yaşını yeniləyirik:
UPDATE students
SET age = 21
WHERE student_id = 1;
Yenidən cədvəldən məlumatları seçirik:
SELECT * FROM students;
Gözlənilən nəticə:
| student_id | name | age | last_modified |
|---|---|---|---|
| 1 | Otto Lin | 21 | 2023-10-15 14:00:00 |
| 2 | Mariya Chi | 22 | 2023-10-15 12:00:00 |
| 3 | Aleks Song | 19 | 2023-10-15 12:00:00 |
Diqqət et: student_id = 1 olan qeyd üçün last_modified sahəsi indiki vaxta yeniləndi, digər qeydlər isə dəyişməz qaldı.
Trigger-in məntiqinin genişləndirilməsi
Tutaq ki, indi istəyirik ki, last_modified sahəsi yalnız müəyyən sütunlar dəyişəndə yenilənsin. Məsələn, yalnız tələbənin adı və ya yaşı dəyişəndə trigger işləsin, başqa dəyişikliklərdə yox.
Bunun üçün trigger təyinində WHEN operatoru ilə şərt əlavə etmək olar.
Şərtli yeni trigger yaradaq:
DROP TRIGGER IF EXISTS set_last_modified ON students;
CREATE TRIGGER set_last_modified
BEFORE UPDATE ON students
FOR EACH ROW
WHEN (OLD.name IS DISTINCT FROM NEW.name OR OLD.age IS DISTINCT FROM NEW.age)
EXECUTE FUNCTION update_last_modified();
Burada:
WHENşərti yoxlayır ki,namevəagesütunları üçün köhnə (OLD) və yeni (NEW) dəyərlər fərqlidirmi.- Əgər bu sütunlardan heç biri dəyişməyibsə, trigger işləmir.
Yenidən cədvəldə məlumatları yeniləyib yeni məntiqi test edək.
Trigger-lərin istifadəsi üçün tövsiyələr
- Trigger-lərdən həddindən artıq istifadə etmə. Onlar rahatdır, amma database məntiqini çətinləşdirə və debug-u daha çətin edə bilər.
- Həmişə trigger-in nə etdiyini və hansı hallarda istifadə olunduğunu sənədləşdir.
WHENşərtlərindən istifadə et ki, trigger-lərin təsadüfi çağırılmasını minimuma endirəsən.- Unutma ki, trigger-lər database performansına təsir edə bilər, xüsusilə cədvəldə çoxlu qeyd varsa.
Trigger-lərlə işləyərkən tipik səhvlər
Məlumatların səhv dəyişdirilməsi. Məsələn, NEW üçün dəyər təyin etməyi unutmusan və dəyişikliksiz orijinal məlumatı qaytarmısan.
Səhv şərtlər. Məsələn, WHEN şərtini əlavə etməyi unutmusan və trigger hətta heç nə dəyişməyəndə də işləyir.
Rekursiya. Əgər trigger elə bir funksiya çağırırsa ki, o yenidən trigger-i çağırır, təsadüfən sonsuz dövrə düşə bilərsən. PostgreSQL rekursiyadan qoruma verir, amma belə hallardan uzaq durmaq yaxşıdır.
Bu nümunə göstərir ki, trigger-lərdən istifadə avtomatik məlumat yenilənməsi işlərini necə asanlaşdıra bilər. Real layihələrdə bu texnika tez-tez dəyişikliklərin log-lanması, məlumat bütövlüyünün qorunması və rutin işlərin avtomatlaşdırılması üçün istifadə olunur.
GO TO FULL VERSION