Ачааллж байна...
Өмнөх хичээлд бид INSERT-ээр шинэ мөр нэмж сурсан. Гэвч өгөгдөл зөвхөн нэмэгддэггүй, бас өөрчлөгддөг. Номын санд нэг номын шинэ хувь ирж хувийн тоо нэмэгдэнэ, гишүүн өөр хот руу нүүнэ, бүртгэлд гарсан үсгийн алдааг засна. Байгаа мөрийн утгыг өөрчлөх тушаал бол UPDATE юм. FastAPI сургалтын засах endpoint дээр та объектын талбарыг өөрчлөөд session.commit() хийдэг байсан — ар талд нь яг энэ тушаал ажиллаж байсан.
UPDATE-ийн бичлэг энгийн бөгөөд та үүнийг хэдхэн минутад эзэмшинэ. Энэ хичээлийн жинхэнэ сэдэв бол бичлэг биш, харин нэг аюул юм. UPDATE нь өөрчлөх мөрүүдээ сонгохдоо WHERE-ийг ашигладаг бөгөөд хэрэв WHERE-ийг мартвал хүснэгтийн бүх мөрийг өөрчилдөг. Үүнийг хийхэд SQLite ямар ч алдааны мессеж өгөхгүй, "та итгэлтэй байна уу" гэж ч асуухгүй — зүгээр л гүйцэтгэнэ. Энэ бол Бүлэг 1-ээс хойш хэд хэдэн удаа дурдсан "алдаагүй гамшиг"-ийн хамгийн аюултай хэлбэр юм.
Бид энэ гамшгийг үгээр тайлбарлахын оронд өөрсдөө үүсгэнэ — гэхдээ хаях хуулбар дээр, жинхэнэ өгөгдөлдөө хүрэлгүйгээр. Өөрийн нүдээр харсан гамшиг нь уншсан анхааруулгаас хамаагүй удаан санагддаг. Дараа нь мэргэжлийн хөгжүүлэгчид өдөр бүр хэрэглэдэг энгийн хамгаалалтын дадлыг сурна: эхлээд SELECT, дараа нь UPDATE.
UPDATE бол бүртгэлийн дэвтэрт байгаа бичилтийг баллуураар арилгаад шинээр бичих үйлдэл юм. Номын санчид “3-р мөрийн номын хувийн тоог 2 болго” гэж хэлбэл тэр яг тэр нэг нүдийг засна. Харин "хувийн тоог 2 болго" гэж аль мөр болохыг хэлэлгүй тушаавал хэт хичээнгүй номын санч дэвтрийн бүх мөрийн хувийн тоог 2 болгож засна. Тэр таныг буруу ойлгоогүй — та яг тэгж хэлсэн.
UPDATE-ийн WHERE бол "аль мөрийг" гэсэн тэр чухал хэсэг юм. SELECT-ийн үед WHERE-ийг мартвал зүгээр л илүү олон мөр харагддаг — хор хөнөөлгүй. UPDATE-ийн үед WHERE-ийг мартвал баллуур дэвтрийн бүх хуудсаар явна. Мөн баллуурдсан бичилт буцаж ирэхгүй: хуучин утгыг хаана ч хадгалаагүй бол түүнийг сэргээх арга байхгүй.
Энэ хичээлд бид books хүснэгтэд огт хүрэхгүй. Үүний оронд түүний яг хуулбарыг үүсгээд, бүх туршилтаа тэр хуулбар дээр хийнэ. Execute SQL табд дараах тушаалыг ажиллуулаарай:
sql
CREATE TABLE books_practice AS SELECT * FROM books;Энэ тушаал юу гэж хэлж байна вэ гэвэл: “books хүснэгтийн бүх мөр, бүх баганыг уншаад, тэр үр дүнгээр books_practice гэсэн шинэ хүснэгт үүсгэ.” CREATE TABLE-ийн тухай Бүлэг 4-т бүрэн ярих тул одоохондоо энэ мөрийг "хуулбар хийх бэлэн тушаал" гэж хүлээн авахад хангалттай. Database Structure таб руу ороход books, members-ийн хажууд books_practice гэсэн гурав дахь хүснэгт гарч ирсэн байна. Энэ хүснэгт одоогоор books-тэй яг ижил зургаан мөртэй.
Хоёр дахь хамгаалалт ч бий: энэ хичээлийн турш Write Changes дарахгүй. Ингэснээр бүх өөрчлөлт маань хадгалагдаагүй хэвээр байх бөгөөд хичээлийн төгсгөлд Revert Changes дарж бүгдийг арилгаж болно. Гэхдээ энэ хамгаалалт зөвхөн DB Browser-т л бий гэдгийг анхаараарай. Python-оос эсвэл PostgreSQL-ийн psql-ээс ажиллуулсан UPDATE ихэвчлэн тэр даруй бүрмөсөн хадгалагддаг бөгөөд тэнд Revert Changes товч байхгүй. Тиймээс энэ хичээлийн дадал "буцаах товч байхгүй" гэж үзэн ажиллахад зориулагдсан.
Бидний books_practice хүснэгт UPDATE-ээс өмнө:
id | title | author | year | genre | copies
---+--------------------------+------------------+------+-------------+-------
1 | Монголын нууц товчоо | NULL | 1240 | Түүх | 2
2 | Тунгалаг Тамир | Ч.Лодойдамба | 1962 | Роман | 3
3 | Учиртай гурван толгой | Д.Нацагдорж | 1934 | Жүжиг | 1
4 | Clean Code | Robert C. Martin | 2008 | Програмчлал | 4
5 | Python Crash Course | Eric Matthes | 2015 | Програмчлал | 5
6 | The Pragmatic Programmer | Andrew Hunt | 1999 | Програмчлал | 2"Учиртай гурван толгой"-н хоёр шинэ хувь ирж, нийт гурван хувьтай боллоо. Query:
sql
UPDATE books_practice
SET copies = 3
WHERE id = 3;Мессежийн талбарт 1 rows affected гэж гарна. Хүснэгт UPDATE-ийн дараа:
id | title | author | year | genre | copies
---+--------------------------+------------------+------+-------------+-------
1 | Монголын нууц товчоо | NULL | 1240 | Түүх | 2
2 | Тунгалаг Тамир | Ч.Лодойдамба | 1962 | Роман | 3
3 | Учиртай гурван толгой | Д.Нацагдорж | 1934 | Жүжиг | 3
4 | Clean Code | Robert C. Martin | 2008 | Програмчлал | 4
5 | Python Crash Course | Eric Matthes | 2015 | Програмчлал | 5
6 | The Pragmatic Programmer | Andrew Hunt | 1999 | Програмчлал | 2Энэ query юу гэж хэлж байна вэ гэвэл: “books_practice хүснэгтэд id нь 3 байгаа мөрийн copies-ыг 3 болго.” Тушаал гурван хэсэгтэй. UPDATE-ийн араас ямар хүснэгтийг засахыг бичнэ. SET нь "тохируул" гэсэн утгатай бөгөөд араас нь аль баганад ямар утга өгөхийг багана = утга хэлбэрээр бичнэ. Энд байгаа = нь WHERE дахь шиг харьцуулалт биш, харин утга оноох үйлдэл юм — SQL-д нэг тэмдэг байрнаасаа хамаарч хоёр өөр утгатай болдгийн ховор жишээ. WHERE нь өмнөх бүлэгт сурсантай яг ижилээр ажилладаг: мөр бүрийг шалгаж, нөхцөл үнэн гарсан мөрүүдийг л засна.
3-р мөрөөс бусад таван мөр огт өөрчлөгдөөгүйг анзаараарай. Мөн “rows affected” тоо 1 байгаа нь бидний хүлээлттэй таарч байна — бид нэг номыг засахыг хүссэн бөгөөд нэг мөр засагдсан. Энэ тоог шалгах нь UPDATE бүрийн дараа хийх анхны алхам юм. Бид id-аар шүүсэн нь санамсаргүй биш: id бүр давхардахгүй тул WHERE id = 3 нь яг нэг мөртэй таарахыг баталдаг. Нэг тодорхой мөрийг засах үед id-аар шүүх нь хамгийн найдвартай арга юм.
Жишээ 1: нэг дор хэд хэдэн багана засах
“The Pragmatic Programmer” номын 2019 оны шинэчилсэн хэвлэл ирж, хуучнаа сольжээ. Энэ хэвлэлийн хамтран зохиогч David Thomas-ийг ч бүртгэлд нэмье. Хүснэгт дээрхтэй адил (3-р мөр одоо 3 хувьтай). Query:
sql
UPDATE books_practice
SET author = 'Andrew Hunt, David Thomas', year = 2019
WHERE id = 6;Мессеж: 1 rows affected. 6-р мөр UPDATE-ийн өмнө ба дараа:
өмнө:
id | title | author | year | genre | copies
---+--------------------------+---------------------------+------+-------------+-------
6 | The Pragmatic Programmer | Andrew Hunt | 1999 | Програмчлал | 2
дараа:
id | title | author | year | genre | copies
---+--------------------------+---------------------------+------+-------------+-------
6 | The Pragmatic Programmer | Andrew Hunt, David Thomas | 2019 | Програмчлал | 2Энэ query юу гэж хэлж байна вэ гэвэл: “books_practice хүснэгтэд id нь 6 байгаа мөрийн author-ийг ‘Andrew Hunt, David Thomas’, year-ийг 2019 болго.” SET-ийн араас багана = утга хосуудыг таслалаар тусгаарлан хэдийг ч бичиж болно. Нэрлээгүй баганууд (title, genre, copies) хэвээр үлдсэн. Хоёр баганыг заавал нэг UPDATE-ээр засах шаардлагагүй, хоёр тусдаа UPDATE ч мөн адил үр дүн өгнө. Гэхдээ нэг мөрийн холбоотой өөрчлөлтүүдийг нэг тушаалд нэгтгэх нь илүү цэвэрхэн бөгөөд хэрэв нэг нь бүтэлгүйтвэл нөгөө нь ч хийгдэхгүй гэдгийг баталдаг.
Жишээ 2: олон мөрийг тооцоололоор засах
Номын сан програмчлалын ном бүрийн нэг нэмэлт хувь худалдаж авлаа. Энэ удаад бид нэг мөрийг биш, нөхцөлд таарсан бүх мөрийг засах бөгөөд шинэ утгыг тогтмол тоогоор биш, хуучин утгаас тооцоолно. Query:
sql
UPDATE books_practice
SET copies = copies + 1
WHERE genre = 'Програмчлал';Мессеж: 3 rows affected. Хүснэгт UPDATE-ийн өмнө ба дараа (зөвхөн copies багана):
id | title | genre | өмнө | дараа
---+--------------------------+-------------+------+------
1 | Монголын нууц товчоо | Түүх | 2 | 2
2 | Тунгалаг Тамир | Роман | 3 | 3
3 | Учиртай гурван толгой | Жүжиг | 3 | 3
4 | Clean Code | Програмчлал | 4 | 5
5 | Python Crash Course | Програмчлал | 5 | 6
6 | The Pragmatic Programmer | Програмчлал | 2 | 3Энэ query юу гэж хэлж байна вэ гэвэл: “books_practice хүснэгтэд genre нь 'Програмчлал' байгаа мөр бүрийн copies-ыг өөрийнх нь одоогийн утга дээр нэгийг нэмсэн утгаар соль.” copies = copies + 1 гэдэг илэрхийлэл Python-ы copies = copies + 1-тэй яг ижил санаатай: баруун тал нь хуучин утгыг уншиж, зүүн тал руу шинэ утгыг бичдэг. Чухал нь, энэ тооцоолол мөр бүрт тусдаа хийгддэг — Clean Code 4-өөс 5, Python Crash Course 5-аас 6, The Pragmatic Programmer 2-оос 3 болсон. Нэг тушаал гурван өөр шинэ утга үүсгэсэн.
“rows affected” тоо 3 байгаа нь хүснэгтэд програмчлалын гурван ном байгаатай таарч байна. Хэрэв энэ тоо 0 гарсан бол жанрын нэрийг буруу бичсэн (жишээ нь жижиг үсгээр) байх магадлалтай, хэрэв 6 гарсан бол WHERE ажиллаагүй гэсэн аюултай дохио. Энэ тоог үргэлж өөрийн хүлээлттэй харьцуул — энэ бол UPDATE-ийн дараах хамгийн хурдан эрүүл мэндийн шинжилгээ юм.
Жишээ 3: WHERE-гүй UPDATE — гамшгийг өөрийн нүдээр
Одоо энэ хичээлийн гол хэсэг ирлээ. Номын санч "Учиртай гурван толгой"-н бүх хувь засварт явсан тул түүний хувийн тоог 0 болгох гэж байна. Тэр яарч байгаад WHERE мөрийг бичихээ мартжээ. Энэ query-г зөвхөн books_practice хүснэгт дээр ажиллуулаарай. Хүснэгт одоо ийм байна:
id | title | author | year | genre | copies
---+--------------------------+---------------------------+------+-------------+-------
1 | Монголын нууц товчоо | NULL | 1240 | Түүх | 2
2 | Тунгалаг Тамир | Ч.Лодойдамба | 1962 | Роман | 3
3 | Учиртай гурван толгой | Д.Нацагдорж | 1934 | Жүжиг | 3
4 | Clean Code | Robert C. Martin | 2008 | Програмчлал | 5
5 | Python Crash Course | Eric Matthes | 2015 | Програмчлал | 6
6 | The Pragmatic Programmer | Andrew Hunt, David Thomas | 2019 | Програмчлал | 3Query:
sql
UPDATE books_practice
SET copies = 0;Мессежийн талбарт ердийн, тайван мөр гарна: 6 rows affected. Улаан өнгө байхгүй, анхааруулга байхгүй, асуулт байхгүй. Хүснэгт UPDATE-ийн дараа:
id | title | author | year | genre | copies
---+--------------------------+---------------------------+------+-------------+-------
1 | Монголын нууц товчоо | NULL | 1240 | Түүх | 0
2 | Тунгалаг Тамир | Ч.Лодойдамба | 1962 | Роман | 0
3 | Учиртай гурван толгой | Д.Нацагдорж | 1934 | Жүжиг | 0
4 | Clean Code | Robert C. Martin | 2008 | Програмчлал | 0
5 | Python Crash Course | Eric Matthes | 2015 | Програмчлал | 0
6 | The Pragmatic Programmer | Andrew Hunt, David Thomas | 2019 | Програмчлал | 0Энэ query юу гэж хэлж байна вэ гэвэл: “books_practice хүснэгтийн copies-ыг 0 болго.” Өгүүлбэрт "аль мөрийн" гэсэн хэсэг алга. SQL-ийн дүрмээр WHERE байхгүй бол "нөхцөл байхгүй" буюу "бүх мөр" гэсэн утгатай — SELECT-ийн үед ч яг ийм байсан. SQLite таны хэлснийг үнэн зөв гүйцэтгэжээ.
Хоромхон зогсоод энэ үр дүнг бодит нөхцөлд төсөөлөөд үзээрэй. Номын сангийн бүх ном одоо "нэг ч хувь байхгүй" гэж бүртгэгдсэн. Гишүүд сайтаас ямар ч ном захиалж чадахгүй. Хамгийн муу нь, хуучин утгууд — 2, 3, 3, 5, 6, 3 — хаана ч үлдээгүй. Энэ хичээлд бид хүснэгтийн хуулбарыг дээр нь хэвлэж харуулсан тул тэдгээрийг мэдэж байна, бодит амьдралд хэн ч тэгж хэвлэдэггүй. Хэрэв нөөц хуулбар (backup) байхгүй бол тэдгээр тоог сэргээх цорын ганц арга нь номын сангийн тавиур бүрийг гараар дахин тоолох юм. Энэ бол яг ийм шалтгаанаар мэргэжлийн хөгжүүлэгчид WHERE-гүй UPDATE-ээс айдаг бөгөөд backup-ийн тухай Бүлэг 15-д бүтэн хичээл бий.
Энэ үр дүнг хараад нэг юмыг тэмдэглэ: “6 rows affected” гэдэг тоо л таныг аварч чадах цорын ганц дохио байсан. Та нэг номыг засах гэж байсан, тэгэхэд зургаа гэсэн тоо гарвал тэр даруй ямар нэг юм буруу болсныг мэдэх ёстой.
WHERE-гүй UPDATE-ээс хамгаалах хамгийн энгийн бөгөөд хамгийн найдвартай дадал гурван алхамтай. Эхлээд хүснэгтээ буцааж засъя — Жишээ 3-ын гамшиг дараагийн алхмуудад саад болохгүйн тулд энэ мөрийг ажиллуулаарай: UPDATE books_practice SET copies = 3 WHERE id = 3; (бусад мөрүүд 0 хэвээр үлдэнэ, энэ нь зүгээр — бидэнд одоо зөвхөн 3-р мөр хэрэгтэй).
Алхам 1: засах мөрөө SELECT-ээр олох. UPDATE бичихээсээ өмнө ижил WHERE-тэй SELECT бичнэ:
sql
SELECT *
FROM books_practice
WHERE id = 3;Үр дүн:
id | title | author | year | genre | copies
---+-----------------------+-------------+------+-------+-------
3 | Учиртай гурван толгой | Д.Нацагдорж | 1934 | Жүжиг | 3Энэ query юу гэж хэлж байна вэ гэвэл: “books_practice хүснэгтээс id нь 3 байгаа мөрийг бүхэлд нь харуул.” Үр дүнг хараад хоёр асуулт асуу: энэ бол миний засах гэж байгаа мөр мөн үү? Хэдэн мөр ирсэн бэ? Нэг мөр, зөв ном — үргэлжлүүлж болно. Хэрэв тэнд олон мөр ирсэн эсвэл буруу ном ирсэн бол UPDATE хийхээсээ өмнө WHERE-ээ засах боломж танд байна, учир нь SELECT юуг ч өөрчлөөгүй.
Алхам 2: SELECT-ийг UPDATE болгон хувиргах. Шалгасан query-ний эхний хоёр мөрийг (SELECT * болон FROM books_practice) UPDATE books_practice болон SET copies = 0 мөрөөр солино. WHERE мөрөнд огт хүрэхгүй — тэр нь аль хэдийн шалгагдсан:
sql
UPDATE books_practice
SET copies = 0
WHERE id = 3;Мессеж: 1 rows affected. Энэ query юу гэж хэлж байна вэ гэвэл: “books_practice хүснэгтэд id нь 3 байгаа мөрийн copies-ыг 0 болго.”
Алхам 3: “rows affected”-ийг SELECT-ийн мөрийн тоотой харьцуулах. SELECT 1 мөр буцаасан, UPDATE 1 мөрөнд нөлөөлсөн — таарч байна. Хэрэв эдгээр тоо зөрвөл ямар нэг юм буруу болсон бөгөөд хадгалахаасаа өмнө зогсох хэрэгтэй.
Энэ дадлын хүч нь нэг энгийн санаанд оршдог: WHERE-ийг та UPDATE дотор биш, харин аюулгүй SELECT дотор бичиж туршдаг. UPDATE руу зөвхөн шалгагдсан WHERE шилждэг. Олон туршлагатай хөгжүүлэгч UPDATE-ийн WHERE-ийг гараар бичихийг ерөөсөө больж, үргэлж SELECT-ээс хуулж авдаг. Мөн нэмэлт хамгаалалт болгон зарим хүмүүс UPDATE-ийн WHERE мөрийг хамгийн түрүүнд, SET-ээс ч өмнө бичдэг — ингэснээр query бүрэн бичигдэхээс өмнө санамсаргүй ажиллуулсан ч WHERE-гүй үлдэх боломжгүй.
Туршилт дууслаа. Бид Write Changes огт дараагүй тул хэрэгслийн мөрөөс Revert Changes дараад гарч ирэх асуултад зөвшөөрнө. books_practice хүснэгт болон түүн дээр хийсэн бүх өөрчлөлт алга болж, өгөгдлийн сан хичээлийн эхэн дэх байдалдаа буцна. Database Structure табд зөвхөн books болон members үлдсэн эсэхийг шалгаарай. books хүснэгт энэ хичээлийн турш огт өөрчлөгдөөгүй тул эхлэл зургаан номтойгоо хэвээр байна.
Хэрэв сонирхож байвал дасгалын хуулбарыг дахин үүсгээд (CREATE TABLE books_practice AS SELECT * FROM books;), гурван алхамт дадлыг өөр өөрчлөлт дээр давтаж үзээрэй: жишээ нь Улаанбаатарт амьдардаг гишүүд биш, харин 1950 оноос өмнө хэвлэгдсэн номнуудын жанрыг 'Сонгодог' болгох. Эхлээд SELECT-ээр хэдэн ном таарахыг тоол, дараа нь UPDATE хийгээд “rows affected”-тэй харьцуул. Дуусаад Revert Changes дарахаа мартуузай. Эдгээр нь зөвхөн санал бөгөөд дараагийн хичээлүүд тэдгээрийг хийсэн гэж тооцохгүй.
WHERE мартах. Жишээ 3-т харсанчлан алдааны мессеж гарахгүй, зөвхөн “rows affected” тоо хүснэгтийн бүх мөрийн тоотой тэнцүү гарна. Энэ бол энэ хичээлийн гол сургамж бөгөөд түүнээс хамгаалах арга нь эхлээд SELECT, дараа нь UPDATE гэсэн дадал юм.
Query-ний зөвхөн нэг хэсгийг тодруулж ажиллуулах. Бүлэг 1-д бичих талбарт текст тодруулаад F5 дарвал зөвхөн тодруулсан хэсэг ажилладаг гэж сурсан. Хэрэв та гурван мөрт UPDATE-ийн эхний хоёр мөрийг л санамсаргүй тодруулаад F5 дарвал SQLite зөвхөн UPDATE books_practice SET copies = 0 хэсгийг харж, WHERE-гүй UPDATE-ийг гүйцэтгэнэ. Бичих талбарт WHERE мөр харагдаж байгаа ч ажиллаагүй байх болно. UPDATE ажиллуулахын өмнө юу тодорсон байгааг шалгаарай, эсвэл тодруулгагүйгээр бүх талбарыг ажиллуулах дадал гаргаарай.
SET дотор таслалын оронд AND бичих. Хоёр багана засахдаа ярианы хэлээрээ “copies-ыг 6 болго БӨГӨӨД year-ийг 2020 болго” гэж бодоод SET copies = 6 AND year = 2020 гэж бичих нь элбэг. Энэ үед алдааны мессеж гарахгүй, харин аймшигтай үр дүн гарна: SQLite үүнийг “copies-ыг (6 AND year = 2020) гэсэн логик илэрхийллийн утгаар соль” гэж ойлгоод copies-д 0 эсвэл 1 бичнэ, year огт өөрчлөгдөхгүй. SET доторх хосуудыг үргэлж таслалаар тусгаарла: SET copies = 6, year = 2020.
SET-ийн сүүлд илүү таслал. SET copies = 6, WHERE id = 3 гэж бичвэл near "WHERE": syntax error гарна. Энэ мессеж юу гэж хэлж байна вэ гэвэл: “WHERE гэдэг үгийн ойролцоо дүрэм зөрчигдлөө.” SQLite таслалын араас дахин нэг багана = утга хос хүлээж байтал WHERE ирсэн. Энэ нь SELECT болон INSERT-ийн жагсаалтын сүүлийн таслалын алдаатай ижил шалтгаантай.
NULL-ийг =-ээр хайж засах. UPDATE books_practice SET author = 'Тодорхойгүй' WHERE author = NULL гэж бичвэл 0 rows affected гарна. Бүлэг 2-ын NULL-ийн хичээлд сурсанчлан = NULL хэзээ ч юуг ч олдоггүй тул UPDATE нэг ч мөр олсонгүй. WHERE author IS NULL гэж бичих ёстой. Энэ нь эхлээд SELECT хийх дадлын бас нэг давуу тал: SELECT хоосон үр дүн өгсөн бол UPDATE-ийг ажиллуулахаасаа өмнө асуудлыг олно.
Энэ хичээлд та UPDATE ... SET ... WHERE ... тушаалаар байгаа мөрийг засаж сурлаа. SET-ийн араас таслалаар тусгаарласан багана = утга хосууд ирдэг бөгөөд copies = copies + 1 шиг хуучин утгаас тооцоолсон утга ч өгч болно. WHERE нь засах мөрүүдийг сонгодог бөгөөд түүнгүйгээр UPDATE хүснэгтийн бүх мөрийг алдааны мессежгүйгээр өөрчилдгийг та дасгалын хуулбар дээр өөрийн нүдээр харлаа. Хуучин утгууд буцаж ирэхгүй тул хамгаалалт нь урьдчилан сэргийлэх дадал юм: эхлээд ижил WHERE-тэй SELECT ажиллуулж мөрөө шалгах, дараа нь түүнийг UPDATE болгон хувиргах, эцэст нь “rows affected”-ийг SELECT-ийн мөрийн тоотой харьцуулах.
Дараагийн хичээлд бид DELETE-ээр мөр устгаж сурна. Ижил аюул, ижил хамгаалалтын дадал тэнд ч үйлчилнэ, харин үр дагавар нь бүр ч ноцтой: засагдсан мөр ядаж хүснэгтэд үлддэг бол устгагдсан мөр бүрмөсөн алга болдог. Мөн өгөгдлийг сэргээх бодит боломжуудын тухай шударга ярина.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.