Offline |
|
|
Csatlakozott: 2014.09.08. 22:21 Hozzászólások: 3014
Megköszönt másnak: 96 alkalommal Megköszönték neki: 555 alkalommal
|
[kozep]SQL Tutorial by mforce[/kozep]Leírás:Ez egy egy szálon futó folyamat, ha a leírás szerint alkalmazzátok, akkor kevés teljesítmény használat mellett van egy hibátlan SQL mentésetek.Gyors ismertető: Kód: CREATE TABLE IF NOT EXISTS = Tábla létrehozása, ha nem létezik SELECT * from `tabla_neve` = Összes kiválasztása a `tabla_neve` táblából WHERE = Ahol INSERT INTO = Beillesztés UPDATE = Frissítés VALUES = Értékek varchar(32) = 32 karakterszámú szövegsor int(11) = 11 karakterszámú számsor (ugyanígy tovább float,boolean,text stb., de mi általában csak ezeket használjuk.) NOT NULL = Nem üres sor NULL = Automatikusan üres sor AUTO_INCREMENT = Automatikus növekedés PRIMARY KEY = Elsődleges kulcs Alap:SQL csatlakozás adatait és egy kezelő tömböt adjunk a pluginnak. (függvényen kívül felülre) new const SQL_INFO[][] = { "127.0.0.1", // HOST "username", // USERNAME "password", // PASSWORD "database" // DATABASE } new Handle:g_SqlTuple; // meg gondolom van legalább változónk is, ha már valamit menteni akarunk. new valtozo[33] // tároljuk valamibe a nevet is, mert nem akarom, mindig lekérni. new name[33][32]
Tábla létrehozás:Formázások a meghatározók a fentebb felsorolt gyors ismertető szerint. Jelenleg a tábla létrehozás az első. Illesszük be a `tabla_neve` helyére a tábla nevét, amit majd minden parancshoz is beillesztünk, ahol ezt látunk. Ezután adjuk meg a sorok nevét és az értékeket, esetleg a kiegészítő parancsokat, például jelen esetben NOT NULL, majd vesszővel válasszuk el a következő sortól. Az `id` részt javaslom úgy hagyni. A phpmyadminok, csak úgy engedik szerkeszteni a táblákat, ha van egy egyedi elsődleges tábla. Egy automatikusan növekvő számsor sorok létrehozása szerint tökéletes a célra. Ezután a createTableThread rész az SQL kérést teszi meg és figyeli, hogy nem-e lett benne hiba. public plugin_cfg() { new Query[512]; g_SqlTuple = SQL_MakeDbTuple(SQL_INFO[0],SQL_INFO[1],SQL_INFO[2],SQL_INFO[3]) formatex(Query, charsmax(Query), "CREATE TABLE IF NOT EXISTS `tabla_neve` (`username` varchar(32) NOT NULL,`valami_ertek` int(11) NOT NULL,`id` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY)") SQL_ThreadQuery(g_SqlTuple,"createTableThread", Query) } public createTableThread(FailState, Handle:Query, Error[], Errcode, Data[], DataSize, Float:Queuetime) { if(FailState == TQUERY_CONNECT_FAILED) set_fail_state("Nem tudtam csatlakozni az adatbazishoz."); else if(FailState == TQUERY_QUERY_FAILED) set_fail_state("Query Error"); if(Errcode) log_amx("Hibat dobtam: %s",Error); }
Játékos betöltése:Mivel username sort készítettem, így most névre mutatom meg. Persze változtatható egyszerűen, get_user_name részt átírjuk get_user_authid -re, akkor steamid-ről töltődik, viszont akkor arra is kell menteni. A load részből a QuerySelectData részbe visszük tovább az adatokat. public client_putinserver(id) { if(!is_user_bot(id)) { get_user_name(id, name[id], charsmax(name)) load(id) } } public load(id) { new Query[512], Data[1] Data[0] = id formatex(Query, charsmax(Query), "SELECT * FROM `tabla_neve` WHERE username = ^"%s^";", name[id]) SQL_ThreadQuery(g_SqlTuple, "QuerySelectData", Query, Data, 1) } public QuerySelectData(FailState, Handle:Query, Error[], Errcode, Data[], DataSize, Float:Queuetime) { if(FailState == TQUERY_CONNECT_FAILED || FailState == TQUERY_QUERY_FAILED) { log_amx("%s", Error) return } else { new id = Data[0]; if(SQL_NumRows(Query) > 0) { // Ha talált legalább 1 sort, akkor ezek történnek. valtozo[id] = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "valami_ertek")) // Ez a parancs szöveg, szám és float esetében is másképp van, ehhez infó lentebb. } else { // Ha nem talált sort, mert még nem volt a szerveren, akkor készítünk neki egyet. save(id) // Ehhez infó a Játékos sorainak létrehozásánál. } } }
Most egy szám változót töltöttünk be, de mi van ha szöveg kellene? Az SQL_ReadResult mindenhol másképp van. API infó:https://www.amxmodx.org/api/sqlx/SQL_ReadResultKönnyed leírás:Szám betöltés, amit most láthattunk: valtozo[id] = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "valami_ertek"))
Szöveg: SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "valami_ertek"), valami[id], charsmax(valami[]))
Float: SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "valami_ertek"), valami[id])
Játékos sorainak létrehozása:Itt a betöltés résznél, már lekértük a save(id) függvényt, ha nem találtuk az adatbázisban az embert. Az értéknek alapból 0-át adunk meg, nem is kérjük le inkább feleslegesen, még ha 0 is. Lássuk: public save(id) { new text[512]; formatex(text, charsmax(text), "INSERT INTO `tabla_neve` (`username`, `valami_ertek`) VALUES (^"%s^", ^"0^");", name[id]) SQL_ThreadQuery(g_SqlTuple, "QuerySetData", text) } public QuerySetData(FailState, Handle:Query, Error[], Errcode, Data[], DataSize, Float:Queuetime) { if(FailState == TQUERY_CONNECT_FAILED || FailState == TQUERY_QUERY_FAILED) { log_amx("%s", Error) return } }
Megjegyzés: A QuerySetData részt még felhasználjuk a játékos pontjainak mentéséhez is. Játékos pontjainak mentése:Az int = szám az %i, a string = szöveg az %s, ne felejtsük el. Most a valtozo[id], az szám, tehát nézzük a példát: public update(id) { new text[512]; formatex(text, charsmax(text), "UPDATE `tabla_neve` SET valami_ertek = ^"%i^" WHERE username = ^"%s^";", valtozo[id], name[id]) SQL_ThreadQuery(g_SqlTuple, "QuerySetData", text) }
Ezzel frissültek a névre a pontok. Több érték adása a formázásban így néz ki: formatex(text, charsmax(text), "UPDATE `tabla_neve` SET valami_ertek = ^"%i^", valami_szoveg = ^"%s^" WHERE username = ^"%s^";", valtozo[id], valami[id], name[id])
Tehát igazából csak simán vesszővel elválasszuk. Az update(id) részt, oda rakjuk, ahol mentést szeretnénk, nem terheli le a szervert, mintha fájlba történne. Mutatok azért egy lecsatlakozáskori mentést az egyszerűség kedvéért: public client_disconnect(id) { if(!is_user_bot(id)) { update(id) } valtozo[id] = 0 copy(name[id], charsmax(name[]), "") }
Megjegyzés: Mindig csekkoljuk le, hogy nem-e bot, mivel már csatlakozáskor nem töltöttük be, ha bot, így a tábla se jött létre. Tehát hibát dob, ha botról van szó és frissülne neki valami, de nincs táblája. Befejezés:public plugin_end() { SQL_FreeHandle(g_SqlTuple) }
Teljes forráskód:Kommentek nélkül. new const SQL_INFO[][] = { "127.0.0.1", // HOST "username", // USERNAME "password", // PASSWORD "database" // DATABASE } new Handle:g_SqlTuple; new valtozo[33] new name[33][32] public plugin_cfg() { new Query[512]; g_SqlTuple = SQL_MakeDbTuple(SQL_INFO[0],SQL_INFO[1],SQL_INFO[2],SQL_INFO[3]) formatex(Query, charsmax(Query), "CREATE TABLE IF NOT EXISTS `tabla_neve` (`username` varchar(32) NOT NULL,`valami_ertek` int(11) NOT NULL,`id` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY)") SQL_ThreadQuery(g_SqlTuple,"createTableThread", Query) } public createTableThread(FailState, Handle:Query, Error[], Errcode, Data[], DataSize, Float:Queuetime) { if(FailState == TQUERY_CONNECT_FAILED) set_fail_state("Nem tudtam csatlakozni az adatbazishoz."); else if(FailState == TQUERY_QUERY_FAILED) set_fail_state("Query Error"); if(Errcode) log_amx("Hibat dobtam: %s",Error); } public client_putinserver(id) { if(!is_user_bot(id)) { get_user_name(id, name[id], charsmax(name)) load(id) } } public load(id) { new Query[512], Data[1] Data[0] = id formatex(Query, charsmax(Query), "SELECT * FROM `tabla_neve` WHERE username = ^"%s^";", name[id]) SQL_ThreadQuery(g_SqlTuple, "QuerySelectData", Query, Data, 1) } public QuerySelectData(FailState, Handle:Query, Error[], Errcode, Data[], DataSize, Float:Queuetime) { if(FailState == TQUERY_CONNECT_FAILED || FailState == TQUERY_QUERY_FAILED) { log_amx("%s", Error) return } else { new id = Data[0]; if(SQL_NumRows(Query) > 0) { valtozo[id] = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "valami_ertek")) } else { save(id) } } } public save(id) { new text[512]; formatex(text, charsmax(text), "INSERT INTO `tabla_neve` (`username`, `valami_ertek`) VALUES (^"%s^", ^"0^");", name[id]) SQL_ThreadQuery(g_SqlTuple, "QuerySetData", text) } public QuerySetData(FailState, Handle:Query, Error[], Errcode, Data[], DataSize, Float:Queuetime) { if(FailState == TQUERY_CONNECT_FAILED || FailState == TQUERY_QUERY_FAILED) { log_amx("%s", Error) return } } public update(id) { new text[512]; formatex(text, charsmax(text), "UPDATE `tabla_neve` SET valami_ertek = ^"%i^" WHERE username = ^"%s^";", valtozo[id], name[id]) SQL_ThreadQuery(g_SqlTuple, "QuerySetData", text) } public client_disconnect(id) { if(!is_user_bot(id)) { update(id) } valtozo[id] = 0 copy(name[id], charsmax(name[]), "") } public plugin_end() { SQL_FreeHandle(g_SqlTuple) }
Végszó:Ennyi lenne, az egyszerűség kedvéért írtam csak változókat, persze ezzel mindent meg lehet oldani, de így tudtok minden parancsot. További problémák kibeszélése ezzel kapcsolatban itt!
_________________ GitHub - mforce
A hozzászólást 1 alkalommal szerkesztették, utoljára mforce 2015.11.30. 15:24-kor.
|
|