Skocz do zawartości

Witamy w Nieoficjalnym polskim support'cie AMX Mod X

Witamy w Nieoficjalnym polskim support'cie AMX Mod X, jak w większości społeczności internetowych musisz się zarejestrować aby móc odpowiadać lub zakładać nowe tematy, ale nie bój się to jest prosty proces w którym wymagamy minimalnych informacji.
  • Rozpoczynaj nowe tematy i odpowiedaj na inne
  • Zapisz się do tematów i for, aby otrzymywać automatyczne uaktualnienia
  • Dodawaj wydarzenia do kalendarza społecznościowego
  • Stwórz swój własny profil i zdobywaj nowych znajomych
  • Zdobywaj nowe doświadczenia

Dołączona grafika Dołączona grafika

Guest Message by DevFuse
 

Zdjęcie

MySQL - z czym to się je.


  • Nie możesz napisać tematu
  • Zaloguj się, aby dodać odpowiedź
30 odpowiedzi w tym temacie

#1 Owner123

    Wszechpomocny

  • Użytkownik

Reputacja: 146
Zaawansowany

  • Postów:331
  • Lokalizacja:Barty ;]
Offline

Napisano 17.06.2010 14:31

*
Popularny

Witam.
Na wstępnie chciałbym powiedzieć, że nie będę opisywał tu zapytań MySQL ponieważ to mija się z celem. Jeśli ktoś chce się pouczyć zapytań MySQL zapraszam na uw-team.org (nie wiem czy taka reklama jest dozwolona, jeśli tak to prosiłbym o nie wlepianie mi warna). Szczerze polecam Wideotutorial Unknow'a na temat MySQL.
Życzę miłej lekturki.

MySQL, cóż to takiego ?

Edit. Thx 4 R3X
SQL - Structured Query Language (pl. strukturalny język zapytań), jest to nowoczesny język, dzięki któremu można posługiwać się bazami danych. MySQL to popularna odmiana serwera, które potrafi przetwarzać zapytania w tym języku.

Przejdźmy do sedna.
Aby móc zacząć pracować, musimy dołączyć do swojego pluginu dyrektywą #include odpowiednią biblioteke:

#include <sqlx>


Dobra mamy już odpowiednie narzędzia aby zacząć

Są 2 metody, pracy na bazach danych. Ja opiszę tutaj sposób, który używam osobiście i który sprawdza się w wielu przypadkach (m.in. Diablo Mod).
Ta metoda opiera się tylko na utworzeniu "pojemnika" który przechowuje dane dostępowe do bazy danych i odpowiednim użyciu go.
Możemy go stworzyć funkcją SQL_MakeDbTuple:
native Handle:SQL_MakeDbTuple(const host[], const user[], const pass[], const db[], timeout=0);

Po kolei:
const host[] - adres Hosta. Np. db4free.net, 127.0.0.1
const user[] - login. np. root
const pass[] - hasło.
const db[] - nazwa bazy danych. np. nauka
timeout=0 - tego parametru nie będę opisywał. Najlepiej zostawić tak jak jest.

Przykładowe użycie:
new Handle:Tuple = SQL_MakeDbTuple("127.0.0.1", "root", "", "nauka")

Najlepiej aby zmienne, które są właśnie "pojemnikiem" były globalne.

W jaki sposób wykonać jakieś zapytanie ?

A więc tak, są 2 metody wykonywania zapytań do bazy danych:

- Bezpośrednia (NON-Threaded)
- Pośrednia (Threaded)

Poniżej postaram się opisać obie metody.

Pośrednia / Threaded

Ta metoda przy dużej ilości wpisów w bazie (30k++) zaczyna działać z dużym opóźnieniem, nie ważne na jak dobrym hostingu mamy ulokowaną bazę danych. Jednak jest o wieele bezpieczniejsza. Na czym polega jej bezpieczeństwo?
Otóż tą metodą otrzymujemy wynik później, jednak nie powoduje ona lagów - w przeciwieństwie do NON-Threaded (w niektórych przypadkach, które potem opiszę).

Aby posłuzyć się tą metodą jest funkcja SQL_ThreadQuery:
native SQL_ThreadQuery(Handle:db_tuple, const handler[], const query[], const data[]="", dataSize=0);


Handle:db_tuple - uchwyt do "pojemnika"(nie wiedziałem jak to inaczej określić). Niezbędny aby cokolwiek zrobić.
const handler - nazwa funkcji publicznej która zostanie wywołana PO wykonaniu zapytania.
const query[] - treść zapytania. Jeśli jest skomplikowane lub wymaga użycia %d lub %s to wtedy należy to odpowiednio przygotować komendą format().
Podziękowania dla G[o]Q.
const data[]="" oraz dataSize=0 - parametry opcjonalne.

data to jakby tablica parametrow a dataSize to ich ilosc tak jak parametry w set_task o czym jest osobny poradnik


Przykładowe użycie:

new Handle:gTuple, bool:gConnected
[...]
//Tworzymy "pojemnik" i ustawiamy zmienną gConnected na true jeśli wszystko obeszło się bez przeszkód.

SaveData(id)
{
if(!gConnected) return

new Data[1]
Data[0] = id
new qCommand[512], szName[32]
get_user_name(id, szName, charsmax(szName))
format(qCommand, sizeof qCommand-1, "INSERT INTO nauka VALUES(%s, %i, %i);", szName, iPlayerXP[id], iPlayerLvl[id])
SQL_ThreadQuery(gTuple, "SaveHandler", qCommand, Data, 1)
}

public SaveHandler(FailState, Handle:Query, Error[], Errorcode, Data[], DataSize)
{
new id = Data[0]
if(Errorcode)
log_amx("Blad w zapytaniu: %s [SaveData]", Error)

if(FailState == TQUERY_CONNECT_FAILED)
{
log_amx("Nie mozna podlaczyc sie do bazy danych.")
return PLUGIN_CONTINUE
}
else if(FailState == TQUERY_QUERY_FAILED)
{
log_amx("Zapytanie anulowane [SaveData]")
return PLUGIN_CONTINUE
}

return PLUGIN_CONTINUE
}


Oczywiście zamiast funkcji log_amx, możemy posłużyć się funkcją log_to_file.
Przedstawiłem tu zapis Nicku, Xp i Levela graczy do bazy MySQL.

A co z odczytem ?
Powyższa instrukcja spowoduje, dodanie kolejnego wpisu do bazy danych. Nie ważne czy taki wpis już istnieje czy nie.
Aby sprawdzić czy dany wpis istnieje musimy posłużyć się kolejnym zapytaniem:
new Handle:gTuple, bool:gConnected
[...]
//Tworzymy "pojemnik" i ustawiamy zmienną gConnected na true jeśli wszystko obeszło się bez przeszkód.

CheckData(id)
{
if(!gConnected) return

new Data[1]
Data[0] = id
new qCommand[512], szName[32]
get_user_name(id, szName, charsmax(szName))
format(qCommand, sizeof qCommand-1, "SELECT * FROM `nauka` WHERE `nick` = '%s'", szName)
SQL_ThreadQuery(gTuple, "CheckHandler", qCommand, Data, 1)
}

public CheckHandler(FailState, Handle:Query, Error[], Errorcode, Data[], DataSize)
{
new id = Data[0]
if(Errorcode)
log_amx("Blad w zapytaniu: %s [CheckData]", Error)

if(FailState == TQUERY_CONNECT_FAILED)
{
log_amx("Nie mozna podlaczyc sie do bazy danych.")
return PLUGIN_CONTINUE
}
else if(FailState == TQUERY_QUERY_FAILED)
{
log_amx("Zapytanie anulowane [CheckData]")
return PLUGIN_CONTINUE
}

if(!SQL_MoreResults(Query)) // Nie znaleziono wpisów w bazie danych. Możemy spokojnie utworzyć.
DodajWpis(id)
else // A jednak coś znalazł ! Żeby nie robić kolejnej funkcji od razu odczytujemy.
{
iPlayerXp[id] = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "exp")) // Ponieważ funkcja SQL_ReadResult wymaga ID pola, a my go nie mamy musimy posłużyć się funkcją SQL_FieldNameToNum.
iPlayerLvl[id] = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "lvl")) // j/w
}

return PLUGIN_CONTINUE
}


Tutaj za wiele chyba tłumaczyć nie muszę. Sprawdzamy czy rekordy w bazie danych istnieją. Jeśli nie, to dodajemy, ale jak istnieje od razu odczytujemy dane.

Przechodzenie z jednego wpisu do drugiego
Załóżmy, że zapytanie SELECT zwróci nam kilka rekordów. Powyższa metoda nie zadziała poprawnie albo zadziała inaczej niż przewidywaliśmy.
Wtedy przydatna jest komenda SQL_NextRow(Handle:Query).
Przykład (zaczerpnięty z DiabloModa):
while(SQL_MoreResults(Query))
{
new i = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "klasa"))
srv_avg[i] = SQL_ReadResult(Query, SQL_FieldNameToNum(Query, "AVG"))
SQL_NextRow(Query)
}

Jak zapewne wiadomo - klas w Diablo Modzie jest 8. Zatem zapytanie powyższe zapytanie SELECT odczyta zawartość tylko dla Maga a dla reszty nic by to nie zmieniło. Tutaj zastosowano pętle while która sprawdza czy nadal są jakieś zapytania, jeśli już nie ma - przerwij. Jak już wspomniałem funkcja SQL_NextRow powoduje przeskoczenie z jednego zapytania na drugie, zmniejszając przy tym wartość zwracaną funkcji SQL_MoreResults().

Dla tych co nie rozumieją zbytnio mechanizmu działania
No dobrze. Zapytanie SELECT zwróciło nam 3 rekordy. Chcemy odczytać wszystkie 3, więc tutaj musimy użyć naszej funkcji - SQL_NextRow. Ponieważ, funkcja SQL_MoreResults zwraca ilość rekordów które zostały do odczytania jeśli nic nie zrobiliśmy ma obecnie wartość 3. Dla pomocy kod:
while(SQL_MoreResults(Query))
{
//kod
SQL_NextRow(Query)
}

Po pierwszym obrocie pętli przesuneliśmy się z rekordu pierwszego, na rekord drugi i już wartość zwracana przez funkcje SQL_MoreResults(Query) ma obecnie 2. Teraz możemy bez przeszkód odczytać zawartość kolejnego rekordu.

NOWE!!!
Bezpośrednia / NON-Threaded
Ta metoda daje natychmiastowy zwrot rezultatu ALE pod warunkiem że bazę danych mamy ulokowaną na tej samej maszynie co serwer. W przeciwnym wypadku na serwerze będą ściny serwera i masakryczne pingi.
Aby móc zacząć robić cokolwiek musimy się wpierw połączyć z bazą:

Handle:SQL_Connect(Handle:sqlTuple, &error, szError[], len);

I tutaj strzeżcie się! Pamiętajcie aby ZAWSZE użyc SQL_FreeHandle(Handle:db) jak skończycie majstrować z bazą ! Jak tego nie będziecie robić, serwer będzie crashować bez żadnych error logów. Przykładowe połączenie z bazą wygląda następująco:

public client_authorized(id)
{
new Handle:hConnection, iError, szError[256];

if((hConnection = SQL_Connect(g_hSqlTuple, iError, szError, 255)))
{
// operacje na bazie danych
}
else
{
log_error(AMX_ERR_GENERAL, "Brak polaczenia z baza danych !");
log_error(AMX_ERR_GENERAL, "Kod bledu: %i", iError);
log_error(AMX_ERR_GENERAL, "Tresc bledu: %s", szError);
}

SQL_FreeHandle(hConnection); // PAMIETAJ O TYM BO INACZEJ CZEKA CIE ZGUBA !!!
}


I co to daje ? W metodzie pośredniej takie coś było zbędne!
Otóż użycie tego daje nam możliwość bezpośredniego wprowadzania zapytań do bazy danych. Aby wprowadzić zapytanie musimy użyć 2 funkcji:

Handle:SQL_PrepareQuery(Handle:connection, fmt[], any:...);
bool:SQL_Execute(Handle:query);

Dla ścisłości: funkcja SQL_Execute naprawdę nie zwraca typu bool tylko typ int. Jednak napisałem bool aby uświadomić Tobie, Drogi czytelniku, aby ta funkcja zwraca tylko wartości 1 i 0 aby nas poinformować o tym czy wykonanie zapytania SQL przebiegło poprawnie.
Przejdźmy do małego opisu parametrów:
SQL_PrepareQuery:
Pierwszy parametr:
Uchwyt zwrócony przez funkcje SQL_Connect. Tak, właśnie dlatego było nam potrzebne ręczne połączenie się z bazą!
Drugi i reszta parametrów: Treść zapytania. Jest to w miarę elastyczne ponieważ możemy używać znacznikow %d, %s itd. Uwaga! Nie zalecam używanie tu zapytań typu UPDATE ! Zamiast tego polecam użycie zapytań REPLACE, jednak aby działały one poprawnie wymagane jest utworzenie klucza PRIMARY, UNIQUE lub INDEX. Dlaczego? Nawet jeśli kod jest w pełni zoptymalizowany i baza danych stoi na localhoscie, przy dużej ilości rekordów (100k+, czasem 50k+) powodowane są ścinki i lagi serwera.
Rezultat: Uchwyt do wykonania zapytania. Ta funkcja tylko przygotowuje zapytanie !!! Zapytanie jest wykonywane dopiero przy użyciu funkcji SQL_Execute()! I niech was ręka boska broni! Tutaj też uzywajcie funkcji SQL_FreeHandle()!!! Tak samo jak w przypadku SQL_Connect nie użycie tego powoduje crashe serwera bez żadnych logów!

SQL_Execute:
Jest tutaj tylko jeden parametr: Uchwyt zwrócony przez funkcje SQL_PrepareQuery. Wykonanie tej funkcji jest równoznaczne z wywołaniem zapytania, wcześniej przygotowanego przez funkcje SQL_PrepareQuery.

Dobra koniec teorii, czas na podanie przykładowego kodu:

public client_authorized(id)
{
new Handle:hConnection, iError, szError[256];

if((hConnection = SQL_Connect(g_hSqlTuple, iError, szError, 255)))
{
new szNick[32];
get_user_name(id, szNick, 31);

new Handle:hQuery = SQL_PrepareQuery(hConnection, "SELECT * FROM tabela WHERE `nick` = '%s'", szNick);

if(SQL_Execute(hQuery))
{
new num = 0;
while(SQL_MoreResults(hQuery))
{
num = SQL_ReadResult(hQuery, SQL_FieldNameToNum(hQuery, "klasa"));
g_iPlayerLvl[id][num] = SQL_ReadResult(hQuery, SQL_FieldNameToNum(hQuery, "lvl"));
g_iPlayerExp[id][num] = SQL_ReadResult(hQuery, SQL_FieldNameToNum(hQuery, "exp"));
SQL_NextRow(hQuery)
}
}
else
{
SQL_QueryError(hQuery, szError, 255);
log_error(AMX_ERR_GENERAL, "Blad w zapytaniu !");
log_error(AMX_ERR_GENERAL, "Kod bledu: %i", iError);
log_error(AMX_ERR_GENERAL, "Tresc bledu: %s", szError);
}

SQL_FreeHandle(hQuery); // Niech was reka boska broni, przed zapomnieniem o tym
}
else
{
log_error(AMX_ERR_GENERAL, "Brak polaczenia z baza danych !");
log_error(AMX_ERR_GENERAL, "Kod bledu: %i", iError);
log_error(AMX_ERR_GENERAL, "Tresc bledu: %s", szError);
}

SQL_FreeHandle(hConnection);
}


Dałem kod razem z SQL_Connect abyście dobrze widzieli w jaki sposób posługiwać się uchwytem do połączenia.

Jak zapewne widać zmian w korzystaniu z SQL_ReadResult i SQL_NextRow nie ma.

Na tym kończę ten tutorial!

Myślę że opisałem najważniejsze rzeczy. Jeśli ktoś chce poznać resztę funkcji które oferuję biblioteka sqlx wystarczy zajrzeć do pliku sqlx.inc który znajduję się w addons/amxmodx/scripting/include. Co prawda po angielsku, ale chyba z jakiejś przyczyny powstały tłumacze internetowe, prawda ? Dobrym punktem odniesienia jest Diablo Mod. Posiada on szereg funkcji dzięki którym możemy majstrować w bazie MySQL.

Wszelkie błędy, niedopowiedzenia oraz literówki lub inne badziewa, proszę zgłaszać w tym temacie.
Wszelka krytyka mile widziana smile.gif


Użytkownik GwynBleidD edytował ten post 25.03.2015 22:26

  • +
  • -
  • 31

#2 R3X

    Godlike

  • Przyjaciel

Reputacja: 2 987
Godlike

  • Postów:4 248
  • Lokalizacja:Nie
Offline

Napisano 17.06.2010 16:14

Na pewno przydatny artykuł :)

Drobna poprawka
- SQL to nazwa języka, MySQL to popularna odmiana serwera, które potrafi przetwarzać zapytania w tym jezyku.
  • +
  • -
  • 1

#3 G[o]Q

    I'm G[o]Q

  • Przyjaciel

Reputacja: 1 344
Godlike

  • Postów:3 563
  • Steam:steam
  • Imię:Krzysiek
  • Lokalizacja:C: / program Files / Valve / Cstrike / G[o]Q.dem
Offline

Napisano 17.06.2010 16:19

hmm zamiast pojemnik uzyl bym uchwyt ale to twoj tutek

a co do


native SQL_ThreadQuery(Handle:db_tuple, const handler[], const query[], const data[]="", dataSize=0);

to data to jakby tablica parametrow a dataSize to ich ilosc tak jak parametry w set_task o czym jest osobny poradnik

+ bo widac ze jednak sie nameczyles i dobrze jest to zrobione :D
  • +
  • -
  • 1
Manual ponad wszystko, konsola ponad manual :D :&

Chcesz wysłać do mnie PW ? użyj nazwy GoQ zamiast G[o]Q
Chcesz Kupić moduł płatności via Pukawka,Tserwery, Gamesol, Zabijaka do mojego sklepu? napisz PW cena to tylko 10 zł/sztuka

GG:6022845 (nie pomagam za free osobom ponizej rangi MoD) :D

#4 Owner123

    Wszechpomocny

  • Autor tematu
  • Użytkownik

Reputacja: 146
Zaawansowany

  • Postów:331
  • Lokalizacja:Barty ;]
Offline

Napisano 17.06.2010 16:19

@R3X
Dzięki ;)
Poprawione.
@Go[Q]
Uchwyt też dobre, ale mi się to kojarzy z takim właśnie pojemnikiem. Do pojemników wkładamy różne rzeczy, tutaj ze zmiennej robimy właśnie taki pojemnik który przechowuje adres hosta, login, hasło i nazwę bazy danych.

Użytkownik Owner123 edytował ten post 17.06.2010 16:22

  • +
  • -
  • 0

#5 G[o]Q

    I'm G[o]Q

  • Przyjaciel

Reputacja: 1 344
Godlike

  • Postów:3 563
  • Steam:steam
  • Imię:Krzysiek
  • Lokalizacja:C: / program Files / Valve / Cstrike / G[o]Q.dem
Offline

Napisano 17.06.2010 16:27

jak uwazasz wazne ze chodzi o to samo xD
  • +
  • -
  • 0
Manual ponad wszystko, konsola ponad manual :D :&

Chcesz wysłać do mnie PW ? użyj nazwy GoQ zamiast G[o]Q
Chcesz Kupić moduł płatności via Pukawka,Tserwery, Gamesol, Zabijaka do mojego sklepu? napisz PW cena to tylko 10 zł/sztuka

GG:6022845 (nie pomagam za free osobom ponizej rangi MoD) :D

#6 Owner123

    Wszechpomocny

  • Autor tematu
  • Użytkownik

Reputacja: 146
Zaawansowany

  • Postów:331
  • Lokalizacja:Barty ;]
Offline

Napisano 17.06.2010 17:45

Zgadza się, ważne że chodzi o to samo ;)
Możliwe że jeszcze dziś opiszę drugą metodę (prawdopodobnie szybsza, ale nie jest to potwierdzone).
  • +
  • -
  • 0

#7 G[o]Q

    I'm G[o]Q

  • Przyjaciel

Reputacja: 1 344
Godlike

  • Postów:3 563
  • Steam:steam
  • Imię:Krzysiek
  • Lokalizacja:C: / program Files / Valve / Cstrike / G[o]Q.dem
Offline

Napisano 17.06.2010 17:50

od siebie dodam ze po stworzeniu uchwytu/pojemnika mozna uzyc


Handle:SQL_Connect ( Handle:cn_tuple, &errcode, error[], maxlength )


zeby sie polaczyc z baza chociaz tego nie sprawdzalem :D

17 czerwiec 2010 - 18:50:
im wiecej rzeczy opisanych tym lepiej a alternatywne sposoby moga sie tez niektorym przydac :D

Użytkownik G[o]Q edytował ten post 17.06.2010 17:52

  • +
  • -
  • 0
Manual ponad wszystko, konsola ponad manual :D :&

Chcesz wysłać do mnie PW ? użyj nazwy GoQ zamiast G[o]Q
Chcesz Kupić moduł płatności via Pukawka,Tserwery, Gamesol, Zabijaka do mojego sklepu? napisz PW cena to tylko 10 zł/sztuka

GG:6022845 (nie pomagam za free osobom ponizej rangi MoD) :D

#8 Owner123

    Wszechpomocny

  • Autor tematu
  • Użytkownik

Reputacja: 146
Zaawansowany

  • Postów:331
  • Lokalizacja:Barty ;]
Offline

Napisano 17.06.2010 18:00

Właśnie o tym mam zamiar napisać ;)
Tylko że jeśli chcemy pracować w ten sposób już nie możemy użyć funkcji SQL_ThreadQuery.
  • +
  • -
  • 0

#9 R3X

    Godlike

  • Przyjaciel

Reputacja: 2 987
Godlike

  • Postów:4 248
  • Lokalizacja:Nie
Offline

Napisano 17.06.2010 18:10

Dobrze, że opisałeś tylko SQL_ThreadQuery, bo ta funkcja wykonuje zapytanie asynchronicznie (tworzy wątek). W drugiej metodzie serwer czeka na odpowiedź MySQLa i robi się lag.
  • +
  • -
  • 1

#10 G[o]Q

    I'm G[o]Q

  • Przyjaciel

Reputacja: 1 344
Godlike

  • Postów:3 563
  • Steam:steam
  • Imię:Krzysiek
  • Lokalizacja:C: / program Files / Valve / Cstrike / G[o]Q.dem
Offline

Napisano 17.06.2010 18:17

mozesz opisac chociaz jak dla mnie ta metoda szybsza i lepsza m.in z powodu ktory podal R3X :D
  • +
  • -
  • 0
Manual ponad wszystko, konsola ponad manual :D :&

Chcesz wysłać do mnie PW ? użyj nazwy GoQ zamiast G[o]Q
Chcesz Kupić moduł płatności via Pukawka,Tserwery, Gamesol, Zabijaka do mojego sklepu? napisz PW cena to tylko 10 zł/sztuka

GG:6022845 (nie pomagam za free osobom ponizej rangi MoD) :D

#11 Owner123

    Wszechpomocny

  • Autor tematu
  • Użytkownik

Reputacja: 146
Zaawansowany

  • Postów:331
  • Lokalizacja:Barty ;]
Offline

Napisano 17.06.2010 18:27

Hmm rzeczywiście :o
Wniosek: używać SQL_ThreadQuery. Metoda druga przy dużej ilości zapytań SQL powoduje niezły lag serwera ...
Skoro tak to nie będę fatygować się w opisanie drugiej metody :F

Użytkownik Owner123 edytował ten post 17.06.2010 18:28

  • +
  • -
  • 0

#12 GwynBleidD

    Godlike

  • Przyjaciel

Reputacja: 1 869
Godlike

  • Postów:3 066
  • Steam:steam
  • Lokalizacja:Przemyśl
Offline

Napisano 20.06.2010 12:30

Zapomniano o SQL_FreeHandle! Trzeba zwolnić "pojemnik" gdy nie jest już potrzebny, najlepiej w plugin_end

public plugin_end() {
SQL_FreeHandle(gTuple);
}

Użytkownik GwynBleidD edytował ten post 20.06.2010 12:31

  • +
  • -
  • 1

NIE pomagam na PW. Nie trudź się, na zlecenia nie odpiszę... Od pomagania jest forum.
NIE zaglądam w tematy wysłane na PW. Jeśli są na forum to prędzej czy później je przeczytam. Jeśli mam co w nich odpisać, to odpiszę.
 
1988650.png?theme=dark


#13 Owner123

    Wszechpomocny

  • Autor tematu
  • Użytkownik

Reputacja: 146
Zaawansowany

  • Postów:331
  • Lokalizacja:Barty ;]
Offline

Napisano 20.06.2010 20:45

Freeing the tuple is not necessary,


  • +
  • -
  • 0

#14 Knopers

    Nie patrz tak na mnie !

  • Przyjaciel

Reputacja: 588
Wszechwiedzący

  • Postów:2 013
  • GG:
  • Steam:steam
  • Imię:Mateusz
  • Lokalizacja:Cz-wa
Offline

Napisano 22.06.2010 09:58

Najczęściej wyczyszczenie uchwytu pod koniec mapki powoduje error log nieraz nawet crashe, nie wiem dla czego, nie zagłębiałem się bardziej szczegółowo dlaczego.
I z tego co chyba pamiętam to po zmianie mapki są czyszczone z pamięci różnego rodzaju zmienne.
  • +
  • -
  • 0

#15 NesquiK

    Początkujący

  • Użytkownik

Reputacja: 0
Nowy

  • Postów:16
  • Imię:Sławek
  • Lokalizacja:Gliwice
Offline

Napisano 06.11.2010 17:41

wszystko wykonujemy w jakim pliku ? jak chce np do CODModa zrobic zapisywanie lv na MySQL to wszystkie operacje w pliku .sma? czy w bazie danych na serwerze?
  • +
  • -
  • 0

#16 Juma

    Wszechpomocny

  • Użytkownik

Reputacja: 64
Pomocny

  • Postów:373
  • GG:
  • Steam:steam
  • Imię:Arek
  • Lokalizacja:Haynau
Offline

Napisano 06.11.2010 18:15

sma :)


plus nie odkopuj tematów ;)

Użytkownik Juma edytował ten post 06.11.2010 18:16

  • +
  • -
  • 0

#17 GoldeN

    Wszechmogący

  • Zbanowany

Reputacja: 69
Pomocny

  • Postów:676
  • Imię:Kamil
  • Lokalizacja:DG
Offline

Napisano 01.02.2011 22:47

A mógłby ktoś napisać gotowy kod zapisu? Bo tam jest DodajWpis(id) a takiej funkcji nie ma...

#18 Svizz

    Zaawansowany

  • Użytkownik

Reputacja: 33
Życzliwy

  • Postów:142
  • GG:
  • Imię:Svizz
  • Lokalizacja:Polska :)
Offline

Napisano 03.05.2011 12:41

Witam, odkopuje, bo mam powód :) No właśnie, dałeś funkcję DodajWpis, a nie podałeś jej treści...
  • +
  • -
  • 0

#19 R3X

    Godlike

  • Przyjaciel

Reputacja: 2 987
Godlike

  • Postów:4 248
  • Lokalizacja:Nie
Offline

Napisano 03.05.2011 13:01

DodajWpis powinno wykonać zapytanie INSERT INTO zgodne ze schematem tabeli. Dokładnie to robi funkcja SaveData z przykładu wyżej
  • +
  • -
  • 0

#20 Svizz

    Zaawansowany

  • Użytkownik

Reputacja: 33
Życzliwy

  • Postów:142
  • GG:
  • Imię:Svizz
  • Lokalizacja:Polska :)
Offline

Napisano 03.05.2011 17:41

Ok dzięki wielkie :) Zaczynam już trochę rozumieć sqlx. Muszę jeszcze poczytać o zapytaniach sql.
  • +
  • -
  • 0




Użytkownicy przeglądający ten temat: 0

0 użytkowników, 0 gości, 0 anonimowych