CodeGym /Kurslar /SQL SELF /RAISE NOTICE, RETURN QUERY operatorları

RAISE NOTICE, RETURN QUERY operatorları

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

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əki printf-ə 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 NOTICERETURN QUERY bir yerdə

Bəzən RETURN QUERYRAISE 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.

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