Asosiy kontentga o‘tish
Innovialabs

SQL INSERT, UPDATE va DELETE: ma’lumotlarni xavfsiz o‘zgartirish

Asoslar4 daq

Qisqacha

INSERT qator qo‘shadi, UPDATE o‘zgartiradi, DELETE o‘chiradi; xavfsiz ishlash uchun WHERE shartini avval SELECT bilan tekshiring, o‘zgarishni tranzaksiya ichida bajaring va COMMIT’dan oldin ta’sirlangan qatorlar sonini solishtiring.

Qisqa javob

SQL’da ma’lumotlarni uchta buyruq o‘zgartiradi:

  • INSERT yangi qatorlar qo‘shadi.
  • UPDATE mavjud qatorlardagi qiymatlarni o‘zgartiradi.
  • DELETE qatorlarni o‘chiradi.

UPDATE va DELETE WHERE shartiga mos keladigan barcha qatorlarga ta’sir qiladi. Agar shart xato bo‘lsa yoki umuman yo‘q bo‘lsa, buyruq baribir bajariladi — noto‘g‘ri qatorlarda yoki butun jadvalda. Shuning uchun xavfsizlik, avvalo, o‘zgarish yakuniy bo‘lishidan oldin WHERE’ni tekshirishdir.

INSERT: qator qo‘shish

INSERT INTO customers (name, email, city)
VALUES ('Aziza Karimova', 'aziza@example.com', 'Tashkent');

-- bir nechta qatorni birdaniga
INSERT INTO customers (name, email, city)
VALUES ('Bekzod', 'bek@example.com', 'Samarkand'),
       ('Dilnoza', 'dil@example.com', 'Bukhara');

-- so‘rov natijasini qo‘shish
INSERT INTO archived_orders (id, total, created_at)
SELECT id, total, created_at FROM orders WHERE created_at < '2024-01-01';

Ustunlarni doim aniq sanab o‘ting. Ro‘yxatsiz INSERT ustunlar tartibiga bog‘liq bo‘ladi va kimdir jadvalni o‘zgartirganda buziladi yoki qiymatlarni jimgina boshqa ustunlarga yozib qo‘yadi.

UPDATE: qatorlarni o‘zgartirish

UPDATE products
SET price = price * 1.1, updated_at = now()
WHERE category_id = 7;

SET ichida ustunning joriy qiymati, boshqa ustunlar va ifodalardan foydalanish mumkin. Bitta buyruq minglab qatorlarni o‘zgartirishi mumkin, shuning uchun eng muhim qism — WHERE.

DELETE: qatorlarni o‘chirish

DELETE FROM sessions
WHERE expires_at < now();

Jadvalni to‘liq tozalash uchun odatda TRUNCATE tezroq, lekin u qatorma-qator mantiqni chetlab o‘tadi va uni bekor qilish qiyinroq. Biznes jadvallarida ko‘pincha yumshoq o‘chirish (deleted_at ustuni) xavfsizroq: ma’lumotni tiklash mumkin, tarix saqlanadi.

Avariyalardan saqlaydigan odatlar

1. Avval xuddi shu WHERE bilan SELECT

UPDATE yoki DELETE’dan oldin aynan shu shart bilan SELECT bajaring:

SELECT count(*) FROM orders WHERE status = 'draft' AND created_at < '2025-01-01';

40 ta qator kutgan bo‘lsangiz-u, 40 000 tani ko‘rsangiz — to‘xtang. Keyin WHERE’ni o‘zgartirmasdan buyruqqa ko‘chiring.

2. O‘zgarishni tranzaksiyaga o‘rang

BEGIN;
UPDATE orders SET status = 'cancelled'
WHERE status = 'draft' AND created_at < '2025-01-01';
-- klient nechta qator o‘zgarganini ko‘rsatadi
SELECT status, count(*) FROM orders GROUP BY status;
COMMIT;   -- yoki biror narsa noto‘g‘ri bo‘lsa ROLLBACK

Tranzaksiya ichida natijani tekshirib, orqaga qaytarish mumkin. E’tibor bering: ba’zi vositalar (va autocommit yoqilgan MySQL) tranzaksiya aniq boshlanmasa, har bir buyruqni darhol qayd etadi. Bunday tranzaksiyalarni uzoq ochiq qoldirmang — ular qulflarni ushlab turadi.

3. RETURNING nima o‘zgarganini ko‘rsatadi

PostgreSQL (va boshqa ayrim MBBT) ta’sirlangan qatorlarni qaytara oladi:

DELETE FROM coupons
WHERE expires_at < now()
RETURNING id, code;

Bu arzon o‘zgarishlar jurnali, INSERT’dan keyin esa alohida SELECT’siz yaratilgan ID’larni olish usuli.

4. «Tekshir, keyin qo‘sh» o‘rniga UPSERT

Qator allaqachon mavjud bo‘lishi mumkin bo‘lsa, «avval tekshirish, keyin qo‘shish» poyga holatlarini (race condition) keltirib chiqaradi. Bitta atomar buyruqdan foydalaning. Buning uchun unikal kalit kerak.

-- PostgreSQL
INSERT INTO stock (sku, qty) VALUES ('A-100', 5)
ON CONFLICT (sku) DO UPDATE SET qty = stock.qty + EXCLUDED.qty;

-- MySQL
INSERT INTO stock (sku, qty) VALUES ('A-100', 5)
ON DUPLICATE KEY UPDATE qty = qty + VALUES(qty);

MySQL’ning yangi versiyalarida bu joyda VALUES() o‘rniga qator aliasini ishlatish tavsiya etiladi — o‘z versiyangiz hujjatlarini tekshiring.

Klassik avariya: WHERE’siz UPDATE

UPDATE users SET password_hash = '...';   -- bitta emas, barcha foydalanuvchilarda

Odatda bu so‘rovning belgilangan bo‘lagini ishga tushirganda, oxirgi qatorni yo‘qotganda yoki shoshilib tahrirlaganda sodir bo‘ladi. Himoya:

  • Avval WHERE’ni, keyin SET’ni yozing.
  • MySQL’da safe updates rejimini (--safe-updates) yoqing: u kalit bo‘yicha shartsiz yoki LIMIT’siz UPDATE va DELETE’ni rad etadi.
  • Ilova va tahlilchilar akkauntlariga ortiqcha huquq bermang; prod’dagi o‘zgarishlar tekshirilgan skriptlar va migratsiyalar orqali o‘tsin.
  • Tekshirilgan zaxira nusxalar va vaqt nuqtasiga tiklash imkoniyati bo‘lsin — COMMIT’dan keyin tranzaksiya yordam bermaydi.

Ko‘p uchraydigan xatolar

  • Autocommit yoqilgan GUI-klientdan to‘g‘ridan-to‘g‘ri prod’da tahrirlash.
  • Katta jadvalni daqiqalab qulflab qo‘yadigan bitta ulkan buyruq; uni bo‘laklarga ajrating.
  • SQL’ni parametrlar o‘rniga satrlarni qo‘shib yig‘ish — bu SQL-in’yeksiyaga yo‘l ochadi.
  • Tashqi kalitlar va ON DELETE CASCADE’ni tushunmay turib ota qatorlarni o‘chirish.

Ko‘p beriladigan savollar

SQL’ning o‘zi bilan — yo‘q. Zaxira nusxa, vaqt nuqtasiga tiklash yoki yumshoq o‘chirish sxemasi kerak. Shuning uchun natijani COMMIT’dan oldin tekshirish lozim.

Yana o‘qing

G‘oya yoki vazifangiz bormi? Bizga aytib bering

Ish kuni davomida javob beramiz va yechim taklif qilamiz. Konsultatsiya bepul.