Есть код Спойлер PHP: public OnClientDisconnect(client){ if (db == INVALID_HANDLE) { new String:Error[256]; LogError("Fail connect: %s", Error); } else if(Player[PlayerJoin][client] == 1 && !IsFakeClient(client)) { CheckNewNix(client); CheckstVIP(client); Player[PlayerJoin][client] = 0; decl String:sAuth[64], String:pName[150], String:query[2048]; GetClientName(client, sAuth, sizeof(sAuth) - 1); SQL_EscapeString(db, sAuth, pName, sizeof(pName) - 1); GetClientAuthString(client, sAuth, sizeof(sAuth) - 1); FormatEx(query, sizeof(query), "INSERT INTO dp_users (Steam, Nick, Kills, Deaths, Level, EXP, Credits, BanValue, Rating) VALUES ('%s', '%N', %d, %d, %d, %d, %d, %d, %d) ON DUPLICATE KEY UPDATE Steam = '%s', Nick = '%N', Kills = %d, Deaths = %d, Level = %d, EXP = %d, Credits = %d, BanValue = %d, Rating = %d", sAuth, client, Player[pKills][client], Player[pDeaths][client], Player[pLevel][client], Player[pEXP][client], Player[pCredit][client], Player[pBanValue][client], Player[Rating][client], sAuth, client, Player[pKills][client], Player[pDeaths][client], Player[pLevel][client], Player[pEXP][client], Player[pCredit][client], Player[pBanValue][client], Player[Rating][client]); SQL_TQuery(db, SQL_SelectPlayerCallback, query); } } Периодически выдаёт ошибку PHP: Ошибка подключения к базе данных (You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 's', 10, 17, 1, 0, 10, 0, 27) ON DUPLICATE KEY UPDATE Steam = 'STEAM_1:1:1234567' at line 1) Что не так с запросом, или как решить эту проблему?
Открыть базу данных и удалить дубликат. Либо добавить колонку 'id' и установить ее как "auto_increment".
ykpon, не то) Плохое решение) И я не делал id. В этом нет нужды. В общем, проблема, как я понял, в том, что в нике может быть спецсимвол типа кавычки, из-за этого весь запрос рушится. Я думал, что SQL_EscapeString решает эту проблему, но оно не решило проблему. Есть ли еще варианты решения?
Может что то не передается в запрос? Включай дебаг. Вместе с запросом выводи данные, которые передаются.
ykpon, я, вроде, предоставил код. Смотри код, всё передаётся. Хорошая идея, попробую. Еще варианты есть? :D
Primo, предже всего сделай LogMessage(query); чтобы увидеть что в запросе не так. На sql кажется ON DUPLICATE KEY UPDATE у меня не работало и выдавало ошибку как у тебя... По поводу Вообще мистическая ф-я. То всё норм, то в ручную нужно экранировать символы.
R1KO, я с 100% уверенностью скажу, что это из-за ' в нике. У чувака ник 'BenQ, а в ошибку вывело всё, что после ', то бишь BenQ, 0, 0, 0 ON DUPLICATE KEY UPDATE SET...... Указывая на то, что с ника пошел ошибочный синтаксис.
R1KO, Оффтоп как же я не подумал, что можно было тупо убрать эти кавычки из ника :( Сам себе противен
Спойлер PHP: static cell_t SQL_QuoteString(IPluginContext *pContext, const cell_t *params) { IDatabase *db = NULL; HandleError err; if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db)) != HandleError_None) { return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err); } char *input, *output; size_t maxlength = (size_t)params[4]; pContext->LocalToString(params[2], &input); pContext->LocalToString(params[3], &output); size_t written; bool s = db->QuoteString(input, output, maxlength, &written); cell_t *addr; pContext->LocalToPhysAddr(params[5], &addr); *addr = (cell_t)written; return s ? 1 : 0; } /** * Quotes a string for insertion into a query. * * @param str Source string. * @param buffer Buffer to store new string (should not overlap source string). * @param maxlen Maximum length of the output buffer. * @param newSize Pointer to store the output size. * @return True on success, false if the output buffer is not big enough. * If not big enough, the required buffer size is passed through * newSize. */ virtual bool QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newSize) =0; ... mysql_real_escape_string(m_mysql, buffer, str, size);
R1KO, Notes: This is a backwards compatibility stock. You should use SQL_EscapeString() instead, as this function will probably be deprecated in SourceMod 1.1.
Primo, это только в inc SQL_EscapeString, на самом деле это старая SQL_QuoteString. Я скинул исходы sm
Ничего не видно, что у тебя передается. Одно дело, что ты в скрипте прописал, другое, что передается на самом деле, в запросе. В консоль выводи содержимое запроса. Это элементарный вопрос отладки.
ykpon, ну, я, конечно, понимаю, что тебе нужно больше информации, но она предоставлена. Давай рассуждать логически: Код: Player[pKills][client], Player[pDeaths][client], Player[pLevel][client], Player[pEXP][client], Player[pCredit][client], Player[pBanValue][client], Player[Rating][client], Это целочисленные переменные, они в любом случае будут иметь какое-то значение, пусть даже 0. Код: GetClientAuthString(client, sAuth, sizeof(sAuth) - 1); sAuth. Из ошибки видно, что STEAMID получен! Ну а client что, получить ник, зная индекс, плёвое дело. Из ошибки ты видел, что ник получен. Вопрос, что тебя не устраивает? Запрос прописан, что я передаю в запросе тоже написано. А, ну для описания решения проблемы: я, дурак, делаю SQL_EscapeString, да вот в запросе pName не использую, моя невнимательность.