CodeGym /Kurslar /SQL SELF /Funksiyaların yaradılmasında tipik səhvlərin təhlili

Funksiyaların yaradılmasında tipik səhvlərin təhlili

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

Bu gün funksiyaların yaradılmasında tipik səhvləri, onların səbəblərini və necə düzəldiləcəyini müzakirə edəcəyik. Axı, yalnız debug edərək əsl proqramçı öz sənətini öyrənir — coding! Let's debug it!

Funksiya yaratmaq, xüsusilə PL/pgSQL öyrənməyə yeni başlayanlar üçün bir az çətin görünə bilər. Hətta ən təcrübəli PostgreSQL developer-lar belə bəzən "daşlara" rast gəlirlər. Gəlin bunları bir-bir analiz edək.

1. RETURNS açar sözünün unudulması

PL/pgSQL funksiyaların təsvirində çox ciddi davranır. Ən çox rast gəlinən yanlışlardan biri — funksiyanın hansı data type qaytarmalı olduğunu göstərməməyi unutmaqdır. Məsələn:

-- Səhv: RETURNS açar sözü yoxdur
CREATE FUNCTION incorrect_function() AS $$
BEGIN
    RETURN 1;
END;
$$ LANGUAGE plpgsql;

PostgreSQL başa düşməyəcək ki, bu funksiya nə qaytarmalıdır. RETURNS sintaksisin məcburi hissəsidir və qaytarılan data type-ı göstərir (məsələn, RETURNS INT, RETURNS TEXT və ya hətta RETURNS VOID).

Düzəliş: RETURNS açar sözünü və data type-ı əlavə et:

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

2. RETURN olmadan nəticə qaytarmaq cəhdi

Yeni başlayan developer-lar tez-tez unudurlar ki, PL/pgSQL-də nəticə qaytarmaq üçün mütləq RETURN operatorundan istifadə etmək lazımdır. Məsələn:

-- Səhv: RETURN yoxdur
CREATE FUNCTION missing_return() RETURNS TEXT AS $$
BEGIN
    'Salam, Dünya!'; -- Sadəcə string, amma qaytarılmır
END;
$$ LANGUAGE plpgsql;

Burada 'Salam, Dünya!' sadəcə yazılıb, amma qaytarılmır. PostgreSQL bunu nəticə kimi görmür və error atacaq.

Düzəliş: aydın şəkildə RETURN operatorunu əlavə et:

CREATE FUNCTION fixed_return() RETURNS TEXT AS $$
BEGIN
    RETURN 'Salam, Dünya!';
END;
$$ LANGUAGE plpgsql;

3. Deklarasiya olunmamış dəyişənə data yazmaq cəhdi

PL/pgSQL-də dəyişəni istifadə etməzdən əvvəl DECLARE blokunda elan etmək lazımdır. Məsələn:

-- Səhv: my_var dəyişəni elan olunmayıb
CREATE FUNCTION missing_variable() RETURNS VOID AS $$
BEGIN
    my_var := 'Salam, Dünya!';
END;
$$ LANGUAGE plpgsql;

PostgreSQL my_var dəyişəninin mövcudluğundan xəbərsizdir, çünki o, DECLARE blokunda elan olunmayıb.

Düzəliş: dəyişənləri həmişə DECLARE-də elan et:

CREATE FUNCTION declared_variable() RETURNS VOID AS $$
DECLARE
    my_var TEXT;
BEGIN
    my_var := 'Salam, Dünya!';
END;
$$ LANGUAGE plpgsql;

4. VOID tipinin düzgün istifadə olunmaması

VOID tipi göstərir ki, funksiya heç bir data qaytarmır. Bəzən developer-lar VOID tipli funksiyada RETURN istifadə etməyə çalışırlar və bu da error verir:

-- Səhv: VOID tipli funksiyada RETURN
CREATE FUNCTION void_example() RETURNS VOID AS $$
BEGIN
    RETURN 1; -- Dəyər qaytarmaq olmaz
END;
$$ LANGUAGE plpgsql;

VOID tipli funksiyalar dəyər qaytarmamalıdır. RETURN operatorundan istifadə etmək olar, amma dəyərsiz.

Düzəliş: ya RETURN-u sil, ya da dəyərsiz yaz:

CREATE FUNCTION correct_void() RETURNS VOID AS $$
BEGIN
    -- Sadəcə əməliyyatlar aparılır
    RAISE NOTICE 'Bu funksiya heç nə qaytarmır';
    RETURN; -- Funksiyanı bitirir
END;
$$ LANGUAGE plpgsql;

5. Debug üçün RAISE-in səhv istifadəsi

PL/pgSQL-də debug çox vaxt RAISE NOTICE operatoru ilə edilir. Amma yanlış format və dəyişənlərdən istifadə error-a səbəb ola bilər.

Məsələn:

-- Səhv: yanlış format
CREATE FUNCTION debug_example() RETURNS VOID AS $$
BEGIN
    RAISE NOTICE 'Dəyər: %'; -- Dəyişən yoxdur
END;
$$ LANGUAGE plpgsql;

RAISE operatoru gözləyir ki, %-dən sonra dəyişən və ya dəyər gələcək. Əgər % boş qalsa, PostgreSQL error verəcək.

Düzəliş: dəyişən və ya dəyərləri düzgün göstər:

CREATE FUNCTION fixed_debug() RETURNS VOID AS $$
DECLARE
    my_var TEXT := 'PostgreSQL';
BEGIN
    RAISE NOTICE 'Dəyər: %', my_var; -- Dəyişən göstərilib
END;
$$ LANGUAGE plpgsql;

6. Dəyişən və sütun adlarının toqquşması

Əgər dəyişənin adı sütunun adı ilə üst-üstə düşürsə, bu gözlənilməz nəticələrə gətirib çıxara bilər. Məsələn:

-- Səhv: dəyişən və sütun adının konflikti
CREATE FUNCTION name_conflict() RETURNS TEXT AS $$
DECLARE
    name TEXT;
BEGIN
    SELECT name INTO name FROM students LIMIT 1; -- Hansı name istifadə olunur?
    RETURN name;
END;
$$ LANGUAGE plpgsql;

PL/pgSQL-də dəyişən adı ilə sütun adı üst-üstə düşəndə, dəyişən üstünlük təşkil edir.

Düzəliş: cədvəl üçün alias istifadə et və ya adların üst-üstə düşməsindən qaç:

CREATE FUNCTION fixed_conflict() RETURNS TEXT AS $$
DECLARE
    student_name TEXT;
BEGIN
    SELECT s.name INTO student_name FROM students s LIMIT 1;
    RETURN student_name;
END;
$$ LANGUAGE plpgsql;

7. Dövrədə (loop-da) sorğuların səhv icrası

Loop-larda SQL-sorğuları icra edərkən tez-tez səhvlər olur. Məsələn:

-- Səhv: loop-da yanlış sorğu
CREATE FUNCTION cycle_error() RETURNS VOID AS $$
BEGIN
    FOR rec IN SELECT * FROM students LOOP
        EXECUTE 'UPDATE students SET active = TRUE WHERE id = ' || rec.id;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

SQL-injection... Təhlükə! SQL-sorğular üçün string birləşdirmək — pis praktikadır. Bu, təhlükəsiz deyil.

Düzəliş üçün parametrlərdən istifadə et:

CREATE FUNCTION safe_cycle() RETURNS VOID AS $$
BEGIN
    FOR rec IN SELECT * FROM students LOOP
        EXECUTE 'UPDATE students SET active = TRUE WHERE id = $1' USING rec.id;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

8. Data type-larla bağlı səhvlər

Səhv nümunəsi:

-- Səhv: data type uyğun gəlmir
CREATE FUNCTION type_error() RETURNS INT AS $$
DECLARE
    my_var TEXT := 'not_a_number';
BEGIN
    RETURN my_var; -- INT əvəzinə TEXT qaytarılır, error
END;
$$ LANGUAGE plpgsql;

PostgreSQL INT gözləyir, amma TEXT alır. Data type-ların uyğunluğu ciddi yoxlanılır.

Düzəliş? Data type-ları uyğunlaşdır və ya explicit conversion et:

CREATE FUNCTION type_correct() RETURNS INT AS $$
DECLARE
    my_var TEXT := '42';
BEGIN
    RETURN my_var::INT; -- Text-i rəqəmə çeviririk
END;
$$ LANGUAGE plpgsql;

Ən yaxşı praktikalar və məsləhətlər

  • Çətin funksiyaları kiçik hissələrə böl. Bu, debug və test etməyi asanlaşdırır.
  • Funksiyalarda comment-lərdən istifadə et — çətin əməliyyatları izah etmək üçün.
  • Funksiyaları əvvəlcə kiçik datalar üzərində test et, real cədvəllərdə istifadə etməzdən əvvəl.
  • RAISE NOTICE ilə debug et, icra prosesini başa düşmək üçün.
  • SQL-injection-lardan qaç: sorğular üçün parametrlərdən istifadə et.
-- Debug üçün RAISE istifadə olunur
DO $$
DECLARE
    total_students INT;
BEGIN
    SELECT COUNT(*) INTO total_students FROM students;
    RAISE NOTICE 'Cəmi tələbə: %', total_students; -- Debug mesajı
END;
$$;

Bu məsləhətlər bir çox başağrısından qaçmağa və PL/pgSQL "daşlarını" birdəfəlik məhv etməyə kömək edəcək!

1
Sorğu/viktorina
, səviyyə, dərs
Əlçatan deyil
Sadə funksiyaların yaradılması
Sadə funksiyaların yaradılması
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION