Skocz do zawartości
Mario

Dodawanie admina.

Rekomendowane odpowiedzi

Mam taką komendę:

CMD:dodaj_admina(playerid, params[])
{
    if(PlayerInfo[playerid][pAdmin] < 3) return SendClientMessage(playerid, -1, "Nie jesteś adminem.");
    new level, gracz[24];
    if(sscanf(params, "s[24]d", gracz, level)) return SendClientMessage(playerid, -1, "/dodaj_admina [Nickname][Level].");
    if(level < 1 || level > 3) return SendClientMessage(playerid, -1, "Level od 1 do 3.");
    new Query[500], query[300], string[128];
    format(query, 300, "SELECT `Nick` FROM `Gracze` WHERE `Nick` = '%s' LIMIT 1", gracz);
    mysql_query(Query);
    mysql_store_result();
    if(mysql_num_rows() > 0)
    {
        format(Query, 500, "UPDATE `Gracze` SET `Admin` = '%d' WHERE `Nick` = '%s' LIMIT 1", level, gracz);
        mysql_query(Query);
        mysql_free_result();
        format(string, sizeof(string), "Dodałeś admina %s level %d.", gracz, level);
        SendClientMessage(playerid, -1, string);
    }
    else
    {
        return SendClientMessage(playerid, -1, "Nie ma takiego konta w bazie danych.");
    }
    return 1;
}

 

Jak wpiszę w parametrach komendy odpowiedni nickname i level, wysyła mi wiadomość, że nie ma takiego konta w bazie danych (a tak na prawdę jest konto o takim nicku). Do tego w logach mam błędy od MySQL:

[MySQL] Error (0): Failed to exeute query. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL' at line 1.
 [MySQL] Error (0): Function: mysql_store_result called when no prior successful query executed. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL' at line 1.
[MySQL] Error (0): Function: mysql_num_rows called when no result stored. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL' at line 1.

 

Zapewne coś nie tak zrobiłem ze sscanfem, tak przypuszczam. Za pomoc like.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Według mnie format jest nie potrzebny. Spróbuj to zrobić w stocku. 

stock DajAdmina(tutajdajsobienazwezmiennej)

mysql_query(sprintf("UPDATE gracze SET 'Admin' = '%d' WHERE Nick = '%d'", pInfo[playerid][gracz_admin], pInfo[playerid][gracz_nick]));

 

a potem gdzies w kodzie dodaj poprostu DajAdmina(gracz);

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

mysql_query(sprintf("UPDATE gracze SET 'Admin' = '%d' WHERE Nick = '%d'", pInfo[playerid][gracz_admin], pInfo[playerid][gracz_nick]));

Przecież to nie zadziała, wysyłając zapytanie do bazy danych bez formatowania treści zapytania, jeżeli to potrzebne nic to nie da (dając %d, %s bez formatu). Do tego jak oznaczenie liczby typu int może zostać użyte do oznaczenia nicku gracza, skoro nick to ciąg znaków? :P I tak wychodzi na jedno, czy zrobię to za pomocą stocka czy bez. Błąd leży gdzieś w kodzie, który podałem.

Edytowane przez Mario

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
  1. Po prostu zrób print'y obydwu kwerend tuż po sformatowaniu.
  2. Po zapytaniach, dla których nie jest używane cache (np. INSERT, UPDATE, DELETE) nie stosuje się mysql_free_result().
  3. *Dla ciągu niecałych 80 znaków używasz zmiennej, która może pomieścić ich 500.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

1. Zaraz to sprawdzę i dam edit.

Edit

Printuje mi wszystko tak jak należy, jak dam w parametrach funkcji np. /dodaj_admina Gracz 1 to printuje prawidłowe dane.

2. Jak zostawię to mysql_free_result(); to coś będzie nie tak z kodem? Myślałem, że po każdej operacji związanej z bazą danych, należy tego używać, ale jak nie, to kiedy poprawnie użyć w/w funkcji?

3. W sumie to sam nie wiem, dlaczego taki duży rozmiar tablicy dałem, już to poskracałem. :)

Edytowane przez Mario

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
  1. Chodziło mi o:
    format(Query, 500, "UPDATE `Gracze` SET `Admin` = '%d' WHERE `Nick` = '%s' LIMIT 1", level, gracz); print(Query);
    Co masz na myśli przez słowo "dane"? Przecież nigdzie ich nie pobierasz (po w/w kwerendzie), chyba że jednak tak.
  2. Funkcji mysql_store_result() oraz mysql_free_result() używa się dla zapytań wymagających pamięci podręcznej dla zwróconego wyniku, tj. SELECT.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Zrobiłem tak:

format(query, 100, "SELECT `Nick` FROM `Gracze` WHERE `Nick` = '%s' LIMIT 1", gracz);
printf("`Nick` = '%s'", gracz);
        

oraz

format(Query, 150, "UPDATE `Gracze` SET `Admin` = '%d' WHERE `Nick` = '%s' LIMIT 1", level, gracz);
printf("`Admin` = '%d' WHERE `Nick` = '%s'", level, gracz);

Wyprintowało mi odpowiednie wartości, takie jakie podałem w parametrach komendy, a i tak dostaję wiadomość, że nie ma takiego konta w bazie danych (pomimo, że w bazie jest takie konto). Pisząc dane, chodziło mi o parametry komendy, że takie jakie podałem, zostały wyprintowane w konsoli serwera. :)

Edytowane przez Mario

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
new Query[500], query[300], string[128];
format(query, 300, "SELECT `Nick` FROM `Gracze` WHERE `Nick` = '%s' LIMIT 1", gracz);
mysql_query(Query);

Formatujesz zmienną 'query', a w funkcji mysql_query? Popraw i powinno być dobrze.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Tak w ogóle kwerenda SELECT jest w zupełności zbędna, można zostawić samą kwerendę UPDATE, a do sprawdzenia czy rekord został zmodyfikowany służy ta funkcja.

A co z tym?

[MySQL] Error (0): Failed to exeute query. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL' at line 1.

Chodziło o błąd w kwerendzie SELECT, więc nic dziwnego, że mysql_num_rows() zwraca 0. Natomiast funkcja mysql_query() zwraca 0 po prawidłowym wykonaniu zapytania albo kod błędu.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Teraz, PrzMas napisał:

Tak w ogóle kwerenda SELECT jest w zupełności zbędna, można zostawić samą kwerendę UPDATE, a do sprawdzenia czy rekord został zmodyfikowany służy ta funkcja.

Mógłbyś mi na przykładzie pokazać, jak użyć tej funkcji, np. na podstawie mojego kodu? Tej funkcji szczerze mówiąc nie widziałem jeszcze. :P

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
format(query, sizeof(query), "UPDATE `Gracze` SET `Admin` = '%d' WHERE `Nick` = '%s' LIMIT 1;", level, gracz);
if (!mysql_query(query) && mysql_affected_rows() > 0)
{
  // wprowadzono zmianę/y w bazie
}
else
{
  // nie wprowadzono zmian/y w bazie - błąd składni SQL albo konto nie istnieje
}

Przy porównywaniu przez = uwzględniana jest wielkość znaków, natomiast nie jest ona rozróżniana dla porównań LIKE.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dzięki wielkie za pomoc. Jeszcze miałbym jedno pytanie, bo niby to jest takie proste, jednak czasami zastanawiam się, czy dobrze robię. Jeżeli wykonuje się jakiś kawałek kodu, np. ten co Ty podałeś wyżej to mam zwracać 1 po tym, gdy dany warunek się będzie/nie będzie zgadzał? Znaczy się wiem, że jak czynność się wykona poprawnie to należy dać return 1;, jednak nie jestem pewien, czy w takim kodzie, gdzie wykonuje się jego kawałek w klamrach także należy zwracać 1, czy wystarczy return 1; na końcu kodu. :)

 

if (!mysql_query(query) && mysql_affected_rows() > 0)
{
  // wprowadzono zmianę/y w bazie
	SendClientMessage(playerid, -1, "Dodałeś admina.");
	return 1;
}
else
{
  // nie wprowadzono zmian/y w bazie - błąd składni SQL albo konto nie istnieje
	SendClientMessage(playerid, -1, "Nie ma takiego konta.");
	return 1;
}
Edytowane przez Mario

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Klauzula return jest wyjściem z bloku funkcji w miejscu, w którym została (ta klauzula) wywołana, z pominięciem wykonania znajdującego się po niej kodu - oznacza zakończenie działania funkcji i (opcjonalnie) zwrócenie określonej wartości funkcji, zależy czy dana funkcja ma zwracać wartość czy po prostu wykonywać jakieś działanie/a (tzw. procedura).

somefunc(argument)
{
  // blok funkcji 'somefunc'
  // wywołanie 'return' w tym miejscu pominie wykonanie poniższego kodu i zakończy działanie funkcji
  for(new i= 0; i < 10; i++)
  {
    // blok pętli
    // wywołanie 'continue' w tym miejscu pominie wykonanie poniższego kodu
    // wywołanie 'break' w tym miejscu pominie wykonanie poniższego kodu i przerwie działanie pętli
    // wywołanie 'return' w tym miejscu pominie wykonanie poniższego kodu, przerwie działanie pętli i zakończy działanie funkcji 'somefunc'
    if (i == 5)
    {
      // blok instrukcji warunkowej
    }
  }
  // blok funkcji 'somefunc'
}

*Klauzule continue i break można stosować tylko w pętlach (for(), while() i do...while()).

Edytowane przez PrzMas

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

  • Przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×