←  Pytania dotyczące pluginów

AMXX.pl: Support AMX Mod X i SourceMod

»

[ROZWIĄZANE] Pytanie odnoście MYSQL

Zablokowany

  • +
  • -
Black004 - zdjęcie Black004 31.07.2019

Napisałem taki kod, oczywiście patrzyłem jak inne pluginy są napisane w SQL, wyszło mi takie coś:

 

Spoiler

 

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
Odpowiedz

  • +
  • -
Robiin - zdjęcie 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
);
Spoiler

Użytkownik aSiorr edytował ten post 31.07.2019 19:57
Odpowiedz

  • +
  • -
Rivit - zdjęcie 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


Rivit (31.07.2019 20:05):
No i ubiegł mnie, ale to dobrze bo aSiorr napisał bardziej o SQL'u, a ja o samym kodzie :D

Użytkownik TibacK edytował ten post 31.07.2019 20:20
Odpowiedz

  • +
  • -
Toldi - zdjęcie 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.

Odpowiedz

  • +
  • -
Black004 - zdjęcie Black004 31.07.2019

Dzięki wszystkim za odpowiedź :D 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!

Odpowiedz

  • +
  • -
dasiek - zdjęcie dasiek 01.08.2019

Wiadomość wygenerowana automatycznie


Ten temat został zamknięty przez moderatora.

Powód: Pomoc udzielona

Jeśli się z tym nie zgadzasz, report.png raportuj ten post, a moderator lub administrator rozpatrzy go ponownie.


Z pozdrowieniami,
Zespół AMXX.PL
Odpowiedz
Zablokowany