CodeGym /Kurslar /SQL SELF /Qeyd dəyişəndə last_modified sahəsinin avto...

Qeyd dəyişəndə last_modified sahəsinin avtomatik yenilənməsi üçün trigger

SQL SELF
Səviyyə , Dərs
Mövcuddur

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_modified sahə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 üçün NOW() (indiki tarix və vaxt) dəyərini təyin edirik.
  • Funksiya yenilənmiş NEW də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 UPDATE göstərir ki, trigger yeniləmə əməliyyatından əvvəl işləyir.
  • FOR EACH ROW o 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_modified funksiyası ç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, nameage sü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

  1. 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.
  2. Həmişə trigger-in nə etdiyini və hansı hallarda istifadə olunduğunu sənədləşdir.
  3. WHEN şərtlərindən istifadə et ki, trigger-lərin təsadüfi çağırılmasını minimuma endirəsən.
  4. 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.

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION