Mundarija (28)
- Bu darsda
- 1. Nega bu kerak?
- 2. UPDATE asoslari
- 2.1 SET va WHERE
- 2.2 Hech narsa topilmasa — xato emas
- 2.3 Cheklovlar UPDATE'da ham ishlaydi
- 3. DELETE asoslari
- 3.1 Qator o'chirish
- 3.2 CASCADE'ni eslang
- 4. Xavfsiz o'zgartirish tartibi
- 4.1 To'rt qadam
- 4.2 WHERE unutilsa
- 4.3 Xato tranzaksiyani "buzadi"
- 5. Boshqa jadvalga qarab o'zgartirish
- 5.1 UPDATE … FROM
- 5.2 DELETE … USING
- 6. TRUNCATE: jadvalni bo'shatish
- 6.1 TRUNCATE va DELETE farqi
- 6.2 Tashqi kalit TRUNCATE'ni to'xtatadi
- 7. SQL qadami: tahrir va o'chirish so'rovlari (holat 15, commit yo'q)
- 8. Ko'p uchraydigan xatolar
- 9. Mashqlar
- 1-mashq (oson): natijani toping
- 2-mashq (o'rta): Sardorning mashinasi
- 3-mashq (qiyin): Bekzodning bajarilganlari
- 10. Real ishda
- Xulosa
- Manbalar
SQL UPDATE va DELETE: ma'lumotni xavfsiz o'zgartirish va o'chirish
Qisqacha:
UPDATE jadval SET ustun = qiymat WHERE shartqatorlarni o'zgartiradi,DELETE FROM jadval WHERE shart— o'chiradi.WHEREni unutsangiz — butun jadval o'zgaradi. Xavfsiz odat: avval xuddi shuWHEREbilanSELECTqiling, keyinBEGINichida o'zgartiring,RETURNINGbilan natijani ko'ring va faqat to'g'ri bo'lsaCOMMIT— aks holdaROLLBACK. Boshqa jadvalga qarab o'zgartirish —UPDATE … FROMvaDELETE … USING; jadvalni butunlay bo'shatish —TRUNCATE.
Bu darsda
UPDATE … SETbilan bir yoki bir necha ustunni o'zgartirasiz, ifoda ishlatasiz.DELETEbilan qator o'chirasiz vaCASCADEzanjirini eslab qolasiz.- "SELECT → BEGIN → RETURNING → COMMIT/ROLLBACK" xavfsiz tartibini odat qilasiz.
UPDATE … FROMvaDELETE … USINGbilan boshqa jadval ma'lumotiga qarab o'zgartirasiz.TRUNCATEvaDELETEfarqini, tashqi kalit bilan bog'liq tuzog'ini bilasiz.
Oldin bilishingiz kerak: SELECT va WHERE, INSERT va RETURNING, Foreign key va referential actions.
1. Nega bu kerak?
Vazifa bajarildi — bajarildi ni true qilish kerak. Foydalanuvchi matnni tahrirladi — matn o'zgaradi. Vazifa o'chirildi — qator ketadi. Har ilovada bu uch amal har kuni minglab marta bajariladi.
Lekin UPDATE va DELETE — SQL'ning eng xavfli buyruqlari. SELECT noto'g'ri bo'lsa — noto'g'ri natija ko'rasiz, xolos. UPDATE noto'g'ri bo'lsa — ma'lumot buziladi. Va psql "ishonchingiz komilmi?" deb so'ramaydi.
Dasturchilar orasida mashhur hikoya bor. Kimdir ishlab turgan (production) bazada yozadi:
UPDATE foydalanuvchilar SET parol = '...'…va WHERE id = 5 ni yozishga ulgurmay Enter'ni bosadi. Hamma foydalanuvchining paroli bir xil bo'lib qoladi. Bu hikoya har yili kimningdir boshidan o'tadi.
O'xshatish: jarroh. Yaxshi jarroh operatsiyadan oldin uch marta tekshiradi: bemor shumi, qaysi tomon, nima qilinadi. SQL'da ham shunday "tekshiruv ro'yxati" bor. Bu dars — o'sha ro'yxat.
2. UPDATE asoslari
2.1 SET va WHERE
Bu darsdagi hamma misol holat 15 bazasida, BEGIN … ROLLBACK ichida — baza o'zgarmaydi. Biz ishga tushirdik (PG 17.6, Windows 11):
BEGIN;
UPDATE vazifalar
SET matn = matn || ' #shoshilinch', bajarildi = false
WHERE id = 29
RETURNING id, matn, bajarildi;Natija:
BEGIN
id | matn | bajarildi
----+----------------------------------+-----------
29 | Gaz to'lovi #to'lov #shoshilinch | f
(1 row)
UPDATE 1Qismlar:
| Qism | Ma'nosi |
|---|---|
UPDATE vazifalar |
Qaysi jadval |
SET matn = …, bajarildi = false |
Qaysi ustunlar va yangi qiymatlar (vergul bilan) |
WHERE id = 29 |
Qaysi qatorlar |
RETURNING … |
O'zgargan qatorning yangi holati |
matn || ' #shoshilinch' — || matnlarni ulaydi. O'ng tomondagi matn — eski qiymat. Ya'ni SET ifodalari o'zgarishdan oldingi qatorni ko'radi. Shuning uchun SET a = b, b = a ikki ustunni almashtiradi — JavaScript'dagidan farqli, vaqtinchalik o'zgaruvchi kerak emas.
UPDATE 1 — psql holati: 1 qator o'zgardi.
Qisqa misol: holatni teskarisiga almashtirish (NOT). Biz ishga tushirdik (PG 17.6):
BEGIN;
UPDATE vazifalar SET bajarildi = NOT bajarildi
WHERE id IN (1, 2) RETURNING id, bajarildi;
ROLLBACK;Natija:
BEGIN
id | bajarildi
----+-----------
1 | t
2 | f
(2 rows)
UPDATE 2
ROLLBACKBu — ilovadagi "belgilash" tugmasi (checkbox) bazada.
2.2 Hech narsa topilmasa — xato emas
Biz ishga tushirdik (PG 17.6):
UPDATE vazifalar SET bajarildi = true WHERE id = 999;Natija:
UPDATE 0999-vazifa yo'q, lekin xato ham yo'q — nol qator o'zgardi. Ilova uchun bu muhim signal: PATCH /vazifalar/999 so'rovida UPDATE 0 bo'lsa, server 404 Not Found qaytarishi kerak (25-qism, Xato javoblari). Node'da bu son rowCount deb keladi (node-postgres asoslari).
2.3 Cheklovlar UPDATE'da ham ishlaydi
CREATE TABLE darsidagi CHECK lar faqat INSERT ni emas, UPDATE ni ham tekshiradi. Biz ishga tushirdik (PG 17.6) — Dilnozaning hamma vazifasi matnini bo'shatishga urinish:
UPDATE vazifalar SET matn = '' WHERE egasi_id = 2;Natija:
ERROR: new row for relation "vazifalar" violates check constraint "vazifalar_matn_check"
DETAIL: Failing row contains (5, 2, , t, 2026-10-02 02:00:00+00).Tarjimasi: "vazifalar jadvalidagi yangi qator vazifalar_matn_check ni buzadi". UPDATE uchun ham "yangi qator" deyilgani bejiz emas: PostgreSQL'da UPDATE aslida qatorning yangi nusxasini yozadi (bu haqda MVCC darsida). Dilnozaning 6 vazifasidan birinchisi (id 5) buzilishi bilanoq butun UPDATE bekor bo'ldi — hech qaysi qator o'zgarmadi.
Tekshirib ko'ring:
UPDATE vazifalar SET bajarildi = true WHERE egasi_id = 1 AND bajarildiqancha qator o'zgartiradi va natija nima beradi?
Javob
Azizning 4 ta bajarilgan vazifasi — UPDATE 4. Lekin hech narsa amalda o'zgarmaydi: ular allaqachon true. PostgreSQL baribir 4 qatorni qayta yozadi. Shuning uchun WHERE ga AND NOT bajarildi qo'shish foydali — keraksiz yozuv bo'lmaydi va UPDATE N haqiqiy o'zgarishlar sonini ko'rsatadi.
3. DELETE asoslari
3.1 Qator o'chirish
DELETE FROM vazifalar WHERE id = 29;Sintaksis UPDATE dan ham sodda: qaysi jadval va qaysi qatorlar. RETURNING ham bor — o'chirilgan qatorlar ko'rinadi.
3.2 CASCADE'ni eslang
Foreign key darsida vazifalar_egasi_id_fkey ni ON DELETE CASCADE bilan yaratdik. Foydalanuvchi o'chirilsa nima bo'lishini ko'ramiz. Biz ishga tushirdik (PG 17.6, BEGIN … ROLLBACK ichida):
BEGIN;
DELETE FROM foydalanuvchilar
WHERE email = 'aziz@example.com'
RETURNING id, ism;
SELECT count(*) AS qolgan_vazifalar FROM vazifalar;
ROLLBACK;Natija:
BEGIN
id | ism
----+--------------
1 | Aziz Karimov
(1 row)
DELETE 1
qolgan_vazifalar
------------------
31
(1 row)
ROLLBACKDELETE 1 — "bitta qator". Haqiqatda esa 10 qator ketdi: Aziz va uning 9 vazifasi (40 − 9 = 31). RETURNING ham faqat foydalanuvchini ko'rsatdi. O'chirishdan oldin "bu qator kimlarni o'zi bilan olib ketadi?" deb o'ylang.
4. Xavfsiz o'zgartirish tartibi
4.1 To'rt qadam
flowchart TD
A["1. SELECT ... WHERE<br/>nima o'zgaradi?"] --> B["2. BEGIN"]
B --> C["3. UPDATE/DELETE ... WHERE<br/>RETURNING"]
C --> D{"Son va qatorlar<br/>kutilgandekmi?"}
D -->|ha| E["COMMIT"]
D -->|yo'q| F["ROLLBACK"]Diagrammadagi tarmoqlanishga qarang: COMMIT faqat tekshiruvdan keyin. Kanon (PostgreSQL 18.6) bu tartibni Azizning #o'qish vazifalarida ko'rsatadi.
1-qadam — avval ko'rish. O'zgartiradigan WHERE ni avval SELECT bilan ishga tushiring:
SELECT id, matn, bajarildi FROM vazifalar
WHERE egasi_id = 1 AND matn LIKE '%#o''qish%';Natija:
id | matn | bajarildi
----+--------------------------------------------------+-----------
1 | JavaScript kursining 26-qismini boshlash #o'qish | f
2 | Postgres'ni Docker'da ko'tarish #o'qish #docker | t
34 | SQL JOIN mashqlarini yechish #o'qish | f
(3 rows)3 ta qator. Bu son yodda qolsin.
2–3-qadam — tranzaksiyada o'zgartirish. SELECT ni UPDATE ga aylantiramiz, WHERE ni o'zgartirmasdan nusxa olamiz:
BEGIN;
UPDATE vazifalar SET bajarildi = true
WHERE egasi_id = 1 AND matn LIKE '%#o''qish%'
RETURNING id, bajarildi;Natija:
BEGIN
id | bajarildi
----+-----------
1 | t
2 | t
34 | t
(3 rows)
UPDATE 34-qadam — qaror. UPDATE 3 — SELECT dagi 3 ga teng, qatorlar o'sha. Kutilgandek bo'lsa — COMMIT;. Son boshqacha bo'lsa (masalan UPDATE 40) — ROLLBACK; va hech narsa o'zgarmaydi. Kanon bu darsda ROLLBACK qildi — baza o'z holida qolishi uchun.
Tranzaksiya (transaction) — BEGIN dan COMMIT gacha bo'lgan buyruqlar guruhi: ular yo hammasi birga saqlanadi, yo hammasi birga bekor bo'ladi. COMMIT dan oldin o'zgarishlarni faqat siz ko'rasiz, boshqa ulanishlar — eski holatni. To'liq nazariyasi — Tranzaksiya asoslari.
4.2 WHERE unutilsa
Endi hikoyadagi xatoni ataylab qilamiz, lekin tranzaksiya ichida. Biz ishga tushirdik (PG 17.6):
BEGIN;
UPDATE vazifalar SET bajarildi = false;
SELECT count(*) AS bajarilganlar FROM vazifalar WHERE bajarildi;
ROLLBACK;
SELECT count(*) AS bajarilganlar FROM vazifalar WHERE bajarildi;Natija:
BEGIN
UPDATE 40
bajarilganlar
---------------
0
(1 row)
ROLLBACK
bajarilganlar
---------------
20
(1 row)UPDATE 40 — hamma qator. Tranzaksiya ichida 20 ta bajarilgan vazifa yo'qoldi. ROLLBACK dan keyin — 20 tasi joyida. Tranzaksiyasiz yozilgan bo'lsa, ularni faqat zaxiradan (backup) tiklash mumkin edi — agar zaxira bo'lsa.
UPDATE N dagi N — eng birinchi tekshiruvingiz. 1 ta qatorni o'zgartirmoqchi edingiz-u, 40 ko'rsatsa — to'xtang.
4.3 Xato tranzaksiyani "buzadi"
Tranzaksiya ichida bitta xato bo'lsa, qolgan buyruqlar bajarilmaydi. Biz ishga tushirdik (PG 17.6):
BEGIN;
UPDATE vazifalar SET bajarildi = true WHERE id = 1;
SELECT 1/0;
UPDATE vazifalar SET bajarildi = true WHERE id = 2;
COMMIT;Natija:
BEGIN
UPDATE 1
ERROR: division by zero
ERROR: current transaction is aborted, commands ignored until end of transaction block
ROLLBACKTarjimasi: "joriy tranzaksiya bekor qilingan, tranzaksiya bloki oxirigacha buyruqlar e'tiborsiz qoldiriladi". E'tibor bering: biz COMMIT yozdik, psql esa ROLLBACK deb javob berdi. Xatodan keyin COMMIT ham bekor qilishga aylanadi — birinchi UPDATE ham saqlanmadi. Bu "hammasi yoki hech biri" qoidasi amalda.
Maslahat: psql'da
\set AUTOCOMMIT offyozsangiz, har buyruq avtomatik tranzaksiyada boshlanadi va sizCOMMITyozmaguningizcha saqlanmaydi. Production bazaga qo'lda ulanadigan ba'zi jamoalar shu sozlamani.psqlrcga qo'yadi (psql chuqur). Ehtiyot bo'ling: unutilgan ochiq tranzaksiya qatorlarni qulflab, boshqalarni kuttirib qo'yishi mumkin (Qulflar).
Tekshirib ko'ring: Tranzaksiya ichida
UPDATEqildingiz vaCOMMITdan oldin boshqa terminaldanSELECTqildingiz. Ikkinchi terminal nimani ko'radi?
Javob
Eski qiymatni. COMMIT qilinmagan o'zgarish faqat shu tranzaksiyaga ko'rinadi:
| Qadam | A terminal | B terminal | B ko'radigan bajarildi (id 29) |
|---|---|---|---|
| 1 | BEGIN; |
— | t |
| 2 | UPDATE … SET bajarildi = false WHERE id = 29; |
— | — |
| 3 | — | SELECT bajarildi … WHERE id = 29; |
t (eski) |
| 4 | COMMIT; |
— | — |
| 5 | — | xuddi shu SELECT |
f (yangi) |
Bu jadval PostgreSQL'ning sukut izolyatsiya darajasidagi (READ COMMITTED) xatti-harakati — hujjatga ko'ra; ikki terminalli tajribani Read phenomena va izolyatsiya darajalari darsida o'zimiz o'tkazamiz. Shuning uchun tranzaksiya ichida bemalol tekshirsangiz bo'ladi — foydalanuvchilar yarim tayyor holatni ko'rmaydi.
5. Boshqa jadvalga qarab o'zgartirish
5.1 UPDATE … FROM
Savol: "Bekzodning hamma bajarilmagan vazifalarini bajarilgan qil". Bizda email bor (bekzod@example.com), vazifalar da esa faqat egasi_id. Ikki jadvalni bitta buyruqda bog'lash kerak. PostgreSQL'da buning uchun UPDATE … FROM. Kanon (PostgreSQL 18.6, ROLLBACK bilan):
BEGIN;
UPDATE vazifalar v
SET bajarildi = true
FROM foydalanuvchilar f
WHERE f.id = v.egasi_id
AND f.email = 'bekzod@example.com'
AND NOT v.bajarildi
RETURNING v.id, v.matn;
ROLLBACK;Natija:
BEGIN
id | matn
----+-------------------------------
19 | Universitet kontrakti #to'lov
33 | Noutbukka SSD qo'yish #ta'mir
(2 rows)
UPDATE 2
ROLLBACKO'qilishi:
vazifalar v,foydalanuvchilar f— jadvallarga qisqa nom (v,f). Endiv.bajarildi— "vazifalardagibajarildi".FROM foydalanuvchilar f— o'zgartirishda qo'shimcha jadval ishtirok etadi.WHERE f.id = v.egasi_id— bog'lash sharti: har vazifani o'z egasi bilan juftlaydi. Bu eng muhim qator.- Qolgan shartlar — kerakli juftliklarni tanlaydi.
Diqqat: Bog'lash shartini (
f.id = v.egasi_id) unutsangiz, har vazifa har foydalanuvchi bilan juftlanadi. Bekzod qatori bor ekan, hamma vazifalar shartga mos keladi — butun jadval o'zgaradi.WHEREsizUPDATEning yashirin ko'rinishi. Tekshiruv usuli o'sha: avval xuddi shuFROM … WHEREbilanSELECT.
Bu ikki jadvalni bog'lash g'oyasi — JOIN'lar darsining mavzusi. UPDATE … FROM — PostgreSQL kengaytmasi; MySQL'da UPDATE … JOIN deb yoziladi.
5.2 DELETE … USING
DELETE da xuddi shu g'oya USING deb ataladi. Kanon (PostgreSQL 18.6, ROLLBACK bilan) — Gulnoraning bajarilgan vazifalari:
BEGIN;
DELETE FROM vazifalar v
USING foydalanuvchilar f
WHERE f.id = v.egasi_id
AND f.email = 'gulnora@example.com'
AND v.bajarildi
RETURNING v.id, v.matn;
ROLLBACK;Natija:
BEGIN
id | matn
----+-----------------------------------------
4 | Somsa uchun xamir tayyorlash #oshxona
22 | Un va yog' xarid qilish #bozor #oshxona
(2 rows)
DELETE 2
ROLLBACKNega FROM emas, USING? DELETE FROM da FROM so'zi band — u o'chiriladigan jadvalni bildiradi. Ikkinchi jadval uchun boshqa so'z kerak bo'lgan.
PostgreSQL 18 da RETURNING ga old. va new. qo'shildi: UPDATE … RETURNING old.matn, new.matn bitta so'rovda "nima edi — nima bo'ldi" ni beradi. Mashinadagi 17.6 da bu yo'q, biz sinamadik — hujjat bo'yicha (postgresql.org/docs/18, UPDATE, 2026-10-24).
6. TRUNCATE: jadvalni bo'shatish
6.1 TRUNCATE va DELETE farqi
TRUNCATE jadval — butun jadvalni bir zumda bo'shatadi. Kanon (PostgreSQL 18.6, ROLLBACK bilan):
BEGIN;
TRUNCATE vazifalar;
SELECT count(*) FROM vazifalar;
ROLLBACK;
SELECT count(*) AS hammasi_joyida FROM vazifalar;Natija:
BEGIN
TRUNCATE TABLE
count
-------
0
(1 row)
ROLLBACK
hammasi_joyida
----------------
40
(1 row)PostgreSQL'da TRUNCATE ham tranzaksiyali — ROLLBACK uni qaytardi. (MySQL'da va boshqa ba'zi bazalarda bunday emas.)
DELETE FROM t |
TRUNCATE t |
|
|---|---|---|
WHERE |
bor | yo'q — faqat hammasi |
RETURNING |
bor | yo'q |
| Tezlik katta jadvalda | sekin (har qator alohida) | juda tez (fayl almashtiriladi) |
| Qator trigger'lari | ishlaydi | ishlamaydi |
| Qulf | qatorlarga | butun jadvalga (o'qish ham kutadi) |
| ID hisoblagichi | o'zgarmaydi | RESTART IDENTITY bilan noldan |
Biz ishga tushirdik (PG 17.6, ROLLBACK bilan) — RESTART IDENTITY:
BEGIN;
TRUNCATE vazifalar RESTART IDENTITY;
INSERT INTO vazifalar (egasi_id, matn)
VALUES (1, 'Yangi boshlanish') RETURNING id;
ROLLBACK;Natija:
BEGIN
TRUNCATE TABLE
id
----
1
(1 row)
INSERT 0 1
ROLLBACKYangi vazifa yana 1-raqamni oldi. Sinov bazasini tozalash uchun qulay. Production'da TRUNCATE — deyarli hech qachon kerak emas.
6.2 Tashqi kalit TRUNCATE'ni to'xtatadi
Kanon (PostgreSQL 18.6):
TRUNCATE foydalanuvchilar;Natija:
ERROR: cannot truncate a table referenced in a foreign key constraint
DETAIL: Table "vazifalar" references "foydalanuvchilar".
HINT: Truncate table "vazifalar" at the same time, or use TRUNCATE ... CASCADE.Tarjimasi: "tashqi kalit ishora qilayotgan jadvalni bo'shatib bo'lmaydi. Vazifalar foydalanuvchilarga ishora qiladi. Maslahat: vazifalarni ham birga bo'shating yoki TRUNCATE … CASCADE ishlating".
TRUNCATE qatorma-qator ishlamaydi, shuning uchun ON DELETE CASCADE ni bajara olmaydi. U shunchaki rad etadi. TRUNCATE … CASCADE esa bog'langan hamma jadvallarni bo'shatadi — uni faqat aniq bilganingizda ishlating.
7. SQL qadami: tahrir va o'chirish so'rovlari (holat 15, commit yo'q)
Sxema o'zgarmaydi. 25-qism dagi PATCH /vazifalar/:id va DELETE /vazifalar/:id bazada shunday ko'rinadi:
-- PATCH: faqat o'z vazifasini, yangi holatni qaytarib
UPDATE vazifalar
SET bajarildi = true
WHERE id = 34 AND egasi_id = 1
RETURNING id, matn, bajarildi;
-- DELETE: faqat o'z vazifasini
DELETE FROM vazifalar
WHERE id = 34 AND egasi_id = 1
RETURNING id;AND egasi_id = 1 ga qarang. Bu — resurs egaligi tekshiruvi. Usiz Aziz id ni o'zgartirib, Dilnozaning vazifasini o'chira olardi. Ikkala shart bitta WHERE da — alohida "avval o'qib tekshir, keyin o'chir" kerak emas. RETURNING bo'sh qaytsa (DELETE 0), ilova 404 beradi: "bunday vazifa yo'q" — va begona vazifa bormi-yo'qmi, oshkor qilinmaydi. Haqiqiy egasi_id autentifikatsiyadan keladi (28-qism); ungacha biz uni qo'lda yozamiz. Repository kodi — Parametrli so'rovlar darsida.
8. Ko'p uchraydigan xatolar
| Xato yoki belgi | Sabab | Davosi |
|---|---|---|
UPDATE 40 (1 ta kutilgan) |
WHERE unutilgan |
BEGIN ichida; ROLLBACK |
UPDATE … FROM butun jadvalni o'zgartirdi |
Bog'lash sharti yo'q | WHERE f.id = v.egasi_id |
UPDATE 0 |
Shartga mos qator yo'q | Xato emas — ilovada 404 |
current transaction is aborted … |
Tranzaksiyada oldinroq xato bo'lgan | ROLLBACK va qaytadan |
COMMIT dan keyin ROLLBACK chiqdi |
Tranzaksiyada xato bo'lgan | Xatoni tuzatib qayta bajaring |
cannot truncate a table referenced in a foreign key constraint |
Boshqa jadval ishora qiladi | Ikkalasini birga yoki DELETE |
DELETE 1, lekin ko'p narsa yo'qoldi |
ON DELETE CASCADE |
O'chirishdan oldin bog'lanishlarni tekshiring |
9. Mashqlar
1-mashq (oson): natijani toping
Holat 15 (40 vazifa, 20 tasi bajarilgan).
UPDATE vazifalar SET bajarildi = true WHERE id = 500holat qatori:UPDATEBEGIN; DELETE FROM vazifalar; ROLLBACK;dan keyin vazifalar soni:UPDATE t SET a = b, b = adan keyinaning qiymati — eski- Jadvalni bo'shatib, ID'ni ham 1 dan boshlash:
TRUNCATE vazifalar
Yechim
- 0 — mos qator yo'q, xato emas.
- 40 —
ROLLBACKhammasini qaytardi. - b —
SETifodalari o'zgarishdan oldingi qatorni ko'radi, shuning uchun ikkalasi almashadi. - RESTART IDENTITY — sinov bazalari uchun.
2-mashq (o'rta): Sardorning mashinasi
Sardor (sardor@example.com) mashinaga oid (#mashina tegli) hamma ishni tugatdi. Xavfsiz tartibda bajaring: avval SELECT bilan ko'ring, keyin tranzaksiyada UPDATE … FROM (faqat bajarilmaganlar), RETURNING, COMMIT. Sardorning id sini qo'lda yozmang.
Yechim
-- 1) avval ko'rish
SELECT v.id, v.matn, v.bajarildi
FROM vazifalar v, foydalanuvchilar f
WHERE f.id = v.egasi_id
AND f.email = 'sardor@example.com'
AND v.matn LIKE '%#mashina%'
ORDER BY v.id;
-- 2) tranzaksiyada o'zgartirish
BEGIN;
UPDATE vazifalar v
SET bajarildi = true
FROM foydalanuvchilar f
WHERE f.id = v.egasi_id
AND f.email = 'sardor@example.com'
AND v.matn LIKE '%#mashina%'
AND NOT v.bajarildi
RETURNING v.id, v.matn, v.bajarildi;
COMMIT;Natija (biz ishga tushirdik, PG 17.6, psql -q — holat qatorlari yashirin):
id | matn | bajarildi
----+------------------------------------------------+-----------
10 | Mashinani texnik ko'rikka olib borish #mashina | f
11 | Moy almashtirish #mashina | t
(2 rows)
id | matn | bajarildi
----+------------------------------------------------+-----------
10 | Mashinani texnik ko'rikka olib borish #mashina | t
(1 row)SELECT 2 qator ko'rsatdi, UPDATE — 1 qator. Bu xato emas: AND NOT v.bajarildi allaqachon bajarilganini (11) o'tkazib yubordi. Farqni oldindan tushunib, keyin COMMIT qilish — aynan xavfsiz tartibning maqsadi. SELECT dagi FROM vazifalar v, foydalanuvchilar f — INSERT va RETURNING darsining 3-mashqidagi juftlash usuli.
3-mashq (qiyin): Bekzodning bajarilganlari
Bekzod (bekzod@example.com) bajarilgan vazifalarini tozalamoqchi. Bitta tranzaksiyada: DELETE … USING bilan o'chiring va o'chirilganlarni ko'rsating, so'ng Bekzodning qolgan vazifalarini (egasi_id 7) chiqarib, faqat bajarilmaganlar qolganini tekshiring, keyin COMMIT.
Yechim
BEGIN;
DELETE FROM vazifalar v
USING foydalanuvchilar f
WHERE f.id = v.egasi_id
AND f.email = 'bekzod@example.com'
AND v.bajarildi
RETURNING v.id, v.matn;
-- tekshiruv: Bekzodda faqat bajarilmaganlar qoldimi?
SELECT id, matn, bajarildi
FROM vazifalar
WHERE egasi_id = 7
ORDER BY id;
COMMIT;Natija (biz ishga tushirdik, PG 17.6, psql -q):
id | matn
----+----------------------------------
25 | Algoritmlar: 5 ta masala #o'qish
39 | Do'stlar bilan choyxona #dam
(2 rows)
id | matn | bajarildi
----+-------------------------------+-----------
19 | Universitet kontrakti #to'lov | f
33 | Noutbukka SSD qo'yish #ta'mir | f
(2 rows)Bekzodda 4 ta vazifa bor edi: 2 tasi o'chdi, 2 tasi (bajarilmagan) qoldi. Tekshiruv COMMIT dan oldin, tranzaksiya ichida — natija noto'g'ri bo'lsa, COMMIT o'rniga ROLLBACK yozasiz.
10. Real ishda
- Ilova kodi —
UPDATE … WHERE id = $1 AND egasi_id = $2 RETURNING …— tahrir va o'chirishning standart shakli;rowCount = 0→ 404. - Qo'lda tuzatish (hotfix) — production bazada qo'lda SQL yozish kerak bo'lsa, tajribali jamoalarda qoida: ikkinchi odam ko'rib chiqadi,
BEGINichida,RETURNINGbilan, oldin zaxira. Ba'zi kompaniyalarda production'ga to'g'ridan-to'g'ri yozish umuman taqiqlangan — faqat migratsiya fayllari orqali. - "O'chirish" ko'pincha
UPDATE— foydalanuvchi "o'chirdim" degan vazifa aslidaochirilgan_vaqtustuni bilan yashiriladi (yumshoq o'chirish, "Savat"). Buni Soft delete, timestamps va tarix darsida quramiz. - Intervyu savollari: "
DELETEvaTRUNCATEfarqi?", "WHEREsizUPDATEni qanday oldini olasiz?", "UPDATEboshqa jadval ma'lumotiga qarab qanday yoziladi?".
Xulosa
UPDATE t SET a = …, b = … WHERE …vaDELETE FROM t WHERE …;SETifodalari eski qatorni ko'radi.- Xavfsiz tartib: avval
SELECT(son),BEGIN, o'zgartirish +RETURNING, son mos bo'lsaCOMMIT, aks holdaROLLBACK. UPDATE 0— xato emas (ilovada 404); cheklovlarUPDATEni ham tekshiradi; tranzaksiyadagi xatoCOMMITniROLLBACKga aylantiradi.UPDATE … FROMvaDELETE … USING— boshqa jadvalga qarab; bog'lash shartini unutmang.DELETE+CASCADEjim zanjir;TRUNCATE— tez,WHEREsiz, tashqi kalit bilan bog'langan jadvalda rad etiladi.- Ilovada egalik tekshiruvi
WHERE id = … AND egasi_id = …bilan bitta so'rovda.
Keyingi dars: NULL mantiqi — NULL nega "noma'lum", uch qiymatli mantiq, IS DISTINCT FROM, COALESCE va NOT IN ning mashhur tuzog'i.
Manbalar
- PostgreSQL 18 hujjati — UPDATE (
FROM,RETURNING old/new) - PostgreSQL 18 hujjati — DELETE (
USING) - PostgreSQL 18 hujjati — TRUNCATE (
RESTART IDENTITY,CASCADE, MVCC-xavfsiz emasligi) - PostgreSQL 18 hujjati — psql: AUTOCOMMIT
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!