CodeGym /Kurslar /SQL SELF /PL/pgSQL Sintaksisinin Əsasları

PL/pgSQL Sintaksisinin Əsasları

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

Gəlin PL/pgSQL-i bir az daha dərindən öyrənək və onu daha aktiv istifadə etməyə başlayaq.

Kod bloku

PL/pgSQL-də kod bloku — dilin əsas tikinti elementidir. Belə deyə bilərik ki, bu, bizim funksiyalarımızın, prosedurlarımızın və başqa magiyanın dayandığı karkasdır. Blok bizə məntiqin icrasını, məlumatların işlənməsini, səhvlərin idarə olunmasını və bütün bunları bir "konteynerdə" təmin edir.

PL/pgSQL blokları strukturlaşdırılıb və üç əsas hissədən ibarətdir:

  1. DECLARE: dəyişənlərin elan olunması (istəyə bağlıdır).
  2. BEGIN ... END: əsas icra bloku, burada məntiq işləyir.
  3. EXCEPTION: səhvlərin işlənməsi (istəyə bağlıdır).

Analogiya sevənlər üçün: təsəvvür elə bir yemək resepti yazırsan. Reseptin mətni bəlkə də inqrediyent siyahısı ilə başlayır, amma əsas magiya bişirmə prosesində baş verir. PL/pgSQL terminlərində:

  • DECLARE — inqrediyentlərin siyahısıdır (dəyişənlər).
  • BEGIN ... END — burada qarışdırılır, qızardılır və bişirilir.
  • EXCEPTION — nəsə yanarsa, nə etmək lazımdır planıdır.

PL/pgSQL blokunun sintaksisi

Əvvəlcə blokun ümumi strukturuna baxaq, yəni "skeletinə". Sonra ora ət (ya da vegetarian pendiri, əgər üstünlük verirsənsə) — konkret məntiq əlavə edəcəyik.

DO $$
DECLARE
    -- Burada dəyişənlər elan olunur
    student_count INT;
BEGIN
    -- Burada məntiq icra olunur
    SELECT COUNT(*) INTO student_count FROM students;
    RAISE NOTICE 'Tələbələrin ümumi sayı: %', student_count;
EXCEPTION
    -- Burada səhvlər işlənir
    WHEN OTHERS THEN
        RAISE NOTICE 'Səhv baş verdi.';
END;
$$;

Gəlin bunu addım-addım analiz edək.

  1. DECLARE — burada dəyişənlərimizi elan edirik. Ən gözəl tərəfi odur ki, PL/pgSQL PostgreSQL-də olan demək olar ki, bütün data tiplərini dəstəkləyir — sadə INTEGER-dən tutmuş ekzotik JSONB-yə qədər. Dəyişəni elan etmək üçün onun adını, data tipini və lazım olsa ilkin dəyərini göstərirsən.

Nümunə:

DECLARE
    student_name TEXT;    -- Tələbənin adı üçün dəyişən
    course_count INT := 0; -- İlkin dəyəri 0 qoyuruq
    is_graduated BOOLEAN; -- Məntiqi dəyişən

Diqqət elə, dəyişənlər həm ilkin dəyərlə (məsələn, course_count), həm də onsuz ola bilər.

  1. BEGIN ... END — əsas icra bloku.

Blokun bu hissəsi əsas məntiqin icrasına cavabdehdir. Burada sən:

  • SQL sorğuları icra edə bilərsən (SELECT, INSERT və s.).
  • Məlumatlarla işləyə bilərsən.
  • İdarəetmə konstruksiyalarından istifadə edə bilərsən (IF, LOOP və s.).
  • RAISE ilə debug mesajları çıxara bilərsən.

Nümunə:

BEGIN
    SELECT COUNT(*) INTO student_count FROM students;
    IF student_count > 0 THEN
        RAISE NOTICE 'Bizdə tələbələr var!';
    ELSE
        RAISE NOTICE 'Tələbə tapılmadı.';
    END IF;
END;
  1. EXCEPTION — səhvlərin işlənməsi (istəyə bağlıdır).

Əgər blokun icrası zamanı səhv baş verərsə, EXCEPTION hissəsi onu tutmağa və nəsə faydalı bir şey etməyə imkan verir — məsələn, mesaj çıxarmaq və ya alternativ kod işlətmək.

Nümunə:

BEGIN
    SELECT COUNT(*) INTO student_count FROM non_existing_table; -- Səhv!
EXCEPTION
    WHEN OTHERS THEN
        RAISE NOTICE 'Ups, nəsə düz getmədi!';
END;

Real nümunə: tələbələrin sayının hesablanması

İndi bütün hissələri birləşdirib real həyatda lazım ola biləcək bir nümunə yazaq. PL/pgSQL bloku yazacağıq ki, students cədvəlində tələbələrin sayını hesablayıb mesaj çıxarsın.

DO $$
DECLARE
    total_students INT; -- Tələbələrin sayını saxlamaq üçün dəyişən
BEGIN
    -- Tələbələrin sayını hesablayırıq
    SELECT COUNT(*) INTO total_students FROM students;

    -- Nəticə ilə mesaj çıxarırıq
    RAISE NOTICE 'Tələbələrin sayı: %', total_students;
EXCEPTION
    -- Mümkün səhvləri işləyirik, məsələn, cədvəl yoxdursa
    WHEN OTHERS THEN
        RAISE NOTICE 'Tələbələrin sayını hesablarkən səhv baş verdi.';
END;
$$;

Bu bloku çağıranda konsolda mesaj çıxacaq. Məsələn: Tələbələrin sayı: 42.

Dəyişənlərdən istifadə xüsusiyyətləri

Gəlin bir neçə vacib məqamı aydınlaşdıraq:

Dəyişənlərə dəyər mənimsətmək. Dəyişənə məlumat yazmaq üçün SELECT INTO operatorundan istifadə edə bilərsən:

SELECT COUNT(*) INTO total_students FROM students;

Dəyişənlərin ilkinləşdirilməsi. Əgər dəyişən elan olunanda ona dəyər verməmisənsə, onun dəyəri avtomatik olaraq NULL olacaq.

Məsələn:

DECLARE
    my_var INT; -- Dəyəri NULL-dur

RECORD tipli dəyişənlər. Bu universal dəyişən tipidir, ora cədvəldən sətir yaza bilərsən. Nümunə:

DECLARE
    student RECORD;
BEGIN
    SELECT * INTO student FROM students WHERE id = 1;
    RAISE NOTICE 'Tələbənin adı: %, Yaşı: %', student.name, student.age;
END;

Nümunə: tələbə üçün kursların sayının hesablanması

İndi praktik bir məsələni həll edək: tələbənin neçə kursa yazıldığını hesablayıb nəticəni çıxaraq.

DO $$
DECLARE
    student_id INT := 1;   -- Tələbənin ID-si
    course_count INT;      -- Kursların sayı üçün dəyişən
BEGIN
    -- Kursların sayını hesablayırıq
    SELECT COUNT(*) INTO course_count
    FROM enrollments
    WHERE student_id = student_id;

    -- Mesaj çıxarırıq
    RAISE NOTICE 'Tələbə ID % % kursa yazılıb.', student_id, course_count;
EXCEPTION
    WHEN OTHERS THEN
        RAISE NOTICE 'Tələbə ID % işlənərkən səhv baş verdi', student_id;
END;
$$;

Bu blok çevik işləyir: student_id-ni dəyişib müxtəlif tələbələr üçün neçə kurs olduğunu yoxlaya bilərsən.

Səhvlər və onların qarşısının alınması

Əgər içindəki PL/pgSQL artıq mikrodalğalı sobada kiçik hot-doq kimi partlayırsa, narahat olma — bu normaldır. Başlanğıcda tez-tez "tipik" səhvlərlə rastlaşmaq olur. Bir neçə nümunə:

Dəyişənin elan olunmaması. Əgər DECLARE ilə dəyişən elan etməyi unutsan, PL/pgSQL "dəyişən mövcud deyil" səhvini verəcək.

NULL dəyərindən istifadə cəhdi. Dəyişən elan olunubsa, amma ona dəyər verilməyibsə, nəticə NULL olacaq. Bu, gözlənilməz davranışlara səbəb ola bilər. Məsələn:

IF my_var = NULL THEN -- İŞLƏMƏYƏCƏK!

IS NULL istifadə et:

IF my_var IS NULL THEN

EXCEPTION hissəsinin səhv istifadəsi. Bəzən proqramçılar bütün səhvləri (WHEN OTHERS) tuturlar, amma nə etmək lazım olduğunu yazmırlar. Bu, real problemi gizlədə bilər. Daha yaxşısı, səhv mesajını qeyd etməkdir:

RAISE NOTICE 'Səhv: %', SQLERRM;
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION