[MySQL] Передать аргументы через массив

Сообщения
673
Реакции
242
Помог
11 раз(а)
Добрый вечер

Прошу вашей помощи
как предать массивы через поточный запрос в MySQL

Тут формируется данные, все ОК
Код:
public register_user(plugin_id, num_params)
{
    new login[32];
    get_string(1, login, charsmax(login));
    
    new pass[32];
    get_string(2, pass, charsmax(pass));
    
    new email[32];
    get_string(3, email, charsmax(email));
    
    new id = get_param(4);
    
    mysql_escape_string(login, charsmax(login));
    mysql_escape_string(pass, charsmax(pass));
    mysql_escape_string(email, charsmax(email));
    
    UpdateDB(login, pass, email, id);
}
дальше через поточный запрос сохраняю некоторые функции а именно = login, pass, email, id

Код:
stock UpdateDB(login[]="", pass[]="", email[]="", id) 
{    
        new szAuth[32];
        get_user_authid(id, szAuth, charsmax(szAuth));
        
        new query[QUERY_LENGTH], que_len;

        que_len += formatex(query[que_len],charsmax(query) - que_len, "SELECT `Login` FROM %s WHERE `Auth` = '%s'",g_szRankTable, szAuth);

        new sData[5];
        sData[0] = SQL_CHECK;
        sData[1] = id;
        sData[2] = login;
        sData[3] = email;
        sData[4] = pass;
        SQL_ThreadQuery(g_hDBHandle, "selectQueryHandler", query, sData, sizeof sData);
}
Передать SQL_запрос и индекс игрока получается а вот строку никак...
 
Сообщения
141
Реакции
201
Помог
5 раз(а)
123
 
Последнее редактирование:
Сообщения
673
Реакции
242
Помог
11 раз(а)
juice, непонял?
1 Окт 2019
Sql Запрос
Код:
public selectQueryHandler(failstate, Handle: queryHandle, err[], errNum, data[], datalen)
{
    switch(failstate)
    {
        case TQUERY_CONNECT_FAILED:  // ошибка соединения с mysql сервером
        {
            log_amx("SQL connection failed")
            log_amx("[ %d ] %s",errNum,err)
            
            return PLUGIN_HANDLED
        }
        case TQUERY_QUERY_FAILED:  // ошибка SQL запроса
        {
            new lastQue[QUERY_LENGTH]
            SQL_GetQueryString(queryHandle,lastQue,charsmax(lastQue)) // узнаем последний SQL запрос
            
            log_amx("SQL query failed")
            log_amx("[ %d ] %s",errNum,err)
            log_amx("[ SQL ] %s",lastQue)
            
            return PLUGIN_HANDLED
        }
    }
    
    
    switch(data[0])
    {
        case SQL_LOAD:
        {
            if(!SQL_NumResults(queryHandle))
            {

                new login[32];
                get_string(1, login, charsmax(login));

                
                new query[QUERY_LENGTH], que_len;

                que_len += formatex(query[que_len],charsmax(query) - que_len, "INSERT INTO %s (`Login`, `Password`, `Email`, `Auth`) VALUES ('%s', '%s', '%s', '%s')",g_szRankTable, login, pass, email, szAuth);
                
                jbe_mysql_stats_add(login, id);
                formatex(g_sLogin[id], charsmax(g_sLogin), "%s", login);

                new sData[1];
                sData[0] = SQL_INGORE;

                SQL_ThreadQuery(g_hDBHandle, "selectQueryHandler", query, sData, sizeof sData);

                

                return regs_main_menu(id);
            }
        }
        case SQL_CHECK:
        {
            new id = sData[1];

            new query[QUERY_LENGTH], que_len;

            que_len += formatex(query[que_len],charsmax(query) - que_len, "SELECT * FROM %s WHERE `Login` = '%s'",g_szRankTable, login);

            new sData[1];
            sData[0] = SQL_LOAD;

            SQL_ThreadQuery(g_hDBHandle, "selectQueryHandler", query, sData, sizeof sData);
        
        }
    }

    return PLUGIN_HANDLED
}
 
Сообщения
141
Реакции
201
Помог
5 раз(а)
123
 
Последнее редактирование:
Сообщения
144
Реакции
276
Помог
1 раз(а)
Массив + enum.

В прочем, сам по себе код мягко говоря, не ахти какой. Как минимум, в кэлбеке запроса нужна проверка на факт выполнения "plugin_end". Там же, в кэлбеке, надо SQL_FreeHandle по идее отсылать. Вызывать что-то на ID игрока, даже не проверив подключен ли он, ну это сразу ждите ошибок в логах, в лучшем случае.
 
Последнее редактирование:
Сообщения
1,293
Реакции
2,294
Помог
57 раз(а)
SISA, разве SQL_FreeHandle() нужен? В описании к SQL_ThreadQuery()
Код:
* @note The handle does not need to be freed.
Limbooc неправильно это
Код:
        new sData[5];
        sData[0] = SQL_CHECK;
        sData[1] = id;
        sData[2] = login;
        sData[3] = email;
        sData[4] = pass;
Куда ж ты строки пытаешься в ячейки запихать? Размер то 5 всего. Или раскуривай datapack.inc, или да, передавай в энумерованном массиве через сам SQL_ThreadQuery()
Код:
 * @param data          Additional data array that will be passed to the handler function.
 * @param dataSize      The size of the additional data array.
Код:
enum _:EXT_DATA_STRUCT {
    EXT_DATA__NAME[MAX_NAME_LENGTH],
    EXT_DATA__USERID
    EXT_DATA__STEAMID[MAX_AUTHID_LENGTH]
}

func_MyFunc(pPlayer) {
    new eExtData[EXT_DATA_STRUCT]
    
    get_user_name(pPlayer, eExtData[EXT_DATA__NAME], MAX_NAME_LENGTH - 1)
    eExtData[EXT_DATA__USERID] = get_user_userid(pPlayer)
    get_user_authid(pPlayer, eExtData[EXT_DATA__STEAMID], MAX_AUTHID_LENGTH - 1)
    
    SQL_ThreadQuery(ТУПЛ, "SQL_Handler", ЗАПРОС, eExtData, sizeof(eExtData))
}

public SQL_Handler(iFailState, Handle:hQueryHandle, szError[], iErrorCode, eExtData[], iDataSize, Float:fQueryTime) {
    // Здесь в eExtData ты имеешь данные, что ты засунул выше
}
 

Вложения

  • 701 байт Просмотры: 3
Сообщения
673
Реакции
242
Помог
11 раз(а)
BlackSignature,
Спасибо за ответ..
Зарегал я енум
Код:
enum _:EXT_DATA_STRUCT {
    EXT_DATA__SQL,
    EXT_DATA__USERID,
    EXT_DATA__INDEX,
    EXT_DATA__LOGIN[32],
    EXT_DATA__PASS[32],
    EXT_DATA__EMAIL[32]
}
и сохранил в запросе...

Код:
stock UpdateDB(login[]="", pass[]="", email[]="", id)
{   

        new szAuth[32];
        get_user_authid(id, szAuth, charsmax(szAuth));
        
        new query[QUERY_LENGTH], que_len;

        que_len += formatex(query[que_len],charsmax(query) - que_len, "SELECT `Login` FROM %s WHERE `Auth` = '%s'",g_szRankTable, szAuth);


        new sData[EXT_DATA_STRUCT];
        sData[EXT_DATA__SQL] = SQL_CHECK;
        sData[EXT_DATA__INDEX] = id;
        sData[EXT_DATA__USERID] = get_user_userid(id);
        sData[EXT_DATA__LOGIN] = login;
        sData[EXT_DATA__PASS] = pass;
        sData[EXT_DATA__EMAIL] = email;


        SQL_ThreadQuery(g_hDBHandle, "selectQueryHandler", query, sData, sizeof sData);

}
но на эти три аргумента ругается компелятор....
C++:
sData[EXT_DATA__LOGIN] = login;
sData[EXT_DATA__PASS] = pass;
sData[EXT_DATA__EMAIL] = email;

error 047: array sizes do not match, or destination array is too small
 
Сообщения
673
Реакции
242
Помог
11 раз(а)
BlackSignature, столкнулся с проблемой
я правильно получаю данные?
Код:
new login[32], email[32], pass[32];

                login = data[EXT_DATA__LOGIN];
                email = data[EXT_DATA__EMAIL];
                pass = data[EXT_DATA__PASS];

                #if defined SQL_CHECKING_LOG
                server_print("PRE SQL_LOAD #1 | %s | %s | %s", login, pass, email);
                #endif
вот последовотальности логирование
1#
Код:
new szAuth[32];
        get_user_authid(id, szAuth, charsmax(szAuth));
        
        new query[QUERY_LENGTH], que_len;

        que_len += formatex(query[que_len],charsmax(query) - que_len, "SELECT `Login` FROM %s WHERE `Auth` = '%s'",g_szRankTable, szAuth);


        new sData[EXT_DATA_STRUCT];
        sData[EXT_DATA__SQL] = SQL_CHECK;
        sData[EXT_DATA__INDEX] = id;
        sData[EXT_DATA__USERID] = get_user_userid(id);

        copy(sData[EXT_DATA__LOGIN], 31, login);
        copy(sData[EXT_DATA__PASS], 31, pass);
        copy(sData[EXT_DATA__EMAIL], 31, email);

        #if defined SQL_CHECKING_LOG
        server_print("SQL_CHECK | %s | %s | %s", login, pass, email);
        #endif

        SQL_ThreadQuery(g_hDBHandle, "selectQueryHandler", query, sData, sizeof sData);
в консоле все ОК
19231

в SQL_CHECK выполняет следующее
Код:
new id = data[EXT_DATA__INDEX];
            if(!is_user_connected(id)) return PLUGIN_HANDLED;
            if(get_user_userid(id) == data[EXT_DATA__USERID])
            {
                new login[32], email[32], pass[32];

                login = data[EXT_DATA__LOGIN];
                email = data[EXT_DATA__EMAIL];
                pass = data[EXT_DATA__PASS];

                #if defined SQL_CHECKING_LOG
                server_print("PRE SQL_LOAD #1 | %s | %s | %s", login, pass, email);
                #endif

                new query[QUERY_LENGTH], que_len;

                que_len += formatex(query[que_len],charsmax(query) - que_len, "SELECT * FROM %s WHERE `Login` = '%s'",g_szRankTable, login);


                new sData[EXT_DATA_STRUCT];
                sData[EXT_DATA__SQL] = SQL_LOAD;
                sData[EXT_DATA__INDEX] = id;
                sData[EXT_DATA__USERID] = get_user_userid(id);

                copy(sData[EXT_DATA__LOGIN], 31, login);
                copy(sData[EXT_DATA__EMAIL], 31, email);
                copy(sData[EXT_DATA__PASS], 31, pass);

                #if defined SQL_CHECKING_LOG
                server_print(" POST SQL_LOAD #1 | %s | %s | %s", login, pass, email);
                #endif

                SQL_ThreadQuery(g_hDBHandle, "selectQueryHandler", query, sData, sizeof sData);
            }
но после этого выбивает в консоль каракули вместо хоронящего в енуме
2 Окт 2019
19235
 

Download all Attachments

Сообщения
1,293
Реакции
2,294
Помог
57 раз(а)
Limbooc,
я правильно получаю данные?
это можно было самостоятельно проверить вот так
Код:
new login[32], email[32], pass[32];

login = data[EXT_DATA__LOGIN];
email = data[EXT_DATA__EMAIL];
pass = data[EXT_DATA__PASS];

#if defined SQL_CHECKING_LOG
server_print("PRE SQL_LOAD #1 | %s | %s | %s", login, pass, email);
server_print("PRE SQL_LOAD #1 | %s | %s | %s", data[EXT_DATA__LOGIN], data[EXT_DATA__EMAIL], data[EXT_DATA__PASS]);
#endif
Используй copy(), только в обратном порядке.
Код:
- login = data[EXT_DATA__LOGIN];
- email = data[EXT_DATA__EMAIL];
- pass = data[EXT_DATA__PASS];

+ copy(login, charsmax(login), sData[EXT_DATA__LOGIN]);
...
 
Сообщения
673
Реакции
242
Помог
11 раз(а)
BlackSignature, благодарю еще раз) выручил
2 Окт 2019
BlackSignature, енумы нужны обнулять? я имею ввиду мэйби другой игрок может взять енумы другого?
2 Окт 2019
или достаточно проверить на
Код:
if(!is_user_connected(id)) return PLUGIN_HANDLED;
            if(get_user_userid(id) == data[EXT_DATA__USERID])
            {
 

Ayk

Сообщения
763
Реакции
478
Помог
19 раз(а)
енумы нужны обнулять? я имею ввиду мэйби другой игрок может взять енумы другого?
Не надо. В твоём коде перед каждым запросом к БД массив создается заново.
Не может. Для этого и передаются экстра дата, чтобы при получении ответа знать к какому игроку/ид он относится.
 
Сообщения
2,491
Реакции
2,794
Помог
61 раз(а)
Limbooc, да ичпользуйте наконец датапак. Више бросали ссилкы на документацию.
 
Сообщения
144
Реакции
276
Помог
1 раз(а)
fantom, зачем городить огород с датапаками, когда сама функция запроса поддерживает передачу любого количества данных в любом формате ? Там всё сделано по уму и прекрасно работает.
 
Сообщения
144
Реакции
276
Помог
1 раз(а)
Чтобы не делать енумы.
Ну да, чтобы создавать датапаки и хранить структуру каждого датапака в голове... Нет, спасибо, лучше создать один енум и использовать его по всем запросам.
 
Сообщения
1,698
Реакции
1,510
Помог
26 раз(а)
Ну да, чтобы создавать датапаки и хранить структуру каждого датапака в голове...
Обычно это разбито по файлам и идет друг за другом, даже не нужно искать структуру.

лучше создать один енум и использовать его по всем запросам.
Как один енум, если данные для запросов разные?
 
Сообщения
2,491
Реакции
2,794
Помог
61 раз(а)
SISA, не спорю что enum-ы работают. Тут каждому свое. Но конкретно в данном случае datapack ИМХО более подходит.
 
Сообщения
144
Реакции
276
Помог
1 раз(а)
fl0wer, В одном плагине, как правило, данные для запросов практически идентичные.
 

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу