UPDATE, DELETE — RETURNING, xavfli holatlar

~15 daq · PostgreSQL · DDL va DML

UPDATE va DELETE — eng xavfli SQL buyruqlar. WHERE unutilsa — jadvalning hamma ma'lumoti o'zgaradi yoki o'chadi. Shu sababli bu ikki buyruqni yaxshi bilish shart.


UPDATE — ma'lumot yangilash

UPDATE foydalanuvchilar
SET ism = 'Alibek'
WHERE id = 1;

Bir vaqtda bir nechta ustun:

UPDATE foydalanuvchilar
SET ism   = 'Alibek',
    yosh  = 26,
    faol  = TRUE
WHERE id = 1;

Hisoblash bilan yangilash:

UPDATE mahsulotlar
SET narx = narx * 1.10   -- ← narxni 10% oshirish
WHERE kategoriya = 'elektronika';

RETURNING — yangilangan qatorni ko'rish

UPDATE foydalanuvchilar
SET yosh = 26
WHERE id = 1
RETURNING id, ism, yosh;

--  id |   ism   | yosh
-- ----+---------+------
--   1 | Alibek  |   26

RETURNING bilan qo'shimcha SELECT yozish shart emas — yangilangan natija darhol qaytadi.


DELETE — ma'lumot o'chirish

DELETE FROM foydalanuvchilar
WHERE id = 1;

Shart bilan o'chirish:

DELETE FROM foydalanuvchilar
WHERE faol = FALSE;

DELETE FROM buyurtmalar
WHERE sana < '2023-01-01';  -- ← eski buyurtmalarni tozalash

RETURNING — o'chirilgan qatorni ko'rish

DELETE FROM foydalanuvchilar
WHERE id = 5
RETURNING *;

--  id |  ism  |     email
-- ----+-------+----------------
--   5 | Jasur | jasur@mail.com

WHERE siz UPDATE va DELETE — eng xavfli xato

Tasavvur qiling: 100,000 foydalanuvchi bor. Bitta qatorni yangilash o'rniga:

-- ❌ WHERE unutildi
UPDATE foydalanuvchilar
SET parol = 'yangi_hash';
-- Hammaning paroli o'zgardi. Orqaga qaytarish yo'q.

-- ✅ WHERE bilan
UPDATE foydalanuvchilar
SET parol = 'yangi_hash'
WHERE id = 42;
-- ❌ WHERE unutildi
DELETE FROM buyurtmalar;
-- Barcha buyurtmalar o'chdi.

-- ✅ WHERE bilan
DELETE FROM buyurtmalar
WHERE id = 15;

Xavfsiz yondashuv — avval SELECT

Istalgan UPDATE yoki DELETE dan oldin avval SELECT bilan nimaga tegishini ko'ring:

-- Avval shu yozuvlarni ko'ring
SELECT * FROM foydalanuvchilar WHERE faol = FALSE;

-- Ko'rib, to'g'ri ekaniga ishonch hosil qilgandan keyin
DELETE FROM foydalanuvchilar WHERE faol = FALSE;

Bir nechta jadval bilan UPDATE

UPDATE ... FROM — boshqa jadval ma'lumotiga qarab yangilash:

UPDATE mahsulotlar
SET narx = narx * chegirma.koeffitsient
FROM chegirma
WHERE mahsulotlar.kategoriya_id = chegirma.kategoriya_id;

Tez-tez uchraydigan xatolar

WHERE siz UPDATE yoki DELETE

-- ❌ — hamma qatorga tegadi
UPDATE foydalanuvchilar SET faol = FALSE;
DELETE FROM sessiyalar;

Himoya uchun — muhim UPDATE/DELETE lar oldidan BEGIN bilan tranzaksiya oching. Noto'g'ri bo'lsa ROLLBACK qiling:

BEGIN;
DELETE FROM foydalanuvchilar WHERE faol = FALSE;
-- Natijani tekshiring
SELECT COUNT(*) FROM foydalanuvchilar;  -- kutilgan sondami?
COMMIT;   -- to'g'ri bo'lsa tasdiqlang
-- yoki
ROLLBACK; -- xato bo'lsa bekor qiling

FOREIGN KEY bor qatorni o'chirish

DELETE FROM foydalanuvchilar WHERE id = 1;
-- ERROR: update or delete on table "foydalanuvchilar" violates
-- foreign key constraint on table "buyurtmalar"

Ali ning buyurtmalari bor — uni o'chirish mumkin emas. Avval buyurtmalarni o'chiring, keyin foydalanuvchini. Yoki ON DELETE CASCADE sozlangan bo'lsa — o'zi bajaradi.

UPDATE da eski qiymatni ishlatish

-- ❌ — SET ichida WHERE dagi qiymatni ishlatib bo'lmaydi
UPDATE hisoblar
SET balans = 0
WHERE balans = balans - 1000;  -- mantiqan noto'g'ri

-- ✅ — mavjud qiymatga nisbatan hisoblash
UPDATE hisoblar
SET balans = balans - 1000
WHERE id = 1;

Xulosa

UPDATE — mavjud qatorlarni yangilash. SET bilan yangi qiymatlar, WHERE bilan qaysi qatorlar.

DELETE — qatorlarni o'chirish. WHERE siz — hammasi o'chadi.

RETURNING — UPDATE va DELETE dan so'ng qo'shimcha SELECT yozmasdan natijani olish.

Asosiy qoida: UPDATE va DELETE yozishdan oldin avval SELECT bilan nimaga tegishini ko'ring.


Keyingi dars

10-dars: UPSERT — INSERT ON CONFLICT DO UPDATE / DO NOTHING