edward
Rejestracja: 2009-09-10, 09:52 Posty: 40
|
Działanie na dużych bazach
Witam,
Mam następujący problem w Handel Premium. Muszę przeglądać kilka baz (m.in SM, TW, BP) i zapisywać niektóre dane do pliku. Problem w tym że te bazy są bardzo duże np. jedna z nich ma ok. 100MB i nie wiem jak sobie poradzić żeby się nie zawieszał. Do przeglądania baz używam pętli while. Na poczatku ustawiam int bufor = tw.getrec(FS) a pozniej w kazdym przebiegu petli bufor = tw.getrec(NX) i w taki sposob analogicznie przegladam cale te bazy (niektore zagniezdzone w innych) i potrzebne dane zapisuje sobie do tablicy. Dla wersji demo z malymi bazami to dziala jednak zawiesza sie w przypadku wspomnianych duzych baz. Jak mozna zapobiec temu albo jak zablokowac dzialanie raportu gdy nastapi jakis blad (aktualnie mam tylko obsluge bledow baz baseError (nrBazy, 4))? Z góry dziękuję za pomoc.
Pozdrawiam
|
Autor |
Wiadomość |
Mix-soft.pl
|
|
|
rafal
Ekspert
Rejestracja: 2007-11-16, 15:08 Posty: 3999 Pomógł: 447
|
Każdy raport można przerwać wciskając Esc na klawiaturze.
Jeżeli nie możesz w ten sposób przerwać swojego raportu zastanowiłbym się nad tym czy dobrze go napisałeś.
Pokaż go to coś poradzimy.
Możesz jeszcze się zastanowić czy użycie FS i NX jest konieczne czy tez nie mógłbyś wesprzeć się jakimś kluczem.
|
2009-09-22, 14:07 |
|
|
edward
Rejestracja: 2009-09-10, 09:52 Posty: 40
|
Esc nie podziala bo sie totalnie zawiesza Symfonia.
W takim razie jeszcze sam sprobuje sobie poradzic jesli nie podolam to wkleje kod wieczorem lub jutro rano.
|
2009-09-22, 14:09 |
|
|
edward
Rejestracja: 2009-09-10, 09:52 Posty: 40
|
Nadal zawiesza mi sie Symfonia dla duzych baz danych. Wklejam kod:
Kod: #define fsoForAppending 8
dispatch fso = "Scripting.FileSystemObject" dispatch f long licz long ile
Record defr
String dana1[10] String dana2[10] Float dana3
EndRec
Int nrBazy=Open "sciezka\\51tw.dat" For Base "TW" BaseError ("sciezka\\51tw.dat", 4)
ile = GetRecordCount(nrBazy)
Close nrBazy Close nrBazy2 Close nrBazy3
defr Tbl(ile)
limit 20000 baseSM sm sm.SetKey("id") sm.SetKeySeg("id",1)
baseBP bp bp.SetKey("id") bp.SetKeySeg("id",1)
baseTW tw tw.SetKey("id") tw.SetKeySeg("id",1)
long err1 = bp.getrec(FS) long err2 = sm.getrec(FS) long err3 = tw.getrec(FS)
licz = 1
while err3 == 0 && licz < ile
if tw.getfield("costam") == "10" then err2 = sm.getrec(FS) while err2 == 0
if sm.getfield("costam2") == 100 && tw.getfield("id") == sm.getfield("idtw") then err1 = bp.getrec(FS)
while err1 == 0 if sm.getfield("idtw") == bp.getfield("idtw") then //dopisywanie do tabeli potrzebnych danych
endif err1 = bp.getrec(NX)
wend endif
err2 = sm.getrec(NX) wend
endif
licz += 1 err3 = tw.getrec(NX) wend // zapisanie danych z tabeli do pliku
przy czym bazy TW i SM maja ok 15MB a baza BP ponad 100MB
help
|
2009-09-23, 12:11 |
|
|
Jarek75
Ekspert
Rejestracja: 2009-03-07, 11:13 Posty: 597 Pomógł: 34
|
Jak już kiedyś pisałem, z coma należy pod Symfonią korzystać tylko wtedy, kiedy nie da się osiągnąć porządanego efektu innymi sposobami.
|
2009-09-23, 14:13 |
|
|
barnie
Ekspert
Rejestracja: 2008-04-07, 13:26 Posty: 208 Pomógł: 2
|
widać gołym okiem że nieźle się w tym kodzie zapętliłeś.
latasz bo tych tabelach niepotrzebnie po kilka (tysięcy) razy od początku do końca.
no i ciekawe po co Ci ta baza BP?
zacznij używać indeksów.
|
2009-09-23, 21:34 |
|
|
edward
Rejestracja: 2009-09-10, 09:52 Posty: 40
|
mniej wiecej idea jest taka zeby znalezc w bazie BP zamowienia na towary ktore spelniaja pewne warunki tzn. dla ktorych stan magazynowy np = 10 i jeszcze w bazie TW dany towar musi spelniac jakis warunek - stad to zapetlanie.
co dokladniej masz na mysli z tymi indeksami? Jak inaczej mam wyciagnac te wszystkie zamowienia spelniajace pewne zalozenia(ktore sa w innych powiazanych bazach)?
|
2009-09-24, 08:23 |
|
|
Jarek75
Ekspert
Rejestracja: 2009-03-07, 11:13 Posty: 597 Pomógł: 34
|
Trudno tutaj coś poradzić. Barnie oczywiście ma rację. Jesteś początkującym programistą, a tutaj dają rady specyficzne dla Symfonii. Poczytaj sobie jakąś książkę o bazach danych, potem helpa, postudiuj przykłady itp. Indeksy, to komendy SetKey, SetKeySeg, GetRec(GE). Multum przykładów również na tym forum.
|
2009-09-24, 08:52 |
|
|
edward
Rejestracja: 2009-09-10, 09:52 Posty: 40
|
moim zdaniem indeksy nie rozwiaza problemu. Podobny odrobine problem jest tutaj:
http://forum.mojasymfonia.pl/viewtopic.php?t=910
odpowiedz rafala mowi o tym ze nie da sie inaczej przejrzec bazy jak rekord po rekordzie w celu wyszukania potrzebnych wartosci
|
2009-09-24, 09:37 |
|
|
rafal
Ekspert
Rejestracja: 2007-11-16, 15:08 Posty: 3999 Pomógł: 447
|
Jeden z pomysłów to:
1. Wyszukaj towary w bazie SM które spełniają Twój warunek i wpisz ich id do zmiennej typu MapValue. Możesz lecieść FS, NX lub z użyciem klucza idx_kod_stnz (pod kątem ilości)
2. Przeszukaj bazę BP za pomocą klucza idx_tw
porównuj to co znalazłeś w BP z zawartością MapValue
dzięki temu lecisz po bazach tylko jeden raz
3. W miedzyczasie czytasz bazę TW za pomocą klucza idx_id i EQ
I już. Odczujesz znaczne przyśpieszenie. Jakieś 1000 razy :)
|
2009-09-24, 13:10 |
|
|
edward
Rejestracja: 2009-09-10, 09:52 Posty: 40
|
dzieki, wyprobuje Twoja metode. Napisz mi tylko jeszcze czym jest to idx_tw. W bazie nie ma takiego pola.
|
2009-09-24, 13:57 |
|
|
wrob
Ekspert
Rejestracja: 2008-04-18, 18:52 Posty: 5169 Pomógł: 59
|
Pomysl troche przeciez idx_tw to skrot myslowy
|
2009-09-24, 14:41 |
|
|
rafal
Ekspert
Rejestracja: 2007-11-16, 15:08 Posty: 3999 Pomógł: 447
|
przykład użycia klucza idx_tw w bazie BP
Wypisuje wszystkie rekordy z bazy BP zawierające szukany towar.
Kod: baseBP bp bp.SetKey("tw") bpSetKeySeg("idtw", 65536)
err = bp.GetRec( GE ) while err == 0 if bp.GetField("idtw") != 65536 then exit
print using "Pozycja o ID = %l zawiera szukany towar."+lf, bp.GetField("id")
err = bp.GetRec( NX ) wend
|
2009-09-24, 19:10 |
|
|