PDA

Просмотр полной версии : [Вопрос] Mysql



DelAccount
28.09.2016, 01:01
Такой вопрос уже был на форуме давно, но решения на него по сей день нет.



Нужна система на MySQL с перелистыванием страниц, то есть в диалоге 10 записей выгрузило жмешь след страница, и тебе ещё 10 показывает... И в загаловке диалога показывать какая страница открыта, если открыта > 1 то кнопка след страница должна меняться на пред страница.

У кого какие мысли по этому поводу?

DeimoS
28.09.2016, 05:19
Эмм, касаемо SQL - всё просто

SELECT * FROM имя_таблицы WHERE условие LIMIT с_какой_строки_выгружать, сколько_строк_выгружать
То бишь

SELECT * FROM users WHERE money > 5 LIMIT 5, 10
такой запрос сначала найдёт все строки, которые подходят под условие "money > 5", после пропустит первые 5 строк и выгрузит следующие 10 (с 5-ой по 15-ую строки).



Главное понимай, что такой запрос сначала ищет строки по условию (срабатывает "money > 5"), а потом уже из этих строк выбирает нужные (срабатывает "LIMIT 5, 10")



В твоём случае нужно просто хранить в памяти номер открытой страницы и подставлять его в запрос

"SELECT * FROM имя_таблицы WHERE условие LIMIT %d*10, 10", переменная_с_номером_страницы

DelAccount
28.09.2016, 07:05
С самим запросом в принципе проблем нет, дело в том, что поиск идет еще и по слову (вместо money > 5 ищет слово в столбце и выгружает через цикл все найденные строки) командой /команда (текст) (страница). Сам запрос работает, а вот как хранить все это в памяти и потом делать запрос по новой в диалоге не совсем понимаю. То есть нужно хранить текст и страницу в пваре или глобальной переменной и в диалоге вызвать команду с этими параметрами, но к странице прибавить нужное значение?

DeimoS
28.09.2016, 15:38
С самим запросом в принципе проблем нет, дело в том, что поиск идет еще и по слову (вместо money > 5 ищет слово в столбце и выгружает через цикл все найденные строки) командой /команда (текст) (страница). Сам запрос работает, а вот как хранить все это в памяти и потом делать запрос по новой в диалоге не совсем понимаю. То есть нужно хранить текст и страницу в пваре или глобальной переменной и в диалоге вызвать команду с этими параметрами, но к странице прибавить нужное значение?

Ну я бы сделал как-то так:

CMD:list(playerid, params[])
{
if(isnull(params))
return SendClientMessage(playerid, -1, "/list <Номер страницы> <Текст>");

new page_number;
sscanf(params, "is[31]", page_number, params);

if(page_number <= 1) page_number = 0;
else page_number-=1;

if(strlen(params) > 30)
return SendClientMessage(playerid, -1, "Текст не может быть больше 30 символов");

SetPVarInt(playerid, "PageNumber", page_number);

/*
В запросе возвращаем не 10 строк, а 11, дабы понять, выгрузили ли мы этим запросом все данные из таблицы
или осталось что-то ещё.

Когда уже начнём работать с кэшем, работать будем лишь с 10-ю строками, а 11-ую трогать не будем.
Она нам нужна лишь для того, чтоб понять, нужно ли добавлять "Далее"
*/

new query_string[39+30+10+1];
format(query_string, sizeof(query_string), "SELECT * FROM users WHERE string = '%s' LIMIT %i, 11", params, page_number*10);
mysql_tquery(connectionHandle, query_string, "MysqlListForPlayer", "ii", playerid, page_number);
return 1;
}


forward MysqlListForPlayer(playerid, page_number);
public MysqlListForPlayer(playerid, page_number)
{
new string[...],
row_count;

cache_get_row_count(row_count);

switch(row_count)
{
case 0:
return SendClientMessage(playerid, -1, "Запрос вернул пустой результат (строк с указанным текстом не найдено)");
case 1:
{
cache_get_value_name(0, "column_name", string_destination, max_len);
cache_get_value_name_int(0, "column_name", int_destination);
cache_get_value_name_float(0, "column_name", float_destination);


format(string, sizeof(string), "%s %d %f", string_destination, int_destination, float_destination);

}
default:
{
new p = (row_count > 10 ? 10 : row_count);
for(new i; i < p, i++)
{
cache_get_value_name(i, "column_name", string_destination, max_len);
cache_get_value_name_int(i, "column_name", int_destination);
cache_get_value_name_float(i, "column_name", float_destination);


format(string, sizeof(string), "%s%s %d %f\n", string, string_destination, int_destination, float_destination);
}
}
}

switch(page_number)
{
case 0: {}
case 1: strcat(string, "Назад");
default:
{
strcat(string, "Назад");
if(row_count > 10) strcat(string, "\nДалее");
}
}
return ShowPlayerDialog(playerid, 666, DIALOG_STYLE_LIST, "caption", string, "Выбрать", "Закрыть");
}


public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
switch(dialogid)
{
case 666:
{
if(!response)
{
DeletePVar(playerid, "PageNumber");
return 1;
}

new page_number = -1;

if(!strcmp(inputtext, "Назад", false))
{
page_number = GetPVarInt(playerid, "PageNumber")-1;

}
else if(!strcmp(inputtext, "Далее", false))
{
page_number = GetPVarInt(playerid, "PageNumber")+1;
}
else
{
switch(listitem)
{
case 0:
{
// Действие
}
case 1:
{
// Действие
}
case 2:
{
// Действие
}
// ...
}
}

if(page_number != -1 && page_number != GetPVarInt(playerid, "PageNumber"))
{
SetPVarInt(playerid, "PageNumber", page_number);
new query_string[39+30+10+1];
format(query_string, sizeof(query_string), "SELECT * FROM users WHERE string = '%s' LIMIT %i, 11", params, page_number*10);
mysql_tquery(connectionHandle, query_string, "MysqlListForPlayer", "ii", playerid, page_number);
}
return 1;
}
}
return 1;
}

На работоспособность не проверял :dance: