CodeGym /Kurslar /SQL SELF /Funksiyalar və prosedurlar arasında qarşılıqlı əlaqə

Funksiyalar və prosedurlar arasında qarşılıqlı əlaqə

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

Bir neçə səviyyə əvvəl artıq PostgreSQL-də prosedurlar və funksiyalar mövzusuna toxunmuşduq. İndi isə gəlin onları daha dərindən öyrənək.

Funksiyalar və prosedurlar təkbaşına işləyə bilər, amma əksər hallarda onların qarşılıqlı əlaqəsi bütün sistemin uğurunu müəyyən edir. Əsas rahatlıq ondadır ki, funksiyaları bir-birinin içində çağırmaq, məlumat ötürmək və hətta nəticəni almaq mümkündür.

Funksiyalar vs Prosedurlar: fərq nədədir?

Gəlin yadımıza salaq, PostgreSQL-də funksiyalar prosedurlardan nə ilə fərqlənir:

  • Funksiyalar (FUNCTION):

    • Dəyərlər qaytarır.
    • Onları SELECT-də istifadə etmək olar.
    • Çox vaxt hesablamalar və ya məlumat çevirmələri üçün istifadə olunur.
  • Prosedurlar (PROCEDURE):

    • Dəyərləri birbaşa qaytarmır.
    • Məlumat əlavə etmək, yeniləmək və ya silmək kimi əməliyyatlar üçün istifadə olunur.
    • CALL əmri ilə çağırılır.

Funksiyalar arasında məlumat ötürülməsi

Praktikaya keçək, funksiyadan prosedura və ya funksiyadan funksiyaya məlumat ötürülməsinin əsas nümunəsindən başlayaq. Əslində, funksiyalar arasında məlumat ötürülməsi parametrlər və qaytarılan dəyərlər vasitəsilə baş verir.

Bir funksiyanın başqa bir funksiyanın içində çağırılması belə görünür:

CREATE OR REPLACE FUNCTION get_student_name(student_id INT)
RETURNS TEXT AS $$
DECLARE
    student_name TEXT;
BEGIN
    -- Student ID-ə görə tələbənin adını çıxarırıq
    SELECT name INTO student_name FROM students WHERE id = student_id;

    -- Adı qaytarırıq
    RETURN student_name;
END;
$$ LANGUAGE plpgsql;

Bu funksiyanı başqa bir funksiyanın içində çağırmaq olar:

CREATE OR REPLACE FUNCTION welcome_student(student_id INT)
RETURNS TEXT AS $$
DECLARE
    message TEXT;
BEGIN
    -- Başqa funksiyanın köməyi ilə tələbənin adını alırıq
    message := 'Xoş gəldin, ' || get_student_name(student_id) || '!';

    -- Salamlamanı qaytarırıq
    RETURN message;
END;
$$ LANGUAGE plpgsql;
  1. get_student_name funksiyası tələbənin identifikatoruna (student_id) görə adını qaytarır.
  2. Başqa funksiyada — welcome_student — bu ad salam mesajı yaratmaq üçün istifadə olunur.

Qeyd: SELECT INTO ilə məlumat çıxaranda nəticə PL/pgSQL dəyişənində saxlanılır.

Funksiyalardan prosedurların çağırılması nümunəsi

İndi isə gəlin baxaq, funksiyadan proseduru necə çağırmaq olar. Tutaq ki, bizdə tələbənin sistemə giriş vaxtını qeyd edən prosedur var:

CREATE OR REPLACE PROCEDURE log_student_entry(student_id INT)
LANGUAGE plpgsql
AS $$
BEGIN
    INSERT INTO log_entries(student_id, entry_time)
    VALUES (student_id, NOW());
END;
$$;

İndi bu proseduru funksiyanın içində çağıracağıq, burada giriş qeyd olunacaq və mesaj qaytarılacaq:

CREATE OR REPLACE FUNCTION student_login(student_id INT)
RETURNS TEXT AS $$
BEGIN
    -- Log üçün proseduru çağırırıq
    CALL log_student_entry(student_id);

    -- Mesajı qaytarırıq
    RETURN 'Tələbənin girişi uğurla qeyd olundu.';
END;
$$ LANGUAGE plpgsql;

Praktik qarşılıqlı əlaqə nümunələri

Nümunə 1: yekun məbləğin hesablanması və sifarişin loglanması

Təsəvvür et ki, sən online-sifariş sistemi ilə işləyirsən. Sifarişin yekun məbləğini hesablamaq üçün belə bir funksiya var:

CREATE OR REPLACE FUNCTION calculate_order_total(order_id INT)
RETURNS NUMERIC AS $$
DECLARE
    total NUMERIC;
BEGIN
    -- Sifarişin bütün mövqelərini toplayırıq
    SELECT SUM(price * quantity) INTO total
    FROM order_items
    WHERE order_id = order_id;

    RETURN total;
END;
$$ LANGUAGE plpgsql;

Sifarişin yekun məbləğini saxlamaq üçün prosedurdan istifadə olunur:

CREATE OR REPLACE PROCEDURE log_order_total(order_id INT, total NUMERIC)
LANGUAGE plpgsql
AS $$
BEGIN
    INSERT INTO order_totals(order_id, total)
    VALUES (order_id, total);
END;
$$;

İndi onları birləşdirək:

CREATE OR REPLACE FUNCTION process_order(order_id INT)
RETURNS TEXT AS $$
DECLARE
    total NUMERIC;
BEGIN
    -- Yekun məbləği hesablamaq üçün funksiyanı çağırırıq
    total := calculate_order_total(order_id);

    -- Yekun məbləği prosedur vasitəsilə loglayırıq
    CALL log_order_total(order_id, total);

    RETURN 'Sifariş uğurla emal olundu.';
END;
$$ LANGUAGE plpgsql;

Nümunə 2: tələbənin maksimum reytinqinin alınması və profilin yenilənməsi

Maksimum reytinqi almaq üçün funksiya:

CREATE OR REPLACE FUNCTION get_highest_rating(student_id INT)
RETURNS INT AS $$
DECLARE
    max_rating INT;
BEGIN
    -- Tələbənin maksimum reytinqini tapırıq
    SELECT MAX(rating) INTO max_rating
    FROM ratings
    WHERE student_id = student_id;

    RETURN max_rating;
END;
$$ LANGUAGE plpgsql;

Tələbə profilini yeniləmək üçün prosedur:

CREATE OR REPLACE PROCEDURE update_student_profile(student_id INT, max_rating INT)
LANGUAGE plpgsql
AS $$
BEGIN
    UPDATE students
    SET highest_rating = max_rating
    WHERE id = student_id;
END;
$$;

Bu əməliyyatları çağıran funksiya:

CREATE OR REPLACE FUNCTION refresh_student_profile(student_id INT)
RETURNS TEXT AS $$
DECLARE
    max_rating INT;
BEGIN
    -- Maksimum reytinqi alırıq
    max_rating := get_highest_rating(student_id);

    -- Tələbə profilini yeniləyirik
    CALL update_student_profile(student_id, max_rating);

    RETURN 'Profil uğurla yeniləndi.';
END;
$$ LANGUAGE plpgsql;

Qarşılıqlı əlaqədə tipik səhvlər

Ən çox rast gəlinən səhvlərdən biri — funksiya və prosedur arasında məlumat tiplərinin uyğun gəlməməsidir. Məsələn, əgər prosedur NUMERIC tipində parametr gözləyirsə, amma sən INTEGER ötürürsənsə, PostgreSQL tip uyğunsuzluğu barədə xəbərdarlıq edəcək. Həmişə yoxla ki, məlumat tipləri uyğun gəlsin.

Başqa bir səhv — funksiyaların bir-birini dövrü şəkildə çağırmasıdır: funksiya A funksiyanı B çağırır, o isə yenidən A-nı çağırır. Bu, sonsuz çağırışa və sistemin çökməsinə gətirib çıxarır.

Praktik əhəmiyyət

Bəs bizə belə qarşılıqlı əlaqə niyə lazımdır? Real həyatda funksiyalar və prosedurlar mürəkkəb sistemlərin "konstruksiya blokları" kimi işləyir. Onlar kodu müstəqil hissələrə bölməyə imkan verir, bu da debug, təkrar istifadə və test etməni asanlaşdırır. Məsələn:

  • Müsahibədə səndən proseduru çağıran funksiya yazmağı istəyə bilərlər. Qarşılıqlı əlaqə bacarığını göstərmək böyük üstünlükdür.
  • Real tətbiqlərin hazırlanmasında, məsələn, internet-mağazalar, log sistemləri və ya CRM-lərdə funksiyalar və prosedurlar vasitəsilə funksionallığı düzgün təşkil etmək kodu xeyli sadələşdirir.

Funksiyalar və prosedurlar arasında qarşılıqlı əlaqəni daha dərindən öyrənmək üçün PL/pgSQL üzrə rəsmi sənədləşməyə baxa bilərsən.

2
Tapşırıq
SQL SELF, səviyyə, dərs
Bağlanıb
Tələbənin profilinin reytinqə əsasən yenilənməsi
Tələbənin profilinin reytinqə əsasən yenilənməsi
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION