MySQL дээр database-ээ анх байгуулахдаа utf8_unicode_ci эсвэл utf8_general_ci энэ хоёрын аль нэгээр хадгалаарай. utf8_general_ci нь арай хурдан боловч utf8_unicode_ci нь илүү тодорхой гэсэн байна. Би програм бичихдээ алийг нь хэрэглэж байснаа мартчихаж.
С хэлээр бичигдэж буй програмаас дээрх монгол кирилл өгөгдөл хадгалагдсан байгаа database-н хүснэгт рүү монгол кирилл үг орсон sql statement явуулах, мөн монгол кирилл үг орсон өгөгдөл авчрах жишээ кодыг тайлбартай нь тавья.
1. Эхний method DB-тэй холбохын тулд тохиргоо хийх method
*5р мөр : Database-ээ utf8аар хадгалсан учраас DB-холболтоо utf8-р тохируулж өглөө.
Иймээс DB рүү илгээх query болон DB-ээс ирэх result нь utf8-р кодлогдсон байгаа.
1. MYSQL* connectDB(void)
2. {
3. MYSQL *conn;
4. conn = mysql_init(NULL);
5. mysql_options(conn, MYSQL_SET_CHARSET_NAME, "utf8");
6. mysql_options(conn, MYSQL_INIT_COMMAND, "SET NAMES utf8");
7. mysql_real_connect(conn, DB_HOST, DB_USER, DB_PASS, DB_NAME, 3306, (char *)NULL, 0);
8. if(conn == NULL)
9. {
10. fprintf(stderr, "Mysql connection error : %s", mysql_error(conn));
11. exit(0);
12. }
13. return conn;
14.}
2. Хоёр дахь method DB рүү query-г илгээж, DB-с ирэх хариуг хүлээн авах үүрэгтэй.
Энэхүү method-ын эхний parameter нь wchar_t type-тай query нэртэй string байна. Би дээрийн бичлэг дээрээ C хэлэн дээр монгол кирилл үсгийг зөв хадгалахын тулд wide character type-г ашиглана гэж бичсэн. Тэгэхээр энэхүү query string маань unicode -оор кодлогдсон байгаа. Харин mysql database дэх монгол кириллээр бичигдсэн өгөгдөл маань utf8-аар кодлогдсон байгаа. Тиймээс DB рүү илгээх query-гээ utf8-аар кодлож байж илгээх ёстой. Тэгэхгүй бол кириллээр бичсэн үгийг зөв тайлж уншиж чадахгүй кодлосон арга нь өөр учраас.
*2р мөрөнд : "char * UNIToUTF(wchar_t*)" -г ашиглаж query-н кодыг Unicode-с UTF8-руу хувиргалаа. Сайн ажиглаарай UNIToUTF нэртэй method -ний оролт нь wchar_t* type-тай байсан бол гаралт нь char * type-тай байна.
*3р мөрөнд : Ингэж хувиргасан query-гээ (queryChar)
mysql_real_query method-г ашиглан db рүү явууллаа.
*10р мөрөнд db-ээс хариу result-авчирлаа.
1.MYSQL_RES * fetch_result(wchar_t * query, MYSQL * conn){
2. MYSQL_RES * res;
3. int query_stat;
4. char * queryChar = UNIToUTF(query);
5. query_stat = mysql_real_query(conn, queryChar, strlen(queryChar));
6. if(query_stat)
7. {
8. fprint(stderr, "Mysql query error : %s", mysql_error(conn));
9. }
10. res = mysql_store_result(conn);
11. return res;
}
3.
*7, 8р мөр : DB-ээс ирсэн хариу өгөгдөл маань utf8-аар кодлогдсон байгаа тул UTF8ToUNI гэсэн method-г ашиглан Unicode руу хувиргана.
1. wchar_t query[256];
2. wcscpy(query, L"select col1, col2 from table1 where col1 like 'өглөө' ");
3. MYSQL_RES *res;
4. MYSQL_ROW row;
5. res = fetch_result(query, conn);
6. while((row=mysql_fetch_row(res))!=NULL){
7. wchar_t * col1 = UTF8ToUNI(row[0]);
8. wchar_t * col2= UTF8ToUNI(row[1]);
....
4. Хамгийн сүүлийн хоёр method бол та бүхэн өөрийнхөө кодод тэр чигээр нь хуулж аваад ашиглах хамгийн гол method-ууд байгаа.
*4 болон 6р мөрөнд ижил method-г дуудсан боловч сүүлээсээ гурав дахь parameter-ээс шалтгаалж 2 өөр үйлдэл гүйцэтгэнэ.
*4р мөрөнд сүүлээсээ гурав дахь parameter буюу string-н уртыг 0р өгвөл whcar_t type- р хадгалагдсан string-г utf8 руу хадгалахад хэр их багтаамж шаардлагатайг хэмжиж өгнө.
*5р мөрөнд HEAP-т дээрх мөрөнд хэмжсэн хэмжээний багтаамжтай зайг гаргаж, түүнийхээ хаягийг strUTF8 -д хадгалууллаа.
*6р мөрөнд энэ урьдчилан бэлдсэн зайндаа strUNI-д байгаа Unicode-р кодлогдсон үгийн utf8 рүү хувиргаж хадгална.
1.char* UNIToUTF8(const wchar_t * strUNI)
2.{
3. char * strUTF8=NULL;
4. int nLen = WideCharToMultiByte(CP_UTF8, 0, strUNI, -1, strUTF8, 0, NULL, NULL);
5. strUTF8 = (char*)malloc(nLen+1);
6. WideCharToMultiByte(CP_UTF8, 0, strUNI, -1, strUTF8, nLen, NULL, NULL);
7. return strUTF8;
8.}
wchar_t* UTF8ToUNI(const char* strUTF8)
{
wchar_t * strUnicode;
int nLen = MultiByteToWideChar(CP_UTF8, 0, strUTF8, lstrlen(strUTF8)+1, NULL, NULL);
strUnicode = (wchar_t*)malloc(nLen+1);
MultiByteToWideChar(CP_UTF8, 0, strUTF8, lstrlen(strUTF8)+1, strUnicode, nLen);
return strUnicode;
}
За өөрийнхөө дээр бичиж байсан кодыг ашиглан жишээ авч чадах ядахаараа тайлбарлалаа. Зарим нэг нэр томьёог монголоор хэлж мэдэхгүй болохоор шууд англиар биччихлээ.
Би өөрөө энэ асуудлыг шийдэх гэж хэдэн өдөр болж байсан шиг санагдаж байна. Дараа дараагийн хүмүүс маань нэгнийхээ туршлаган дээр суурилаад хийвэл хамтаараа илүү олон асуудлуудыг шийдэж чадах болов уу. Та бүхэнд амжилт хүсье.
keyword : mongolian cyrillic word, mysql table record, c programming language
Friday, 28 February 2014
Friday, 21 February 2014
MySQL error code 1175
MySQL safe mode/ аюулгүй төлөвт байхад table update/delete хийхэд WHERE дээр хүснэгтийн индекс ороогүй бол error code 1175 алдаа гарна. Аюулгүй төлөв нь хүснэгтийн өгөгдлүүд олноороо устгагдахаас сэргийлж байгаа юм. Дараах query-аар энэхүү тохиргоог арилгасны дараа update-хийвэл болно.
SET SQL_SAFE_UPDATES = 0;
SET SQL_SAFE_UPDATES = 0;
Monday, 3 February 2014
MySQL view
Тодорхойлолт
View нь байнга хэрэглэгддэг, төвөгтэй select query-г хадгалах зорилготой ба хиймэл хүснэгт(virtual table) гэж нэрлэгдэх нь бий. Учир нь view нь яг table-тэй адилхан багана, мөртэй боловч жинхэнэ өгөгдөл энд хадгалагдаж байгаа биш юм. Гол зорилго нь join -г ашиглан хэд хэдэн өөр table болон view-ээс төвөгтэйгээр гаргаж авах өгөгдлийг хадгалж, дараа нь хялбар аргаар энэхүү өгөгдлийг харах боломжтой. Мөн шаардлагатай нөхцөлийг хангасан тохиолдолд View-ийг ашиглан жинхэнэ өгөгдлийг шинэчилэх боломжтой.
Давуу тал
1. Хэцүү query - г хялбарчилж өгнө. Олон өөр өөр table-ээс өгөгдлийг гаргаж авах урт, төвөгтэй query-ийг view болгон хадгалж, энэ төвөгтэй query-г байнга хэрэглэхийг оронд view-ийг ашиглан амархан select query-ээр өгөгдлийг харж болно.
2. Зарим хэрэглэгчдэд тодорхой өгөгдлийг харуулахгүйгээр хязгаарлах боломжтой.
3. Зөвхөн өгөгдлийг харах боломжтой (read only) view-ийг байгуулж, өгөгдлийг өөрчлөх боломжгүй хамгаалалт үүсгэж болно.
4. Өөр өгөгдлөөс тооцоолон гаргах боломжтой өгөгдлийг view-д хадгалах боломжтой. Table-д ингэж тооцоолон гаргах боломжтой өгөгдлийг хадгалбал ой санамжийн зайг үр ашиггүй хэрэглэсэн болно.
Сул тал
1. View өөр view-ээс үүссэн бол өгөгдлийг тооцоолон гаргахад бага зэрэг удна.
2. Table-ээс үүсгэдэг учраас table өөрчлөгдөхөд view-г ч мөн өөрчлөх шаардлагатай болдог.
View нь байнга хэрэглэгддэг, төвөгтэй select query-г хадгалах зорилготой ба хиймэл хүснэгт(virtual table) гэж нэрлэгдэх нь бий. Учир нь view нь яг table-тэй адилхан багана, мөртэй боловч жинхэнэ өгөгдөл энд хадгалагдаж байгаа биш юм. Гол зорилго нь join -г ашиглан хэд хэдэн өөр table болон view-ээс төвөгтэйгээр гаргаж авах өгөгдлийг хадгалж, дараа нь хялбар аргаар энэхүү өгөгдлийг харах боломжтой. Мөн шаардлагатай нөхцөлийг хангасан тохиолдолд View-ийг ашиглан жинхэнэ өгөгдлийг шинэчилэх боломжтой.
Давуу тал
1. Хэцүү query - г хялбарчилж өгнө. Олон өөр өөр table-ээс өгөгдлийг гаргаж авах урт, төвөгтэй query-ийг view болгон хадгалж, энэ төвөгтэй query-г байнга хэрэглэхийг оронд view-ийг ашиглан амархан select query-ээр өгөгдлийг харж болно.
2. Зарим хэрэглэгчдэд тодорхой өгөгдлийг харуулахгүйгээр хязгаарлах боломжтой.
3. Зөвхөн өгөгдлийг харах боломжтой (read only) view-ийг байгуулж, өгөгдлийг өөрчлөх боломжгүй хамгаалалт үүсгэж болно.
4. Өөр өгөгдлөөс тооцоолон гаргах боломжтой өгөгдлийг view-д хадгалах боломжтой. Table-д ингэж тооцоолон гаргах боломжтой өгөгдлийг хадгалбал ой санамжийн зайг үр ашиггүй хэрэглэсэн болно.
Сул тал
1. View өөр view-ээс үүссэн бол өгөгдлийг тооцоолон гаргахад бага зэрэг удна.
2. Table-ээс үүсгэдэг учраас table өөрчлөгдөхөд view-г ч мөн өөрчлөх шаардлагатай болдог.
Subscribe to:
Posts (Atom)