MySQL запрос. Синтаксическая ошибка.

Тема в разделе "Программирование / Скриптинг", создана пользователем Primo, 29 июн 2015.

  1. Primo

    Primo Где мои манеры

    Сообщения:
    1.191
    Симпатии:
    310
    Есть код
    PHP:
    public OnClientDisconnect(client)

        if (
    db == INVALID_HANDLE)
        {
            new 
    String:Error[256];
            
    LogError("Fail connect: %s"Error);
        }
        else if(
    Player[PlayerJoin][client] == && !IsFakeClient(client)) 
        { 
            
    CheckNewNix(client);
            
    CheckstVIP(client);
            
    Player[PlayerJoin][client] = 0;
            
    decl String:sAuth[64], String:pName[150], String:query[2048]; 
            
    GetClientName(clientsAuthsizeof(sAuth) - 1); 
            
    SQL_EscapeString(dbsAuthpNamesizeof(pName) - 1); 
            
    GetClientAuthString(clientsAuthsizeof(sAuth) - 1); 
            
    FormatEx(querysizeof(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(dbSQL_SelectPlayerCallbackquery);
        } 
    }
    Периодически выдаёт ошибку
    PHP:
    Ошибка подключения к базе данных (You have an error in your SQL syntaxcheck the manual that corresponds to your MySQL server version for the right syntax to use near 's'10171010027ON DUPLICATE KEY UPDATE Steam 'STEAM_1:1:1234567' at line 1)
    Что не так с запросом, или как решить эту проблему?
     
  2. ykpon

    ykpon Владыка Read Only

    Сообщения:
    399
    Симпатии:
    104
    Открыть базу данных и удалить дубликат.
    Либо добавить колонку 'id' и установить ее как "auto_increment".
     
  3. Primo

    Primo Где мои манеры

    Сообщения:
    1.191
    Симпатии:
    310
    ykpon, не то) Плохое решение) И я не делал id. В этом нет нужды.

    В общем, проблема, как я понял, в том, что в нике может быть спецсимвол типа кавычки, из-за этого весь запрос рушится. Я думал, что SQL_EscapeString решает эту проблему, но оно не решило проблему. Есть ли еще варианты решения?
     
  4. ykpon

    ykpon Владыка Read Only

    Сообщения:
    399
    Симпатии:
    104
    Может что то не передается в запрос? Включай дебаг. Вместе с запросом выводи данные, которые передаются.
     
  5. Саша Шеин

    Саша Шеин

    Сообщения:
    1.259
    Симпатии:
    191
    Заменяй спец символ на чёнить другое. Я так делаю в RPG и в Army Ranks вроде так тоже сделано.
     
    Primo нравится это.
  6. Primo

    Primo Где мои манеры

    Сообщения:
    1.191
    Симпатии:
    310
    ykpon, я, вроде, предоставил код. Смотри код, всё передаётся.

    Хорошая идея, попробую. Еще варианты есть? :D
     
  7. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.982
    Симпатии:
    2.983
    Primo, предже всего сделай LogMessage(query); чтобы увидеть что в запросе не так.
    На sql кажется ON DUPLICATE KEY UPDATE у меня не работало и выдавало ошибку как у тебя...
    По поводу
    Вообще мистическая ф-я. То всё норм, то в ручную нужно экранировать символы.
     
    Primo нравится это.
  8. Primo

    Primo Где мои манеры

    Сообщения:
    1.191
    Симпатии:
    310
    R1KO, я с 100% уверенностью скажу, что это из-за ' в нике. У чувака ник 'BenQ, а в ошибку вывело всё, что после ', то бишь BenQ, 0, 0, 0 ON DUPLICATE KEY UPDATE SET...... Указывая на то, что с ника пошел ошибочный синтаксис.
     
  9. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.982
    Симпатии:
    2.983
    Primo, пробуй ReplaceString "'" to "" или "\'" (или "\\'")
     
    Primo нравится это.
  10. Primo

    Primo Где мои манеры

    Сообщения:
    1.191
    Симпатии:
    310
    R1KO, Оффтоп
     
  11. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.982
    Симпатии:
    2.983
    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(inputoutputmaxlength, &written);

        
    cell_t *addr;
        
    pContext->LocalToPhysAddr(params[5], &addr);
        *
    addr = (cell_t)written;

        return 
    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 *strchar buffer[], size_t maxlensize_t *newSize) =0;
    ...
    mysql_real_escape_string(m_mysqlbufferstrsize);
     
  12. Primo

    Primo Где мои манеры

    Сообщения:
    1.191
    Симпатии:
    310
    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.
     
  13. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.982
    Симпатии:
    2.983
    Primo, это только в inc SQL_EscapeString, на самом деле это старая SQL_QuoteString. Я скинул исходы sm
     
  14. ykpon

    ykpon Владыка Read Only

    Сообщения:
    399
    Симпатии:
    104
    Ничего не видно, что у тебя передается.
    Одно дело, что ты в скрипте прописал, другое, что передается на самом деле, в запросе.
    В консоль выводи содержимое запроса.
    Это элементарный вопрос отладки.
     
  15. Primo

    Primo Где мои манеры

    Сообщения:
    1.191
    Симпатии:
    310
    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 не использую, моя невнимательность.