CodeGym /Kurslar /SQL SELF /Məlumatlarla işləyərkən tipik səhvlər

Məlumatlarla işləyərkən tipik səhvlər

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

Məlumatlarla işləyərkən tipik səhvlər

Verilənlər bazası ilə işləmək — proqramçının həyatı kimidir: sürprizlərlə doludur. Hətta ən təcrübəli developer belə səhv edə bilər, məsələn, təsadüfən məlumatları silmək, dublikat əlavə etmək və ya integrity constraint-ləri pozmaq. Amma əsas məsələ təkcə bu səhvlərdən qaçmaq deyil, həm də baş verəndə onları necə düzəltməyi bilməkdir. Gəlin ən tipik səhvlərə baxaq.

Səhv №1: WHERE şərtinin olmaması

Ən klassik səhv, hansı ki, yeni başlayanlar (və, düzünü desək, bəzən təcrübəli developer-lər də) edir — WHERE şərtini update və ya delete sorğusunda unutmaqdır. WHERE olmadan sorğular cədvəldəki bütün sətirləri yeniləyir və ya silir.

-- Necə etmək olmaz:
UPDATE students SET status = 'mezun oldu';

-- Və ya belə:
DELETE FROM students;

Nəticə: təsəvvür elə ki, belə bir sorğunu işə saldın və birdən gördün ki, students cədvəlin tamamilə boşdur. Ən pis tərəfi — backup yoxdursa və ya transaction istifadə etməmisənsə, məlumatları qaytarmaq olmur (hətta olsa belə, artıq stressdir).

Necə qarşısını almaq olar: həmişə UPDATEDELETE sorğularında şərt əlavə et, dəqiq hansı sətirləri dəyişmək və ya silmək istədiyini göstər.

-- Necə etmək lazımdır:
UPDATE students
SET status = 'mezun oldu'
WHERE year_of_study = 4;

DELETE FROM students
WHERE status = 'qovuldu';

Bir fənd də var — silmə əməliyyatından əvvəl həmişə SELECT işə sal, şərtin düzgün olduğuna əmin ol:

-- Əvvəlcə yoxlayırıq:
SELECT * FROM students WHERE status = 'qovuldu';

-- Sonra silirik:
DELETE FROM students WHERE status = 'qovuldu';

Səhv №2: Unikalığın pozulması (UNIQUE)

Əgər cədvəldə UNIQUE constraint varsa, dublikat əlavə etməyə cəhd edəndə səhv alacaqsan.

-- Email dublikatına görə səhv:
INSERT INTO students (name, email) VALUES ('Otto Lin', 'otto.lin@email.com');
INSERT INTO students (name, email) VALUES ('Peter Pen', 'otto.lin@email.com');

Səhv:

ERROR: duplicate key value violates unique constraint "students_email_key"

Necə qarşısını almaq olar: əlavə etməzdən əvvəl yoxla ki, belə dəyərli sətir artıq var, ya yox.

-- Bir variant:
SELECT * FROM students WHERE email = 'otto.lin@email.com';

-- Və ya UPSERT istifadə et:
INSERT INTO students (name, email)
VALUES ('Peter Pen', 'otto.lin@email.com')
ON CONFLICT (email) DO NOTHING;

Səhv №3: Integrity constraint-lərin pozulması (FOREIGN KEY)

Tutaq ki, səndə iki cədvəl var: studentsenrollments, burada enrollments cədvəlindəki student_id xarici açarla students cədvəlinin id-sına bağlıdır. Əgər enrollments-ə elə bir student_id əlavə etməyə çalışsan ki, students-də yoxdur, səhv alacaqsan.

INSERT INTO enrollments (student_id, course_id)
VALUES (999, 101); -- Səhv, çünki student_id 999 mövcud deyil

Necə qarşısını almaq olar?

  1. Əlaqəli cədvələ əlavə etməzdən əvvəl həmişə parent cədvəldə qeyd var, ya yox, yoxla:
SELECT * FROM students WHERE id = 999;
  1. ON DELETE CASCADE constraint istifadə et ki, parent cədvəldə qeyd silinəndə əlaqəli cədvəldə də avtomatik silinsin (amma ehtiyatlı ol).
CREATE TABLE enrollments (
    id SERIAL PRIMARY KEY,
    student_id INT REFERENCES students(id) ON DELETE CASCADE,
    course_id INT
);

Səhv №4: Yanlış data type-lar

Insert və ya update zamanı PostgreSQL data type-ların uyğunluğunu ciddi yoxlayır. Əgər string-i rəqəm sahəsinə yazmağa çalışsan, səhv alacaqsan.

-- Type uyğunluğuna görə səhv:
INSERT INTO students (id, name) VALUES ('abc', 'Alex Go');

Səhv:

ERROR: invalid input syntax for type integer

Necə qarşısını almaq olar? Daxil etdiyin dəyərlərin data type-larına diqqət yetir. Əgər məlumat user form-dan gəlirsə, mütləq application tərəfində validasiya et.

Səhv №5: Paralel giriş problemləri (məlumat sızması)

Təsəvvür elə ki, iki user eyni anda cədvəldə eyni sətri yeniləməyə çalışır. Transaction isolation düzgün qurulmayıbsa, konfliktlər ola bilər.

-- İstifadəçi A:
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;

-- İstifadəçi B:
BEGIN;
UPDATE accounts SET balance = balance - 50 WHERE id = 1;

Necə qarşısını almaq olar? Transaction və isolation level-lərdən istifadə et ki, eyni anda məlumat dəyişməsin.

BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;

Səhv №6: TRUNCATE səbəbindən məlumat itkisi

TRUNCATE cədvəldəki bütün sətirləri bərpa imkanı olmadan silir, çünki bu komanda üçün ROLLBACK dəstəklənmir (trigger-lər işə düşmür və dərhal icra olunur).

-- Hər şeyi geri dönmədən silir:
TRUNCATE TABLE students;

Necə qarşısını almaq olar: TRUNCATE əvəzinə şərtli DELETE istifadə et, əgər rollback etmək istəyirsənsə.

BEGIN;
DELETE FROM students WHERE year_of_study = 1;
-- Fikrin dəyişdi:
ROLLBACK;

Səhv №7: Vacib əməliyyatlarda transaction istifadə etməmək

Əgər bir neçə addımdan ibarət mürəkkəb əməliyyat icra edirsənsə və ortada səhv baş verərsə, məlumatlar inkonsistent qala bilər.

-- Addım 1: tələbəni əlavə edirik
INSERT INTO students (name, email) VALUES ('Otto Lin', 'otto.lin@email.com');

-- Addım 2: onu kursa yazırıq
INSERT INTO enrollments (student_id, course_id) VALUES (LASTVAL(), 101); -- səhv

Necə qarşısını almaq olar? Belə əməliyyatları transaction-a yığ:

BEGIN;

INSERT INTO students (name, email) VALUES ('İvan İvanov', 'ivan.ivanov@email.com');
INSERT INTO enrollments (student_id, course_id) VALUES (LASTVAL(), 101);

COMMIT;

Əgər istənilən mərhələdə səhv olsa, dəyişiklikləri geri qaytara bilərsən:

ROLLBACK;

Səhv №8: NULL ilə təsadüfi işləmək

NULL tez-tez sürprizlər yaradır, çünki nə sıfıra, nə də boş string-ə bərabər deyil və onunla müqayisələr gözlənilməz nəticə verə bilər.

-- Bu işləməyəcək:
SELECT * FROM students WHERE email = NULL;

Necə qarşısını almaq olar? IS NULL və ya IS NOT NULL istifadə et:

SELECT * FROM students WHERE email IS NULL;

Tipik səhvlər qaçılmazdır, amma onları necə tanımaq və qarşısını almağı bilsən, məlumatlarla əməliyyatları təhlükəsiz və effektiv edə bilərsən. PostgreSQL — məlumatlarının ciddi, amma ədalətli qoruyucusudur və nəsə səhv getsə, həmişə səhv mesajı qaytarmağa hazırdır. Sadəcə unutma ki, səhvlər düşmən deyil, müəllimdir.

1
Sorğu/viktorina
, səviyyə, dərs
Əlçatan deyil
Transaksiyalara giriş
Transaksiyalara giriş
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION