Proqramlaşdırmada iki əsas şey var: baş verənləri başa düşmək (xüsusilə hər şey planladığın kimi getməyəndə) və faydalı datanı qaytarmaq. Bu, xüsusilə PL/pgSQL üçün aktualdır, çünki iş server tərəfində gedir və debug etmək həmişə asan olmur. Burda daxili alətlər köməyə gəlir:
RAISE NOTICE — funksiya işləyərkən mesajlar çıxarmaq üçün bir üsuldur. Bunu JavaScript-dəki console.log və ya Python-da print kimi təsəvvür elə. Dəyişənlərin dəyərlərini, icra vəziyyətini və ya sadəcə gələcəkdəki özün üçün "salam" mesajı göstərə bilərsən.
RETURN QUERY — data set-i, məsələn, bütöv bir cədvəl və ya mürəkkəb sorğunun nəticəsini qaytarmaq üsuludur. Bununla PL/pgSQL funksiyaları tam SQL sorğuları kimi işləyir.
RAISE NOTICE komandası
RAISE NOTICE funksiya işləyərkən ekrana mesajlar çıxarmağa imkan verir. Format belədir:
RAISE NOTICE 'Mesaj: %', deyər;
%— dəyişən üçün placeholder-dır, C-dəkiprintf-ə bənzəyir.- Mesaj mətnindən sonra dəyişənləri sadalaya bilərsən, onlar yerinə qoyulacaq.
İstifadə nümunəsi
Təsəvvür elə ki, müxtəlif qruplarda tələbələrin sayını sayan funksiya yazırsan. Aralıq dəyərləri görmək istəyirsən ki, hər şey qaydasındadırmı başa düşəsən.
CREATE OR REPLACE FUNCTION count_students_in_groups() RETURNS VOID AS $$
DECLARE
group_name TEXT;
student_count INT;
BEGIN
FOR group_name IN SELECT DISTINCT group_name FROM students LOOP
SELECT COUNT(*) INTO student_count
FROM students WHERE group_name = group_name;
-- Nəticələri çıxarırıq
RAISE NOTICE 'Qrup: %, Tələbə sayı: %', group_name, student_count;
END LOOP;
END;
$$ LANGUAGE plpgsql;
Bu funksiyanı çağıranda:
SELECT count_students_in_groups();
Loglarda belə mesajlar görəcəksən:
NOTICE: Qrup: Riyaziyyat, Tələbə sayı: 30
NOTICE: Qrup: Fəlsəfə, Tələbə sayı: 25
NOTICE: Qrup: Biologiya, Tələbə sayı: 18
Qeyd elə ki, funksiya heç nə qaytarmır (RETURNS VOID ilə yaradılıb), amma RAISE NOTICE dövrün necə getdiyini göstərir.
RAISE ilə faydalı trüki
NOTICE-dan başqa, başqa mesaj səviyyələrindən də istifadə edə bilərsən:
RAISE DEBUG— əlavə info üçün (yalnız log səviyyəsi DEBUG olarsa görünür).RAISE INFO— ümumi məlumat üçün.RAISE WARNING— xəbərdarlıq üçün.RAISE EXCEPTION— error yaratmaq üçün, bunu sonra öyrənəcəyik.
Debug üçün ən yaxşısı NOTICE və ya DEBUG-dan istifadə etməkdir, çünki onlar rahatdır və funksiyanı dayandırmır.
RETURN QUERY komandası: datanı pro kimi qaytar
RETURN QUERY PL/pgSQL-də sətirlər toplusunu qaytarmaq üçün istifadə olunur. Bununla SQL sorğusunun nəticəsini birbaşa funksiya içindən qaytara bilərik. Sintaksis belədir:
RETURN QUERY <SQL-sorgu>;
Bir neçə sorğunu da birləşdirə bilərsən:
RETURN QUERY <SQL-sorgu 1>;
RETURN QUERY <SQL-sorgu 2>;
Nümunə 1: RETURN QUERY ilə funksiya
Bir funksiya yazaq ki, verilmiş qrupdan olan tələbələrin siyahısını qaytarsın.
CREATE OR REPLACE FUNCTION get_students_by_group(group_name TEXT)
RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
RETURN QUERY
SELECT id, name
FROM students
WHERE group_name = group_name;
END;
$$ LANGUAGE plpgsql;
İndi bu funksiyanı çağırırıq:
SELECT * FROM get_students_by_group('Riyaziyyat');
Funksiyanı yoxlamaq üçün əvvəlcə students cədvəlini yaradıb ora data əlavə edək:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
group_name TEXT NOT NULL
);
INSERT INTO students (name, group_name) VALUES
('Otto Song', 'Fizika'),
('Alex Lin', 'Riyaziyyat'),
('Anna Vel', 'Riyaziyyat'),
('Maria Chi', 'Tarix');
Nəticə:
| id | name |
|---|---|
| 2 | Alex Lin |
| 3 | Anna Vel |
Gördüyün kimi, funksiya adi SQL sorğusu kimi işləyir.
Nümunə 2: Bir neçə sorğunu birləşdirmək
Bəs birdən bir neçə cədvəldən birləşdirilmiş data qaytarmaq lazımdır? Gəlin tələbələrin və onların yazıldığı kursların siyahısını qaytaraq.
CREATE OR REPLACE FUNCTION get_students_and_courses()
RETURNS TABLE(student_name TEXT, course_name TEXT) AS $$
BEGIN
RETURN QUERY
SELECT s.name, c.name
FROM students s
JOIN enrollments e ON s.id = e.student_id
JOIN courses c ON e.course_id = c.id;
END;
$$ LANGUAGE plpgsql;
Əvvəlcə üç cədvəl yaradaq: students, courses və enrollments, sonra bir az data əlavə edək:
-- Tələbələr cədvəli
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
-- Kurslar cədvəli
CREATE TABLE courses (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
-- Kurslara yazılma cədvəli (əlaqələndirici)
CREATE TABLE enrollments (
student_id INT REFERENCES students(id),
course_id INT REFERENCES courses(id)
);
-- Tələbələri əlavə edirik
INSERT INTO students (name) VALUES
('Otto Song'),
('Alex Lin'),
('Anna Vel'),
('Maria Chi');
-- Kursları əlavə edirik
INSERT INTO courses (name) VALUES
('Riyaziyyat'),
('Fizika'),
('Tarix');
-- Kurslara yazılmaları əlavə edirik
INSERT INTO enrollments (student_id, course_id) VALUES
(1, 2), -- Otto -> Fizika
(2, 1), -- Alex -> Riyaziyyat
(3, 1), -- Anna -> Riyaziyyat
(4, 3); -- Maria -> Tarix
Bu halda funksiyanı çağıranda:
SELECT * FROM get_students_and_courses();
belə nəticə alacaqsan:
| student_name | course_name |
|---|---|
| Otto Song | Fizika |
| Alex Lin | Riyaziyyat |
| Anna Vel | Riyaziyyat |
| Maria Chi | Tarix |
Funksiya üç cədvəldən datanı birləşdirir və göstərir ki, hansı tələbə hansı kursa yazılıb.
RAISE NOTICE və RETURN QUERY bir yerdə
Bəzən RETURN QUERY və RAISE NOTICE bir funksiyada işləyə bilər ki, həm funksiyanın icrasına nəzarət edəsən, həm də aralıq nəticələri görəsən.
Budur, tələbələr haqqında data qaytaran və eyni zamanda icra prosesini göstərən mesajlar çıxaran funksiya nümunəsi:
CREATE OR REPLACE FUNCTION debug_students()
RETURNS TABLE(student_id INT, student_name TEXT) AS $$
DECLARE
count_students INT;
BEGIN
-- Tələbələrin sayını sayırıq
SELECT COUNT(*) INTO count_students FROM students;
RAISE NOTICE 'Cəmi tələbə: %', count_students;
-- Tələbələr haqqında datanı qaytarırıq
RETURN QUERY
SELECT id, name FROM students;
RAISE NOTICE 'Funksiya icranı bitirdi.';
END;
$$ LANGUAGE plpgsql;
Əgər students cədvəli hələ yaradılmayıbsa, onu yaradıb data əlavə et:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
INSERT INTO students (name) VALUES
('Otto Song'),
('Alex Lin'),
('Anna Vel'),
('Maria Chi');
İndi funksiyanı çağıranda:
SELECT * FROM debug_students();
Həm data, həm də mesajlar çıxacaq:
| student_id | student_name |
|---|---|
| 1 | Otto Song |
| 2 | Alex Lin |
| 3 | Anna Vel |
| 4 | Maria Chi |
Konsolda mesaj çıxışı:
NOTICE: Cəmi tələbə: 4
NOTICE: Funksiya icranı bitirdi.
İstifadədə tipik səhvlər
RAISE NOTICE-də dəyişənlərlə səhv: əgər dəyişəni elan etməyi unutsan və ya adında səhv etsən, variable does not exist error-u alacaqsan. Həmişə yoxla ki, dəyişənlər düzgün elan olunub.
Qaytarma tipi ilə səhv: əgər RETURN QUERY istifadə edirsən, amma funksiya yaradanda RETURNS TABLE göstərmirsən, PostgreSQL error verəcək. Qaytarılan datanın tipi ilə uyğun olduğuna əmin ol.
RAISE-də placeholder-larla səhv: əgər % placeholder-ların sayı dəyişənlərin sayına uyğun olmasa, error çıxacaq. Məsələn:
RAISE NOTICE 'Dəyər: %, %', value1;
Burda ikinci dəyişən olmadığı üçün error olacaq.
GO TO FULL VERSION