SA-MP Forums

Go Back   SA-MP Forums > Non-English > Languages > Русский/Russian

Reply
 
Thread Tools Display Modes
Old 06/05/2019, 12:05 AM   #1
Johhnyllll
Huge Clucker
 
Johhnyllll's Avatar
 
Join Date: Sep 2014
Posts: 247
Reputation: 12
Question MySQL запросы.

Приветствую.

Пытаюсь сделать мини систему знакомств и испытываю проблемы с запросами к MySQL базе уже 3 день, никак не могу найти более правильный вариант для решения данной проблемы.

Вот код:
1. При нажатии на нужный диалог, идет запрос к БД.
PHP Code:
DialogCreate:d_user_friends(playerid) {
    
getPlayerNameFromDB(playerid,
        
P[playerid][p_friends][0] != -? (P[playerid][p_friends][0]) : (-1),
        
P[playerid][p_friends][1] != -? (P[playerid][p_friends][1]) : (-1),
        
P[playerid][p_friends][2] != -? (P[playerid][p_friends][2]) : (-1)
        );
    
printf("1:%i\n2:%i\n3:%i\n4:%i\n5:%i\n6:%i\n7:%i\n8:%i\n9:%i\n10:%i\n11:%i\n",
    
P[playerid][p_friends][0], P[playerid][p_friends][1], P[playerid][p_friends][2], P[playerid][p_friends][3], P[playerid][p_friends][4], P[playerid][p_friends][5],
    
P[playerid][p_friends][6], P[playerid][p_friends][7], P[playerid][p_friends][8], P[playerid][p_friends][9], P[playerid][p_friends][10]);

Сама функция.
Закомментированная строка, это то что я использовал до этого.
PHP Code:
stock getPlayerNameFromDB(playeriduiduid1uid2){
    new 
query[256+1];
    
// mysql_format(g_MySQL_DB, query, sizeof(query), "SELECT * FROM `accounts` WHERE `UID` = '%i';SELECT * FROM `accounts` WHERE `UID` = '%i';SELECT * FROM `accounts` WHERE `UID` = '%i';", uid, uid1, uid2);
    
mysql_format(g_MySQL_DBquerysizeof(query), "SELECT * FROM accounts WHERE UID = '%i' OR UID = '%i' OR UID = '%i';"uiduid1uid2);
    
mysql_pquery(g_MySQL_DBquery"OnMySQL_GetNameByUID""iiii"playeriduiduid1uid2);
    return 
true;

Ну и сама обработка запроса.
PHP Code:
forward OnMySQL_GetNameByUID(playeriduid0uid1uid2);
public 
OnMySQL_GetNameByUID(playeriduid0uid1uid2) {
    new 
mysql_Name[24],
    
mysql_Name1[24],
    
mysql_Name2[24];
    if(
cache_num_rows() == 0)
        return 
SendClientMessage(playerid0xB22222FF"[Справка]: {FFFFFF}Ошибка [OnMySQL_GetNameByUID].");
    else {
        new 
rowsx;
        
cache_get_row_count(rows);
        
printf("rows: %i"cache_get_row_count(rows));
        
/* new result_count;
        if(!cache_get_result_count(result_count))
            return printf("couldn't retrieve result count");

        printf("we will now go through all %d results:", result_count);
        for(new r; r < result_count; r++)
        {
            cache_set_result(r);
            new rowss = cache_num_rows();
            printf("\t%d rows in %d. result", rowss, r+1);
        } */
        
printf("num rows: %d"cache_num_rows());
        
cache_get_value_name(0"Name"mysql_Name);
        
printf("1num rows: %d"cache_num_rows());
        
cache_get_value_name(cache_get_row_count(rows) + 1"Name"mysql_Name1);
        
printf("2num rows: %d"cache_num_rows());
        
cache_get_value_name(cache_get_row_count(rows) + 1"Name"mysql_Name2);
        
printf("rows end: %i"cache_get_row_count(rows));
        
printf("name: %s | 2: %s | 3: %s"mysql_Namemysql_Name1mysql_Name2);
    }
    return 
true;

Дело в том что, если cache_get_value_name поставить от 0 до 3-х,
т.е.
PHP Code:
cache_get_value_name(0"Name"mysql_Name);
cache_get_value_name(1"Name"mysql_Name1);
cache_get_value_name(2"Name"mysql_Name2); 
Всё будет работать хорошо, но только в "идеальных" условиях, когда все ID действительны и запрос с мог их обработать.

Если например сделать недействительным уже 2 ID, дав ему число -1 или 99, то оно уже выведет ошибку: cache_get_value_name: invalid row index '2'. И даже если на 3 запросе существует такой аккаунт, он уже не пройдет как успешный.

В идеале, всё должно идти так как в БД:



В чём мой вопрос:
Как можно улучшить запросы и их получения из БД, чтобы MySQL не выдавал ошибку, даже если не нашел такого результата и продолжил выполнять "команду"?
__________________
Мои проекты: GitHub
Johhnyllll is offline   Reply With Quote
Old 06/05/2019, 07:52 AM   #2
Stepashka
Godfather
 
Stepashka's Avatar
 
Join Date: Jul 2008
Location: near PC
Posts: 5,737
Reputation: 138
Default Re: MySQL запросы.

  1. Используйте IN() вместо OR...OR...
  2. Пользуйтесь циклом, а не просто обращайтесь к строкам которых может не быть.
__________________
Клятва Страуструпа: "Я обязуюсь прилежно комментировать свой код, не использовать goto и следить за состоянием своих потоков и выделяемой памяти. Я обязуюсь не оставлять мусора в системе и избегать однобуквенных переменных. Ресет." © Куч
M&M GM
Status: ON HOLD

Stepashka is offline   Reply With Quote
Old 06/05/2019, 09:52 AM   #3
Johhnyllll
Huge Clucker
 
Johhnyllll's Avatar
 
Join Date: Sep 2014
Posts: 247
Reputation: 12
Default Re: MySQL запросы.

Quote:
Originally Posted by Stepashka View Post
  1. Используйте IN() вместо OR...OR...
С IN() работает.
PHP Code:
[12:50:01] [INFOquery "SELECT * FROM accounts WHERE UID IN(1, -1, 2)" successfully executed within 0.439 milliseconds
[12:50:01] [DEBUGCResultSet::Create(connection=0x733c98query_str='SELECT * FROM accounts WHERE UID IN(1, -1, 2)')
[
12:50:01] [DEBUGcreated new resultset '0x5a934b8'
[12:50:01] [DEBUGfetched MySQL result '0x6e1100'
[12:50:01] [DEBUGallocated 488 bytes for PAWN result
[12:50:01] [DEBUGCCallback::Execute(amx=0x2bbad98index=45num_params=4)
[
12:50:01] [INFOExecuting callback 'OnMySQL_GetNameByUID' with 4 parameters...
[
12:50:01] [DEBUGprocessing internal specifier 'c'
[12:50:01] [DEBUGpushed value '2' onto AMX stack
[12:50:01] [DEBUGprocessing internal specifier 'c'
[12:50:01] [DEBUGpushed value '-1' onto AMX stack
[12:50:01] [DEBUGprocessing internal specifier 'c'
[12:50:01] [DEBUGpushed value '1' onto AMX stack
[12:50:01] [DEBUGprocessing internal specifier 'c'
[12:50:01] [DEBUGpushed value '0' onto AMX stack
[12:50:01] [DEBUGexecuting AMX callback with index '45'
[12:50:01] [DEBUGcache_get_row_count(0x03F12034) (C:\Users\lJohh\Desktop\Corso\Corso-San-Andreas\pawno\include\lib\a_mysql.inc:182 -> ..\source\mysql.inc:187)
[
12:50:01] [DEBUGcache_get_row_count: return value'1' (C:\Users\lJohh\Desktop\Corso\Corso-San-Andreas\pawno\include\lib\a_mysql.inc:182 -> ..\source\mysql.inc:187)
[
12:50:01] [DEBUGcache_get_row_count(0x03F12040) (..\source\mysql.inc:192)
[
12:50:01] [DEBUGcache_get_row_count: return value'1' (..\source\mysql.inc:192)
[
12:50:01] [DEBUGcache_get_row_count(0x03F12040) (..\source\mysql.inc:193)
[
12:50:01] [DEBUGcache_get_row_count: return value'1' (..\source\mysql.inc:193)
[
12:50:01] [DEBUGcache_get_row_count(0x03F12030) (C:\Users\lJohh\Desktop\Corso\Corso-San-Andreas\pawno\include\lib\a_mysql.inc:182 -> ..\source\mysql.inc:204)
[
12:50:01] [DEBUGcache_get_row_count: return value'1' (C:\Users\lJohh\Desktop\Corso\Corso-San-Andreas\pawno\include\lib\a_mysql.inc:182 -> ..\source\mysql.inc:204)
[
12:50:01] [DEBUGcache_get_value_name(0"Name"0x03F1210424) (..\source\mysql.inc:206)
[
12:50:01] [DEBUGcache_get_value_nameassigned value'Johhny' (..\source\mysql.inc:206)
[
12:50:01] [DEBUGcache_get_value_name: return value'1' (..\source\mysql.inc:206)
[
12:50:01] [DEBUGcache_get_value_name(1"Name"0x03F120A424) (..\source\mysql.inc:207)
[
12:50:01] [DEBUGcache_get_value_nameassigned value'Luciano' (..\source\mysql.inc:207)
[
12:50:01] [DEBUGcache_get_value_name: return value'1' (..\source\mysql.inc:207)
[
12:50:01] [DEBUGcache_get_value_name(2"Name"0x03F1204424) (..\source\mysql.inc:208)
[
12:50:01] [ERRORcache_get_value_nameinvalid row index '2' (number of rows'2') (..\source\mysql.inc:208)
[
12:50:01] [DEBUGAMX callback executed with error '0'
[12:50:01] [INFOCallback successfully executed

Quote:
Originally Posted by Stepashka View Post
  1. Пользуйтесь циклом, а не просто обращайтесь к строкам которых может не быть.
Не совсем понимаю что ты имеешь ввиду. Делать запросы по циклу, записывать куда то данные и потом их собрать?

Ещё я нашел пример с циклом из википедии MySQL:
PHP Code:
if(!cache_get_result_count(result_count)) return printf("couldn't retrieve result count");

printf("we will now go through all %d results:"result_count);
for(new 
rresult_countr++)
{
    
cache_set_result(r);
    new 
rowss cache_num_rows();
        
cache_get_value_name(0"Name"mysql_Name);
    
cache_get_value_name(rowss 1"Name"mysql_Name1);
    
cache_get_value_name(rowss 2"Name"mysql_Name2);
    
printf("\t%d rows in %d. result"rowssr+1);

Но он не особо работает...
__________________
Мои проекты: GitHub
Johhnyllll is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
MySQL запросы обрабатываются долго CamperGTA Русский/Russian 22 08/01/2015 11:36 PM
Многотабличные (сложные) запросы. Urukhay Русский/Russian 15 16/02/2014 07:10 AM
Запросы в MysqL R8 serpip Русский/Russian 17 19/10/2013 02:27 PM
Сервер не отвечает на запросы. Sanbody Русский/Russian 5 12/11/2012 08:54 AM
HTTP запросы. Отправка сообщений на e-mail. Gameyer Русский/Russian 9 18/08/2012 08:46 PM


All times are GMT. The time now is 05:08 AM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.