SA-MP Forums

SA-MP Forums (https://forum.sa-mp.com/index.php)
-   Русский/Russian (https://forum.sa-mp.com/forumdisplay.php?f=32)
-   -   MySQL запросы. (https://forum.sa-mp.com/showthread.php?t=666367)

Johhnyllll 06/05/2019 12:05 AM

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 запросе существует такой аккаунт, он уже не пройдет как успешный.

В идеале, всё должно идти так как в БД:
https://cdn.discordapp.com/attachmen...70/unknown.png


В чём мой вопрос:
Как можно улучшить запросы и их получения из БД, чтобы MySQL не выдавал ошибку, даже если не нашел такого результата и продолжил выполнять "команду"?

Stepashka 06/05/2019 07:52 AM

Re: MySQL запросы.
 
  1. Используйте IN() вместо OR...OR...
  2. Пользуйтесь циклом, а не просто обращайтесь к строкам которых может не быть.

Johhnyllll 06/05/2019 09:52 AM

Re: MySQL запросы.
 
Quote:

Originally Posted by Stepashka (Post 4097782)
  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 (Post 4097782)
  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);


Но он не особо работает...


All times are GMT. The time now is 02:53 PM.

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