Na začiatok je potrebné podotknúť, že v dnešnej dobe, v ktorej je komplikovaný ako samotný návrh, tak aj tvorba aplikácií, je využívanie uý navrhnutých a stabilných systémov veľkou výhodou. MySQL pozná skoro každý programátor, ktorý pracuje či už na vývoji alebo správe webovej stránky. V mnohých prípadoch je potrebné takéto technológie používať aj vo vývoji desktopových aplikácií. Rád by som teraz osvetlil základné kroky k implementácii MySQL do vášho projektu.
V prvom rade potrebujete vedieť, kde máte hľadať hlavičkové súbory MySQL, LIB súbory a samotnú libmysql.dll - srdce MySQL. Najlepším spôsobom je pri inštalácii serveru MySQL zvoliť možnosť inštalovania dodatočných developerských súborov (pri inštalácii zvolíte „Custom“ inštaláciu a vyberiete produkt „C Include Files / Lib Files“). Do priečinka sa nainštalujú taktiež podpriečinky „include“ a „lib“ („lib“ obsahuje „debug“ a „opt“). Následne je vhodné si tieto priečinky vložiť do vášho programovacieho prostredia. Ak používate Visual Studio, priečinok pre „include“ pridáte týmto spôsobom: Project -> Properties -> Configuration Properties -> C/C++ -> General -> Additional Include Directories. Následne si do svojho projektu pridáte hlavičkový súbor:
#include
; Pre vloženie statickej knižnice použijete obdobný spôsob: Project -> Properties -> Configuration Properties -> Linker -> General -> Additional Library Directories Ako som už naznačil, v priečinku „lib“ sa nachádzajú dva ďalšie, a to „debug“ a „opt“. Buď si vyberiete jeden z týchto priečinkov a potom použijete len „libmysql.lib“ alebo si v projekte necháte možnosť využiť či debug knižnicu alebo release (teda použijete „debug/libmysql.lib“) alebo „opt/libmysql.lib“. Knižnicu do svojho projektu môžete pridať týmto preprocesorovým príkazom:
#pragma comment(lib,"libmysql.lib")
Alebo nastaviť priamo v možnostiach projektu: Project -> Properties -> Configuration Properties -> Linker -> Input -> Additional Dependencies Samotnú implementáciu budem komentovať postupne a začnem základným kameňom a to je typ MYSQL, resp. st_mysql. S týmto typom sa budete stretávať pri používaní funkcií na inicializáciu, spojenie, nastavenie komunikácie, odosielanie dotazov atď. Deklarujeme si teda objekt tohto typu:
MYSQL mySQL;
Ďalším krokom je inicializácia tohto objektu. Urobíme to jednoduchou funkciou mysql_init(MYSQL *), ktorá ako argument preberá odkaz na štruktúru MYSQL. V popise tejto funkcie je jedna síce vhodná, no ale možno zbytočná vlastnosť. Ak ako argument použijete NULL, resp. 0, funkcia mysql_init() vytvorí tento objekt automaticky a vráti jeho adresu. Platí teda, ak sa inicializácia podarí, funkcia mysql_init() vracia ukazovateľ na objekt MySQL (v prípade, že argument MYSQL * použijete, funkcia vráti ukazovateľ použitý ako argument), v opačnom prípade je návratová hodnota 0. My teda objekt inicializujeme a výsledok otestujeme takto:
if (mysql_init(&mySQL))
{…}
V druhom kroku potrebujeme nadviazať spojenie s MySQL serverom. Toto docielime použitím funkcie MYSQL * mysql_real_connect(MYSQL *, const char * host, const char * pouzivatel, const char * heslo, const char * databaza, unsigned int port, const char * unix_socket, unsigned long client_flag). Prvým argumentom je ukazovateľ na náš objekt MYSQL, ktorý sme si inicializovali v prvom kroku. Ako druhý parameter použijeme názov hostu, či už ip adresu alebo názvové stvárnenie. Ďalší parameter je meno používateľa, ktorý bude na MySQL serveri prihlásený. K tomu potrebujeme ešte aj heslo, ktoré je štvrtým argumentom. Piatym je názov databázy a šiestym číslo portu. U MySQL je to 3306, ak použijete hodnotu 0, port bude nastavený na automatickú hodnotu. Posledné dva argumenty nás v tomto prípade zaujímať nemusia, ide o rozšírené nastavenia. Funkcia mysql_real_connect() vracia ukazovateľ na objekt spojenia. V prípade, že sa spojenie nadviazať nepodarí, je táto hodnota 0. V opačnom prípade je nastavená na hodnotu prvého argumentu, ktorý je tiež týmto typom. Teda v našom programe pokračujeme takto:
if (mysql_real_connect(&mySQL,"127.0.0.1","root","","databaza",3306,0,0))
{…}
Ako host používam adresu 127.0.0.1, mám pri tom spustený MySQL server. Meno používateľa je root, heslo žiadne. Názov databázy: databaza. Vo vašom prípade budú tieto argumenty s najväčšou pravdepodobnosťou odlišné. V programe ďalej pokračujeme spustením SQL dotazu. Najskôr si teda určíme samotný dotaz:
string dotaz = "SELECT * FROM skusobna_tabulka";
Použil som typ „string“, pretože jeho využiteľnosť je vyššia, ak by ste si chceli tento malý program upraviť. Teraz potrebujeme náš dotaz vykonať. Na toto slúži funkcia int mysql_real_query(MYSQL *mysql, const char * dotaz, unsigned long dlzka_textu_dotazu). Táto funkcia nám vykoná zvolený dotaz, resp. pokúsi sa vykonať a informuje nás o svojom výsledku pomocou návratovej hodnoty takto: ak vykonanie dotazu prebehlo, hodnota je 0. V opačnom prípade je hodnota nenulová.
if (mysql_real_query(&mySQL,dotaz.c_str(),dotaz.length()) == 0)
{…}
Predpokladáme, že náš dotaz bol vykonaný, nech je akéhokoľvek typu. Budeme chcieť obdržať výsledok tohto dotazu, resp. koľko údajov bolo zmenených. Dostávame teda dve možnosti. Buď náš dotaz údaje iba upravoval, mazal a pod. alebo z DB vyberal dáta. Tieto dve situácie rozlíšime nasledovne:
MYSQL_RES * vysledok;
vysledok = mysql_store_result(&mySQL);
if (vysledok)
{
// tento krok si popíšeme za chvíľu
mysql_free_result(vysledok);
}
else
{
if (mysql_field_count(&mySQL) == 0)
cout << "Pocet pozmenenych riadkov: " << mysql_affected_rows(&mySQL) << endl;
else
cout << mysql_error(&mySQL) << endl;
}
Výsledok MySQL je uložený ako typ MYSQL_RES, resp. st_mysql_res. Tento obsahuje údaje ako stĺpce, dáta atď. Získame ho pomocou funkcie MYSQL_RES * mysql_store_result(MYSQL *) a výsledok uvolníme pomocou mysql_free_result(MYSQL_RES *). Z horeuvedeného kódu vyplýva, že táto funkcia vracia ukazovateľ na objekt výsledku dotazu. Ak nie je možné výsledok obdržať, vrátená hodnota je 0. V tomto prípade sú možné dva scenáre. Dotaz spôsobil len zmenu údajov, nie ich výber z DB. Toto otestujeme použitím funkcie unsigned int mysql_field_count(MYSQL *), ktorá vracia informáciu o o počte stĺpcov v údaji o výsledku. Ak je teda počet stĺpcov nulový, jedná sa o údaj, ktorý upravoval určité dáta, preto by mal výsledok dotazu obsahovať počet zmenených riadkov. Funkcia my_ulonglong mysql_affected_rows(MYSQL *mysql) nám tento údaj poskytuje. V prípade, že je počet stĺpcov väčší ako nula, t.j. výsledok by mal obsahovať dáta, je príčinou prázdneho výsledku nejaká chyba. Funkcia const char *mysql_error(MYSQL *) vracia textový údaj o tejto chybe. Ďalej budem popisovať, ako obdržať dáta z výsledku. Všetky údaje sú uložené ako textové reťazce štandardne ukončené nulovým znakom. K týmto dátam je možné pristúpiť najlepšie cez funkciu MYSQL_ROW mysql_fetch_row(MYSQL_RES * vysledok), ktorej návratová hodnota je typu MYSQL_ROW, v prevedení je to char * * (teda pole ukazovateľov na ukazovatele textových reťazcov štýlu C (zakončenie nulovým znakom)). Riadkami môžeme prechádzať v cykle práve pomocou popísanej funkcie mysql_fetch_row().
unsigned int pocetStlpcov = mysql_num_fields(vysledok);
if (pocetStlpcov > 0)
{
MYSQL_ROW riadok = 0;
while ((riadok = mysql_fetch_row(vysledok)))
{
// „riadok“ je teraz pole textových hodnôt
}
}
else
cout << "Ziadne stlpce" << endl;
V prvom rade si funkciou unsigned int mysql_num_fields(MYSQL_RES * vysledok) získame počet stĺpcov z konkrétneho výsledku. Ak je tento počet väčší ako 0, v cykle while (), kde využívame mysql_fetch_row(), prejdeme celý obsah výsledku. Môžem upozorniť na prípady, kedy budete potrebovať vykonať viacero dotazov naraz. Váš kód bude musieť byť pozmenený hneď v niekoľkých častiach. Prvou zmenou je nastavenie možnosti používania viacerých MySQL dotazov naraz. Docielite to funkciou int mysql_set_server_option(MYSQL * mysql, enum enum_mysql_set_option option), kde ako druhý argument použijete hodnotu MYSQL_OPTION_MULTI_STATEMENTS_ON. Túto funkciu je potrebné umiestniť za nadviazaním spojenia. Následne vykonáte dotaz, vytvoríte objekt MYSQL_RES ako v uvedenom príklade, a nastavíte ho funkciou mysql_store_result(). Ďalej však už pokračujeme iným spôsobom, a to tak, že v cykle budeme testovať, či existuje nasledovný výsledok, ak áno, použijeme ho a proces sa opakuje. Viď príklad:
MYSQL_RES * vysledok;
vysledok = mysql_store_result(&mySQL);
while (vysledok)
{
// s výsledkom môžete pracovať ako v predchádzajúcom príklade
mysql_free_result(vysledok);
if (mysql_next_result(&mySQL) == 0)
vysledok = mysql_store_result(&mySQL);
else
break;
}
Nikdy však nesmiete zabudnúť na uvoľnenie výsledku pomocou mysql_free_result() pred tým, než budete chcieť obdržať ďalší výsledok. Prikladám zdrojový kód, kde som popísané postupy (okrem viac-výsledkového) spracoval do jednoduchého programu, ktorý sa pripojí na server 127.0.0.1:3306 s menom „root“ bez hesla, vykoná dotaz (buď zadaný priamo v kóde alebo zadaný ako príkazový argument) a zobrazí výsledok dotazu. Ak výsledok obsahuje dáta, tie sú zobrazené v zozname, kde je uvedený index zvoleného stĺpca, jeho názov a hodnota. Navyše, ak je údajovým typom dát textová hodnota, je zobrazená v apostrofoch (aby ste si všimli použitie atribútov stĺpcov).
Referencie: Dokumentácia MySQL 5.1
Zdrojový kód programu, ktorý sa pripojí na MySQL server 127.0.0.1:3306 a načíta zoznam databáz. Program je však možné spustiť aj s parametrom, ktorý bude reprezentovať SQL dotaz. Pre prácu v určitej databáze je potrebné upraviť pripojenie (mysql_real_connect), aby sa program pripojil na existujúcu databázu. Zdrojový kód programu