[ROZWIĄZANE] Pytanie odnoście MYSQL
Black004
31.07.2019
Napisałem taki kod, oczywiście patrzyłem jak inne pluginy są napisane w SQL, wyszło mi takie coś:
Kod ku mojemu zdziwieniu działa, ale czy dałoby się go jakoś go lepiej napisać? Czega mam unikać w robieniu zapisu sql?
Czy da się to:
liczba[id] = SQL_ReadResult(query, SQL_FieldNameToNum(query,"liczba"))
Odczytać to jakoś inaczej? W innych pluginach inaczej czasami to się robi w inny sposób. Dobry jest to sposób?
Ostanie pytanie, czy da się jakoś bardziej usprawnić ten zapis?
Jeszcze jedno, jak zapisać stringa w sql i go odczytać?
Użytkownik Black004 edytował ten post 31.07.2019 18:50
Robiin
31.07.2019
Jeszcze jedno, jak zapisać stringa w sql i go odczytać?
Przecież już zapisujesz - nick.
// Tworzenie tabeli: CREATE TABLE IF NOT EXISTS `tableName` (`userName` VARCHAR(33), `someValue` INT(10), `someOtherValue` VARCHAR(33)); // Insertowanie wartości: INSERT INTO `tableName` (userName, someValue, someOtherValue) VALUES ('abcd', '0', 'efgh'); // Pobieranie wartości: SELECT * FROM `tableName` WHERE `userName` = 'abcd'; // Aktualizowanie wartości: UPDATE `tableName` SET `someValue` = '1' WHERE `userName` = 'abcd';
Wszystkie zapytania powinny kończyć się średnikiem. Zapytania w kodzie możesz rozbijać na sekcje wieloliniowe poprzez użycie backslasha (\) na końcu linii (niektóre edytory tekstu mogą wywalać błąd, że string nie został zakończony [bo edytor nie znajdzie " na końcu linijki], ale tym się nie przejmuj). Robisz to tak:
format(mysqlRequest, charsmax(mysqlRequest), "INSERT INTO `tableName`\ (userName, someValue, someOtherValue)\ VALUES ('abcd', '0', 'efgh'");
Możesz odczytywać konkretne wartości zamiast wszystkich:
Odczyt wszystkich rekordów względem wartości 'someValue' jeśli jest >= 0:
SELECT * FROM `tableName` WHERE `someValue` >= '0';
Odczyt konkretej wartości rekordów, których wartość someOtheValue jest równa "efgh":
SELECT `userName` FROM `tableName` WHERE `someOtherValue` = 'efgh';
Ważna jest ta funkcja i to, żebyś wiedział co tak naprawdę robi:
stock mysql_escape_string(output[], len) { static const szReplaceIn[][] = { "\\", "\0", "\n", "\r", "\x1a", "'", "^"" }; static const szReplaceOut[][] = { "\\\\", "\\0", "\\n", "\\r", "\Z", "\'", "\^"" }; for(new i; i < sizeof szReplaceIn; i++) replace_all(output, len, szReplaceIn[i], szReplaceOut[i]); }
Jest to zabezpieczenie przed mysql injection.
Usprawnienie tworzenia tabeli:
CREATE TABLE IF NOT EXISTS `tableNane` ( `userName` VARCHAR(33) NOT NULL PRIMARY KEY , `someValue` INT(10) NOT NULL UNSIGNED, `someOtherValue` VARCHAR(33) NOT NULL );
Użytkownik aSiorr edytował ten post 31.07.2019 19:57
Rivit
31.07.2019
mysql_escape_string - tu uważaj, wczoraj poprawiałem błąd takiemu typowi, tu jest to samo.
Chodzi o to, że tam przekazujesz tablice (zawierającą nick) i robisz na niej replace. Replace zamieniające jakiś znak(i) na znak(i) których jest więcej. W takim razie tablica z nickiem powinna być większa! Myśle, że 64 na nick w takim przypadku wystarczy
___
!module_exists("MySQL")
zbędne
_____
w saveData masz sprawdzanie is_user_connected - generalnie ja bym nie sprawdzał, jak wychodzi no to nie bedzie polaczony (jakies dziwne przypadki mialem z tym)
w readData też bym nie sprawdzał is_user_connected
______
len_full += formatex(temp_full[len_full], charsmax(temp_full)-len_full, "UPDATE `TESTOWE` SET `liczba` = '%d' WHERE `name` = '%s'", liczba[id], nazwa_gracza);
ten formatex też dziwnie robisz, po co Ci to len_full tam?
znaczy jest ok, ale nie wiem po co taki zabieg
______
public readDataHandler(failstate, Handle:query, error[], errnum, data[], size) { new id = data[0]; if(failstate != TQUERY_SUCCESS) { return PLUGIN_CONTINUE; }
tu zawsze fajnie jest sobie error wypisac.
log_amx(error)
Tu widze ze readDataHandler2 uzyles tego, wiec ok
____
if(!connected || !is_user_connected(id) || is_user_bot(id) || is_user_hltv(id) || !module_exists("MySQL")) return PLUGIN_CONTINUE;
drugi raz sprawdzasz to w handlerze od query readDataHandler - w zasadzie to nie ma po co, mozna by sprawdzic tylko czy gracz polączony
____
edit:
jeszcze nie musisz miec zmiennej connected, mozesz sprawdzac tak:
if( gSqlTuple == Empty_Handle ) //to znaczy ze sie nie powiodlo łączenie
wypadaloby sprawdzac po uzyciu SQL_MakeDbTuple
_____
liczba[id] = SQL_ReadResult(query, SQL_FieldNameToNum(query,"liczba"))
generalnie jako drugi parametr mozesz podać numer kolumny, ale nie polecam, używaj tak jak teraz. Jak do bazy bedziesz dodawac kolumny itp to nie bedzie trzeba zmieniac wczytywania
Użytkownik TibacK edytował ten post 31.07.2019 20:20
Toldi
31.07.2019
Ja robię tak i mi działa
Zapis
formatex(equip, charsmax(equip), "UPDATE `skins_for_coins` SET `skinid(0-50)`='%s', `skinid(51-100)`='%s', `currentmodel`='%s' WHERE `nick`='%s' ", skins[0], skins[1], currentmodels, PlayerName[id]);
Tablice skins[0]/[1], currentmodels przechowują string.
Odczyt
SQL_ReadResult(Query, SQL_FieldNameToNum(Query,"skinid(0-50)"), skins[0], charsmax(skins[]) ) SQL_ReadResult(Query, SQL_FieldNameToNum(Query,"skinid(51-100)"), skins[1], charsmax(skins[]) ) SQL_ReadResult(Query, SQL_FieldNameToNum(Query,"currentmodel"), currentmodels, charsmax(currentmodels) )
Z kolumny o nazwie skinid(0-50) wkłada stringa do tablicy skins[0], która jest tworzona w funkcji nie globalnie bo identyczna tablica istnieje już w zapisie, która też jest tworzona w tym że publicu.
Black004
31.07.2019
Dzięki wszystkim za odpowiedź Teraz w sumie jakby ktoś jeszcze pytał o sql to można jak najbardziej go tu odsyłać, wszystko wyjaśnione. Jeszcze raz dzięki!
dasiek
01.08.2019
Ten temat został zamknięty przez moderatora.
Powód: Pomoc udzielona
Jeśli się z tym nie zgadzasz, raportuj ten post, a moderator lub administrator rozpatrzy go ponownie.
Z pozdrowieniami,
Zespół AMXX.PL