CodeGym /Kurslar /SQL SELF /Sadə funksiyaların yaradılması: CREATE FUNCTION

Sadə funksiyaların yaradılması: CREATE FUNCTION

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

PostgreSQL-də funksiyalar — kodun avtomatlaşdırılması, biznes-məntiqin yaradılması və serverə daha çox ağıllılıq vermək üçün güclü bir alətdir. Funksiyaları elə bil ki, bazanın içində işləyən mini-proqramlar kimi təsəvvür et. Onlar aşağıdakılar üçün rahatdır:

  • Kodun təkrar istifadəsi. Əgər eyni sorğunu bir neçə dəfə yazırsansa, onu funksiyaya bük və lazım olanda çağır.
  • Tapşırıqların avtomatlaşdırılması. Məsələn, işçilərin maaşını onların iş saatlarına görə hesablamaq lazımdırsa, funksiya bunu rahatlıqla edəcək.
  • Məntiqin inkapsulyasiyası. Çətin hesablamaları server tərəfində saxlamağa imkan verir ki, client-lər SQL sorğuları ilə baş sındırmasın.

Ümumi CREATE FUNCTION sintaksisi

Funksiya yaratmaq üçün ümumi struktur belədir:

CREATE FUNCTION function_name(parameters) RETURNS return_type AS $$
BEGIN
    -- Funksiyanın gövdəsi (məntiq)
    RETURN nəticə;
END;
$$ LANGUAGE plpgsql;

Əsas hissələrə baxaq:

CREATE FUNCTION function_name(parameters):

Bu sətrdə biz funksiyanın adını function_name və parametrləri (əgər lazımdırsa) göstəririk.

Parametrlər ad və data tipini ehtiva edə bilər: my_param INTEGER, another_param TEXT.

RETURNS return_type:

Funksiyamızın nə qaytaracağını göstəririk: bir dəyər (INTEGER, TEXT və s.) və ya data seti (TABLE, RECORD).

BEGIN ... END:

Bu açar sözlərin içində funksiyanın "gövdəsi" yerləşir, bütün sehr burada baş verir.

RETURN nəticə:

Funksiyanın icrasının nəticəsini qaytarır. Diqqətli ol: nəticənin tipi RETURNS-də göstərdiyin tipə uyğun olmalıdır.

LANGUAGE plpgsql:

PL/pgSQL dilindən istifadə etdiyimizi göstəririk. PostgreSQL başqa dilləri də dəstəkləyir, amma indi bizə bu lazımdır.

Sadə nümunə: iki ədədin toplanması

Gəlin iki tam ədədin cəmini qaytaran funksiya yaradaq.

CREATE FUNCTION add_numbers(a INT, b INT) RETURNS INT AS $$
BEGIN
    RETURN a + b;
END;
$$ LANGUAGE plpgsql;

İndi onu çağıraq:

SELECT add_numbers(5, 7); -- Nəticə: 12

Burada nə baş verir?

  • Funksiya iki parametr qəbul edir: ab tipi INT.
  • Funksiyanın içində sadəcə onları toplayırıq (a + b) və nəticəni qaytarırıq.
  • Hər şey kalkulyator kimi sadədir!

Dəyişənlərdən istifadə ilə nümunə

Təsəvvür et ki, universitet bazamız var və neçə tələbənin qeydiyyatdan keçdiyini bilmək istəyirik.

Funksiya yaradaq:

CREATE FUNCTION count_students() RETURNS INT AS $$
DECLARE
    total INT; -- Nəticəni saxlamaq üçün dəyişən elan edirik
BEGIN
    SELECT COUNT(*) INTO total FROM students; -- Cədvəldəki sətrlərin sayını hesablayırıq
    RETURN total; -- Nəticəni qaytarırıq
END;
$$ LANGUAGE plpgsql;

Funksiyanı çağırmaq:

SELECT count_students(); -- Tutaq ki, nəticə: 120

Burada görürük:

  • SQL sorğusunun nəticəsini saxlamaq üçün total dəyişənindən istifadə.
  • SELECT ... INTO komandası sorğunun nəticəsini dəyişənə yazır.

Bu yanaşma xüsusilə rahatdır, əgər əvvəlcə datanı emal edib sonra qaytarmaq lazımdırsa.

Bir neçə dəyərin qaytarılması: RETURNS TABLE

Əvvəlki nümunədə biz yalnız bir dəyər qaytardıq. Amma bəs funksiya data seti, məsələn, tələbələrin siyahısını qaytarmalıdırsa? Məhz burada RETURNS TABLE faydalı olur.

Nümunə:

CREATE FUNCTION get_students() RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
    RETURN QUERY SELECT id, name FROM students;
END;
$$ LANGUAGE plpgsql;

Funksiyanı çağırmaq:

SELECT * FROM get_students();

Mümkün nəticə:

id name
1 Alice
2 Bob
3 Charlie

Funksiya içində sorğular üçün RETURN QUERY-nin faydası

RETURN QUERY bizə SQL sorğusunun nəticəsini birbaşa funksiyadan qaytarmağa imkan verir. Bu, aralıq addımları azaldır və funksiyaları sadələşdirir.

Yalnız aktiv olan tələbələri qaytaran funksiya yaradaq:

CREATE FUNCTION get_active_students() RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
    RETURN QUERY SELECT id, name FROM students WHERE active = TRUE;
END;
$$ LANGUAGE plpgsql;

get_active_students() funksiyasını çağırmazdan əvvəl students cədvəlini yaratmaq və test dataları ilə doldurmaq lazımdır. Bunu belə edə bilərsən:

-- Tələbələr cədvəlini yaradırıq
CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    active BOOLEAN DEFAULT TRUE
);

-- Bir neçə qeyd əlavə edirik
INSERT INTO students (name, active) VALUES
('Alice', FALSE),
('Bob', TRUE),
('Charlie', TRUE),
('Dana', FALSE);

Cədvəl:

id name active
1 Alice false
2 Bob true
3 Charlie true
4 Dana false

İndi çağırış:

SELECT * FROM get_active_students();

Nəticə:

id name
2 Bob
3 Charlie

İcra etməzdən əvvəl datanın düzgünlüyünü yoxlamaq

Funksiyalarda IF yoxlamaları ola bilər ki, datanın düzgünlüyünə əmin olasan. Məsələn, tələbəni növbəti kursa keçirmək üçün o, bütün imtahanları verməlidir.

Nümunə:

CREATE FUNCTION promote_student(student_id INT) RETURNS TEXT AS $$
DECLARE
    passed_exams INT;
BEGIN
    -- Tələbənin verdiyi imtahanların sayını hesablayırıq
    SELECT COUNT(*) INTO passed_exams
    FROM exams
    WHERE student_id = promote_student.student_id AND status = 'keçib';

    -- Şərti yoxlayırıq
    IF passed_exams < 5 THEN
        RETURN 'Tələbə kifayət qədər imtahan verməyib';
    END IF;

    -- Tələbənin kursunu artırırıq
    UPDATE students
    SET course = course + 1
    WHERE id = promote_student.student_id;

    RETURN 'Tələbə kursa keçirildi!';
END;
$$ LANGUAGE plpgsql;

Funksiya yaradarkən tipik səhvlər

Nəticə tipinin olmaması. PostgreSQL həmişə tələb edir ki, funksiyanın hansı nəticəni qaytaracağını göstərəsən. Məsələn:

CREATE FUNCTION fail() AS $$ -- Səhv: RETURNS yoxdur
BEGIN
    RETURN 1;
END;
$$ LANGUAGE plpgsql;

Düzəliş:

CREATE FUNCTION succeed() RETURNS INT AS $$
BEGIN
    RETURN 1;
END;
$$ LANGUAGE plpgsql;

Nəticə tipinin uyğun olmaması. Əgər RETURNS INT göstərmisənsə, mütləq rəqəm qaytarmalısan. Bu halda sətir qaytarmaq — pis fikirdir.

Funksiya içində SQL sorğularında səhv. Sorğuları funksiyalarda istifadə etməzdən əvvəl həmişə yoxla. Ən yaxşısı onları "əllə" psql və ya pgAdmin-də test elə.

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