baze.podataka.212max.headroom,
Skeniranje indeksirane baze traje duže od skeniranja neindeksirane.
Razlog je jednostavan: kada FoxPro "guli" po indeksiranoj bazi on mora
da skače napred-nazad tražeći sledeći zapis u indeksu. Evo primera:
---------------------------------------------
VREDNOST (key) REDNI BROJ ZAPISA
---------------------------------------------
A 100,231
B 7
C 96,325
D 43
E 106,002
---------------------------------------------
Kada FoxPro krene da procesira ovu bazu po indeksiranom polju (key),
on prvo mora da skoči na record 100,231. Tada ide na rec. br. 7. Potom
na 96,325, pa na 43, i, najzad, na 106,002. Toliko skakanja ume da
oduzme dosta vremena :) Sada je jasno zašto Fox neindeksiranu bazu
pretrči za x sekundi manje od indeksirane. Ono što nije za pretposta-
viti je to da sortiranje baze po određenom ključu traje čak i kraće od
tih x sekundi.
Iako je SORTiranje često brže od korišćenja postojećeg indeksa,
postoje momenti kada SORT ne treba koristiti (čak i u slučaju da je
potrebno napraviti novi indeks). Evo nekih činjenica:
- Ako je u bazi manje od nekoliko hiljada zapisa, ili ako query vraća
manje od 50 zapisa, metoda koja se izabere nije ni bitna (SORT ili
ORDER).
- Uvek prvo koristite SQL SELECT pristup problemu.
U slučaju da je brzina ono što je neophodno potrebno, trebalo bi se
odlučiti između indeksiranja i SELECT...ORDER BY. Evo "rešenja":
IF (memo_postoji_i_postoji_sadržaj) .OR. (nedovoljno_mesta_za_SORT)
IF tag_postoji
SET ORDER
ELSE
INDEX ON
ENDIF
ELSE
IF zapisi_su_već_u_odgovarajućem_poretku
SET ORDER
ELSE
IF mnogo_zapisa
IF TAG
SET ORDER
ELSE
INDEX ON
ENDIF
ELSE
SORT / SELECT...ORDER BY
ENDIF
ENDIF
ENDIF
Evo kako dobiti bazu za slučaj "zapisi_su_već_u_odgov._poretku":
** COPY TO pristup
USE baza
SET ORDER TO ime
COPY TO temp
USE
ERASE baza.dbf
ERASE baza.cdx
USE temp
RENAME temp.dbf TO baza.dbf
USE baza
&& ponovo indeksiraj bazu
** SELECT...ORDER BY pristup
SELECT * FROM baza INTO TABLE temp ORDER BY ime
USE IN baza
USE IN temp
ERASE baza.dbf
ERASE baza.cdx
RENAME temp.dbf TO baza.dbf
USE baza
&& ponovo indeksiraj bazu
Ako vas brine ono "ponovo indeksiraj bazu" - džabe se brinete :)
Indeksiranje već sortirane baze (naravno, isti ključ) traje kratko.
baze.podataka.213max.headroom,
BROWSE KEY ili BROWSE FOR - šta je brže?
** Test program
DEFINE WINDOW prozor FROM 1,0 TO 20,75
CLOSE DATA
USE baza
t1 = SECO()
BROWSE FOR pol = "M" NOWAIT WINDOW prozor
t2 = SECO()
CLOSE DATA
USE baza ORDER pol
t3 = SECO()
BROWSE KEY "M" NOWAIT WINDOW prozor
t4 = SECO()
CLOSE DATA
USE baza ORDER pol
t5 = SECO()
BROWSE FOR pol = "M" NOWAIT WINDOW prozor
t6 = SECO()
----------------
Evo i rezultata (baza ima nekih 20,000 zapisa):
FOR 0.445 .
KEY 0.493 . LAN (SET EXCLUSIVE ON)
FOR sa SET ORDER 0.755 .
FOR 0.117 .
KEY 0.259 . LAN (SET EXCLUSIVE OFF)
FOR sa SET ORDER 0.749 .
Koristite BROWSE KEY kad kog možete. BROWSE FOR je fleksibilniji
pristup, ali sporiji. I, što je najzanimljivije, provalite rezultate -
ekskluzivno otvorena baza i sporiji pristup (!). Kažu da je ovo
primećeno samo na Novell-u, u sprezi sa query-jem koji je moguće
optimizovati a koji kao rezultat vraća mali broj zapisa.
baze.podataka.214max.headroom,
A-uh, problema...
Treba da uradim nekakav report na Epson LX-800 štampaču (znate ono
malo devetopinsko čudo). Papir je beskonačni, i sve ide lepo kada
report stane na jednu strane. Ali (agh!) čim se produži na dve-tri ili
više strana, posle prve otštampane strane printer mu daje EJECT i baca
me u nesvest. Tada report izgleda ovako:
---------------------------Prvi list
xxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxx
---------------------------Drugi list
<========================Ovde tera papir
xxxxxxxxxxxxxxxx
---------------------------Treći list
xxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxx
<========================Ovde ponovo EJECT (?!)
---------------------------žetvrti, itd...
U reportu sam izbacio sve "Paper Eject"-ove, dužina strane je 55
linija, tj. sve je standardno. Verovatno je do setovanja štampača. Ima
li neko iskustva sa ovim malim mučiteljem (LX-800)?
baze.podataka.215djelovic,
-> #214, max.headroom> U reportu sam izbacio sve "Paper Eject"-ove, dužina strane je 55
> linija, tj. sve je standardno. Verovatno je do setovanja štampača. Ima
> li neko iskustva sa ovim malim mučiteljem (LX-800)?
Biće da je štampač podešen da posle nekog broja linija sam uradi FF, ili ti
je možda loše podešena dužina strane? Za prvo je najčešće kriv pogrešno
postavljen džamper, a za drugo je potrebna ESC sekvenca na početku programa.
P.S. Odjednom si počeo da pišeš ovo obilje lepih poruka? Odakle taj iznenadni
entuzijazam? Na čemu god da si, daj i meni malo! :)
baze.podataka.216evlad,
-> #214, max.headroom>> A-uh, problema...
>>
>> Treba da uradim nekakav report na Epson LX-800 stampacu (znate ono
>> malo devetopinsko cudo). Papir je beskonacni, i sve ide lepo kada
Ponosni vlasnik LX-800 ti pomaze:
DIP switch group 2 (4 komada)
2-3 je skip over perforation on == 1 inch off == none
2-1 je set page length on == 12 inch off == 11 inch
so 2-3 stavis na off i 2-1 stavis na on i resen problem.
za IBM graficke karaktere
DIP switch group 1 (8 komada)
1-1 je set condenset or normal on == condenset off == normal
1-2 je set zero type on == 0 off == O
1-3 je set character table on == graphics off == italics
1-5 je set print qality on == NLQ off == draft
ako ti treba ostalo vici !
baze.podataka.217max.headroom,
-> #208, djelovic> Hm, ukoliko mi treba mogućnost da se neki slog stornira,
> ja ubacim bajt koji označava storniranje, umesto da ga
> brišem. Ukoliko je potrebna istorija
Da, u globalu se sve stornira (a malo toga konkretno i briše). Al'
vole korisnici onol'ko da brljaju, a posle... ko će sve to ispraviti i
vratiti u normalno stanje :)
> A kada smo dragisha i ja prigovarali Kliperašima što što
> za sve koriste tabele umesto da uposle adekvatne
> memorijske strukture, onda smo mi bili ludi,
Jooj :) Ali zašto praviti, iznova, čitav sistem za rad sa bazama kada
već isti postoji? Na samu pomisao da kreiram sopstveni BROWSE koji
samo izdaleka liči na Fox-ov, diže mi se kosa na glavi :) Ja nekako
praktikujem liniju manjeg otpora :)
> SET JEDINSTVENOIME=<neko ime>
Uh, vole njih petnaest odjednom pod isti user... To nemo'š ljudima
objasniti :) Možda da se za svakog usera definiše neki skup
identifikacionih znakova (3 ili 4) koji će se vući zajedno sa TMP
datotekom - posle bi, verovatno, olakšalo osmatranje sa servera kada
neka baza padne (mada nije tragedija jer su privremene, odn. kreiraju
se po startovanju određenog dela programa). Mene je mnogo više
zainteresovala ideja pravljenja neke Open f-je za baze, koja će videti
da baza (u slučaju da je heder ili indeks oštećen) nije otvorena i
preduzeti odgovarajući recovery. Ali... odakle mi source za taj
recovery program? :) Pokušao sam ja nešto i sam ali mi se rezultati ne
dopadaju (MEMO polja naprosto "odlepršaju").
baze.podataka.218max.headroom,
-> #209, mdrazic> - pošto sve izveštaje prvo pravim u fajl pa zatim gledam,
> editujem, pa ako treba da se štampaju, prosto pošaljem
> u neki queue ili na local. Za te potrebe u jednoj static
> varijabli čuvam brojač koji dodam na gorepomenuta tri
Ako je štampa u pitanju - ne treba praviti dva queue-a (jedan local,
jedan server). Ali se meni češće događa da je izveštaj potrebno
importovati u Excel ili Word, pa mora da stoji i kao file (beuh).
Ja pravim neki TMP stack svega toga, pa kada mi mreža javi da je stvar
"finito", skidam je sa steka. Inače, programski procesi imaju 3
početna slova procesa i random nastavak. A sve to ide u LOG file. Pa
onda traje, traje... Biraj: sigurnost ili brzina :)
> Problemi koji slede kod Visual Object-a: kod
> multitaskinga možeš kao jedan logovan user imati više Win
> procesa (na istoj stanici) istovremeno u aplikaciji u koju
> si se samo jednom logovao!
Elem, reši stvar: svakom programskom procesu dodeli neko ime, pa to
trpaj u neki privremeni stek. Ako user iz drugog taska pokuša da
pokrene isti programski deo (deluje nebulozno), zabrani :) Logično je
da neće da pravi isti izveštaj u oba taska. Ali postoji mogućnost da,
npr. reši da dobije vrednosti za dva različita vremenska perioda
(recimo, 1. task = pregled analitičkih kartica od 01.01.94 do
10.01.94, 2. task = isti pregled anal. kar. ali od 12.01.94. do
01.02.94.)... Tada je rešenje ubaciti i neki "komentar" u gorenavedeno
ime prog. procesa - a to je u ovom primeru datum.
baze.podataka.219max.headroom,
-> #210, pedjav> Pišem jednu malu C++ biblioteku klasa za rad sa bazom
> podataka. ====
A-uh :) Baci pogled u direktorijume, ili pitaj nekoga ko poseduje
nešto slično. Kao C-laik pretpostavljam da je u pitanju sizifovski
posao. Obrati se i u PC.PROG: razno, odn. kontaktiraj korisnika mjova.
baze.podataka.220max.headroom,
RUSHMORE
(Iliti - zašto je Fox brži od sličnih aplikacija)
Rushmore je naziv koji Microsoft upotrebljava da predstavi skup
algoritama i procedura koje koristi Fox da bi optimizovao query-je.
Generalno, kad god se zada neka komanda koja vrši pretragu za podatkom
(skupom podataka) koji odgovara zadatom uslovu, Fox koristi Rushmore
da se čitava stvar izvede što je brže moguće. Na primer, pretpostavimo
da imamo bazu faktura koja sadrži 680,000 istih (oko 50 MB na disku).
Zatim, pretpostavimo da želimo da vidimo koliko je cipela prodato
prošle nedelje...
SELECT COUNT(artikal), SUM(kolicina) ;
FROM fakture WHERE artikal = "cipele" .AND. ;
datum >= š24.08.94ć .AND. datum <= š31.08.94ć
Posle pretrage ispada da je za proteklih sedam dana urađeno 30 stavki,
odn. prodato 96 pari cipela. A čitava pretraga je trajala 1.38 sekundi
(!) Nije korišćen Cray, već odomaćena 486-ica na 50 MHz sa 8 MB RAM-a.
A sada - rešili smo da napravimo query za istu bazu, a rezultati će
odgovarati sledećem uslovu:
SELECT COUNT(artikal), SUM(količina) ;
FROM fakture WHERE artikal = "cipele" .AND. ;
datum >= š24.08.94ć .AND. datum <= š31.08.94ć ;
.AND. kolicina > 2
Daklem, tražimo slične podatke kao i malopre, ali sa još jednim
uslovom - da stavka sadrži minimum tri para cipela. Query je dao
rezultate za 0.02 sekunde. Ha!
ŠTA RUSHMORE ZAHTEVA?
Kada se zada komanda kojom tražimo određene podatke u bazi, Fox prvo
proverava da li je i kako je baza indeksirana. Ako određeni indeksi
postoje, Fox ih koristi za dobijanje rezultata a da nije ni pristupio
samoj bazi. Drugim rečima, da bi Rushmore dao rezultate potrebno je da
baza bude indeksirana. Takođe, potrebno je kao parametar poređenja (sa
vrednošću ključa) upotrebljavati isključivo statičke vrednosti (odn.
one koje se ne menjaju u toku vršenja same pretrage). Evo i
demonstracije pravilnog i nepravilnog korišćenja Rushmore sistema:
Kao prvo, kreira se baza:
Structure for table: c:ĐprogramiĐbaza.dbf
Number of data records: 106960
Date of last update: 02/05/93
Field Field Name Type Width Dec Index
1 IME Character 10 Asc
2 STAROST Numeric 10 Asc
3 DATRODJ Date 8 Asc
** Total ** 29
Select area: 1, Table in Use: C:ĐPROGRAMIĐBAZA.DBF Alias: BAZA
Structural CDX file: C:ĐPROGRAMIĐBAZA.CDX
Index tag: IME Key: IME+STR(STAROST,10)
Index tag: STAROST Key: STAROST
Index tag: DATRODJ Key: DATRODJ
Index tag: BILOSTA Key: DELETED()
Lock(s): Exclusive USE
Kao što se da videti, baza BAZA.DBF sadrži 106,960 zapisa i zauzima
oko 3.1 MB prostora na disku.
Prvi query koristi Rushmore na pravilan način, i to da bi se dobili
svi zapisi u kojima je STAROST 10 godina:
mvar = 10
SELECT * FROM baza WHERE starost = mvar
FoxPro vraća 33 zapisa za 0.22 sekunde. Ovaj primer se povrgava
pravilima Rushmore-a jer:
* Poredi statičku vrednost sa postojećom indeksiranom vrednošću
* Koristi =, <, >, <=, >=, <>, #, odn. != operator.
Sledeći primer je primer nepravilnog korišćenja Rushmore optimizacije:
LIST FOR ime = "B0"
Komandi je potrebno čitavih 16 sekundi da bi dobila i prikazala 35
zapisa. Nešto, očigledno, nije u redu. LIST komanda potpada pod one
koje se mogu Rushmore optimizovati - to, dakle, nije problem. Operator
= je takođe OK, a i konstanta "B0" je svakako statička vrednost.
Evo razloga: mi imamo indeksni tag "ime", ali se isti sastoji od
izraza IME+STR(STAROST,10)... Ponovimo komandu koristeći
LIST FOR ime + STR(starost, 10) = "B0"
Ovog puta sve traje 2.3 sekunde. Problem je bio u tome što navedeni
query uslov mora biti identičan onome iz indeksa. Evo još jednog
primera koji za vraćanje rezultata zahteva 23.78 sekundi (220 zapisa):
SELECT * FROM baza WHERE starost + 0 > 10 .AND. starost + 0 < 20
Zašto izračunavanje traje toliko dugo? Zato što nemamo tag koji sadrži
izraz STAROST + 0. Sledećem query-ju treba 4.7 sekundi za rezultat:
SELECT * FROM baza WHERE starost + 0 > 10 .AND. starost < 20
Znamo da deo query-ja STAROST + 0 > 10 nemože da se optimizuje, ali se
zato deo STAROST < 20 može optimizovati, a i Fox prepoznaje situaciju.
Dakle, Fox prvo izvuče rezultate za deo query-ja koji je moguće
optimizovati, pa zatim na njega primenjuje deo koji ne odgovara
Rushmore-u. To znači da nije potrebno indeksirati baš svako polje da
bi se dobila svemirska :) brzina.
Evo i spiska komandi koje, kombinovane sa SELECT...FOR, mogu biti
Rushmore optimizovane:
AVERAGE INDEX BROWSE LABEL
CALCULATE LIST CHANGE LOCATE
COPY TO RECALL COPY TO ARRAY REPLACE
COUNT REPORT DELETE SCAN
DISPLAY SORT EDIT SUM
EXPORT TOTAL
baze.podataka.221djelovic,
-> #217, max.headroom> > SET JEDINSTVENOIME=<neko ime>
>
> Uh, vole njih petnaest odjednom pod isti user... To nemo'š ljudima
> objasniti :)
Znam, nisam ni predlagao da se za jedinstveno ime koristi username, već,
pošto jedinstveno ime treba da bude jedinstveno za mašinu, broj konekcije
(connection number).
Varjanta dva jeste da na disku postoji nekakva prazna baza podataka, u
kojoj bi svaka radna stanica zaključavala po jedan slog odmah po ulasku u
program - i to, prvi ako može, pa ako ne može onda proba drugi, i tako do
N-tog. Taj jedan slog za sve vreme rada drži zaključan, i njegov redni broj
je *jedinstven*. Uzgredan plus ovog rešenja jeste što može da se ograniči
trenutan broj korisnika programa - zgodno ukoliko se prodaje licenca za
korišćenje na određenom broju mašina.
baze.podataka.222neman,
-> #221, djelovic> N-tog. Taj jedan slog za sve vreme rada drzi zakljucan, i
> njegov redni broj je *jedinstven*. Uzgredan plus ovog
> resenja jeste sto moze da se ogranici
A uzgred minus je situacija kada aplikacija pukne tj. neregularno :)
zavrsi rad.
baze.podataka.223djelovic,
-> #222, neman> A uzgred minus je situacija kada aplikacija pukne tj. neregularno :)
> zavrsi rad.
Zašto? Taj slog se otključa čim se korisnik sledeći put uloguje. Nema
nikakve nekonzistentnosti i nikakvog reindeksiranja jer je zapravo tabela
prazna - jedina svrha joj je međuprocesna konvencija.
baze.podataka.224nbatocanin,
-> #208, djelovic> Van toga, ne vidim neku potrebu za čuvanjem obrisanih slogova?
"Slušaj, došo mi juče mali i igrao se sa kompjuterom. Jel smeta nešto
što je izbrisao lager listu?"
>> posle upotrebe obrisane. Da ne bih gušio, poenta je u
>> sledećem: ako se ispostavi da neka temporary baza treba
>> da postoji, gurnite je u RAM disk. Manje-više što je
> brže, nego je _pouzdanije_.
Hm, ovo mi nije baš najjasnije. Zašto bi kreiranje u RAM disku bilo
sigurnije od kreiranja na disku? I kakve veze ima random ime sa
sadržajem baze?
baze.podataka.225nbatocanin,
-> #209, mdrazic> Problemi koji slede kod Visual Object-a: kod
> multitaskinga možeš kao jedan logovan user imati više Win
> procesa (na istoj stanici) istovremeno u aplikaciji u koju
> si se samo jednom logovao!
Kod moje koncepcije ovo ne utiče na program: svaki korisnik može
kreirati proizvoljan broj procesa koji nešto rade. Ekvivalent je da
se na klasičnom višekorisničkom sistemu uloguje na više terminala.
baze.podataka.226max.headroom,
-> #216, evlad> so 2-3 stavis na off i 2-1 stavis na on i resen problem.
Joj, to je :) Hvala - reko', Fox mi pobrljavio (a do sada nisam baš
previše kalemio sa matričnim štampačima; plus što nemam nikakav Ref.
menjual).
baze.podataka.227max.headroom,
-> #215, djelovic> P.S. Odjednom si počeo da pišeš ovo obilje lepih poruka?
> Odakle taj iznenadni entuzijazam? Na čemu god da si, daj i
> meni malo! :)
A-iii, tajna beskrajna :)) Ma, bacim ja pogled na topic, kad ono - 20
poruka u dva reda. Pa se setim da ovde 50% ljudi piše raznorazne
aplikacije koje, između ostalog, koriste i baze; pa mi deluje
neobično. A u "Računarima" stalno nekakav "umetak", ali nipošto nešto
konkretno. I tako, u krajnjem down-u, vidim da na SETNet-u (paramreža)
ima više poruka na zadatu temu nego ovde. I tu mi pade mrak na oči...
:)
P.S.
Još uvek su ljudi dosta tajanstveni kada treba objasniti princip rada
neke aplikacije, nedajbože pisane za Fox ili Clipper. Sve mislimo -
krademo jedni od drugih 'leba iz usta :) A ovo tržište, sa ovakvim
(floating) zakonima, nikada neće dobiti univerzalni program za
finansijsko, odn. materijalno knjigovostvo. Pa se ne plašim :)
P.P.S.
Program se ne prodaje sam - prodaje ga prodavac. Do debilnosti se
divim ljudima koji su pravili "jednostavni podsetnik sa kalendarom,
alias baza podataka" i prodavali ga (srećnih devedesetih) za 1000 DEM.
baze.podataka.228max.headroom,
SQL SELECT
SQL SELECT komanda daje rezultate izuzetno brzo, u sledećem
slučaju i pod sledećim uslovima: ako je moguće potpuno Rushmore
optimizovati, ako koristi samo jednu bazu, ako koristi polja samo
iz te jedne baze, ako ne koristi aliase za imena polja, ako nema
GROUP BY ili ORDER BY klauzule, i ako daje redirekciju rezultata
u "cursor".
Elem, umesto da se kopira rezultat jednog query-ja u posebnu bazu
(a taj query se vrši nad podacima iz samo jedne baze), FoxPro
pronalazi podatke koji odgovaraju zadatom uslovu, otvara istu
bazu u drugoj radnoj oblasti i uspostavlja filter sa uslovima
identičnim onima iz query-ja.
Dakle, koristeći brzinsku prednost SQL SELECT komande možemo dobiti
rezultate u obliku reporta, BROWSE-a, ili novih baza. Baze kreirane
SQL-om mogu biti permanentne (DBF) ili privremene ("cursor"). Dalje,
pošto je ANSI/ISO standardom definisano implementiranje klauzula u SQL
SELECT, query-ji se lako prenose sa FoxPro platforme na raznorazne
client-server primerke poput Oracle-a i SQL Server-a.
FROM parametar
--------------
Parametar (klauzula) FROM govori SQL-u gde da traži polja iz liste
polja. Ako su navedene baze zatvorene, FoxPro će ih otvoriti ali ne i
zatvoriti posle upotrebe. Ako su baze (baza) već otvorene, FoxPro ih
ponovo otvara pomoću USE...AGAIN komande. Pošto je baza ponovo
otvorena, Fox zahteva dodatnu radnu oblast, ali ne i dodatni file
handle. Po mogućnosti otvorite baze pre upotrebe SQL SELECT, jer je
vreme pristupa kraće.
Lista polja
-----------
Lista polja govori SQL SELECT-u koja polja treba uključiti u rezultat.
Ovaj parametar sledi odmah posle SELECT naredbe. Lista može sadržati
sledeće elemente:
- * (zvezdica) iliti "wildcard"
- Bilo koje polje iz baze navedene posle FROM parametra
- Bilo koju FoxPro f-ju
- Bilo koju SELECT f-ju za rad sa kolonama
- Bilo koju UDF
Primeri: SELECT ime,prezime FROM baza
SELECT * FROM baza
Ja preferiram da naznačim i ime radne oblasti ispred naziva polja
(npr. baza.ime), u slučaju da dva polja iz dve različite baze imaju
isto ime. U slučaju da ovo pravilo nije ispoštovano sledi i greška:
"<polje> đ <promenljiva> is not unique and must be qualified".
SQL i UDF-i (User Defined Functions)
------------------------------------
Kao što rekoh, FoxPro podržava upotrebu UDF-ova u SELECT listi polja.
Očigledno, druge implementacije tako dobijene SQL SELECT komande možda
neće raditi na različitim platformama. Ali postoji još jedan, malo
nezgodniji problem - pošto SELECT vrši kreiranje privremenih baza,
privremenih indeksa i privremenih relacija, UDF se ne sme oslanjati na
njihovo postojanje, niti na način na koji su one indeksirane ili
filtrirane. Još jedan problem je način na koji radi SQL parser: Ako se
u listu polja uključi promenljiva koja se inkrementira pri svakom
prolasku kroz UDF (brojač), da se uočiti da vrednost promenljive
odstupa za jedan prolaz. Drugim rečima, ako UDF broji record-e čiji je
sadržaj "X", vidi se da je krajnja vrednost veća za jedan od realnog
stanja u bazi.
SQL Parser
----------
Kada se query pusti u izvršavanje, FoxPro prvo razbije SELECT komandu
na delove, proveravajući njihovu sintaksu i druge run-time greške.
Zatim proverava postojanje navedenih baza i polja u bazama. Potom se
proverava da slučajno ne postoje dva polja istog imena u dve različite
baze (a da nisu navedena imena radnih oblasti). I na kraju se izvršava
UDF eventualno naveden u query-ju. Pošto FoxPro "proveri" UDF, UDF je
praktično izvršena, čak i pre nego što je bilo koji podatak iz baze
proveren. Eto zašto se UDF u query-ju izvršava jedanput više nego što
mi očekujemo.
Pošto je sintaksa SELECT-a proverena, na scenu stupa SQL optimizer. On
vrši optimizaciju prema sledećim kriterijumima:
- postoje li indeksi koji bi mogli ubrzati query?
- ako ne postoje, treba li ih kreirati "u hodu"?
- da li bi query trebao prvo da izvrši JOIN, pa tek potom doda
filtere i pod-filtere, ili obrnuto?
- može li FoxPro izbeći sekvencijalnu pretragu po bazama
kreirajući neku "međubazu"?
(nastavak o SQL sledi...)
baze.podataka.229max.headroom,
* Í─────────────────────────────────Ě
* ║ DB2PRG DESCRIPTION ║
* Ë─────────────────────────────────Ż
* While developing applications, use CREATE and MODIFY STRUCTURE as usual
* to create and modify data file structures.
* Just before distributing your application, use DB2PRG.PRG. The most
* current structure of each DBF will be recorded in the MAKEDBF.PRG
* generated.
* DB2PRG.PRG does not need to be distributed with an application, only
* the MAKEDBF.PRG it creates need be distributed with your application.
* Your applications could use the following code in it's initialization
* process to let it know if it needs to DO MAKEDBF:
*
* mmakedbf = .NOT. FILE('myfile1.dbf')
* mmakedbf = mmakedbf .OR. .NOT. FILE('myfile2.dbf')
* mmakedbf = mmakedbf .OR. .NOT. FILE('myfile3.dbf')
* * ... and so forth for every dbf file in the application
* IF mmakedbf
* DO makedbf
* * makedbf will only create missing files.
* * makedbf will never overwrite any dbf files that already exist.
* DO reindex && application specific reindexing procedure you supply
* ENDIF
* The author acknowledges John Bauman for his article "DBF'S ON THE FLY" in
* the August 1989 DATA BASED ADVISOR. The article ably proved the value of
* DBF from scratch capabilities. DB2PRG has incorporated adaptations of
* some of the methodologies described in John's article.
db2prg.arjbaze.podataka.230jmilovic,
Zanima me koji se software za baze podataka pokazao kao najbolji pod
UNIX operativnim sistemom ???
baze.podataka.231mdrazic,
-> #221, djelovic> Varjanta dva jeste da na disku postoji nekakva prazna baza
> podataka, u kojoj bi svaka radna stanica zaključavala po
> jedan slog odmah po ulasku u program - i to, prvi ako
> može, pa ako ne može onda proba drugi, i tako do N-tog.
> Taj jedan slog za sve vreme rada drži zaključan, i njegov
> redni broj je *jedinstven*. Uzgredan plus ovog rešenja
> jeste što može da se ograniči trenutan broj korisnika
> programa - zgodno ukoliko se prodaje licenca za korišćenje
> na određenom broju mašina.
Jest, a šta biva kada padne stanica: slog osta zaključan?
Kod mene kada user pristupa sistemu kada prođe password,
prvo mu prikažem ko je tada na sistemu i definišem njegov
proces (kao poslednji proces istog usera koji se trenutno
vrti + 1). Tada upišem u tabelu procesa da se logovao,
vreme, i tako to. Kod rada možeš ako želiš da u ovu
tabelu upisuješ šta radi user (gde je u meniju, koje
transakcije izvodi i slično), pa ovlašćeno lice :) može
prilično detaljno da gleda šta ko trenutno radi (dinamički).
Kada user izađe regularno, i to se registruje, pa oslobađa
proces. Kada padne stanica, to je serveru isto kao da
se ona duže vreme ne javlja. Tako posle pada vidiš da
postoji proces koji je poslednji put bio aktivan pre neka
tri sata i možeš da ga ukineš (pospremiš šta treba).
I ovde je trivijalno ograničiti istovremeni broj usera.
Milan
baze.podataka.232mdrazic,
-> #218, max.headroom> Ako je štampa u pitanju - ne treba praviti dva queue-a
> (jedan local, jedan server). Ali se meni češće
Za više štampača, više queue-ova; bar je meni tako lakše ;))
> Ja pravim neki TMP stack svega toga, pa kada mi mreža javi
> da je stvar "finito", skidam je sa steka. Inače,
Što da Novell ne brine o tome? A ti vozić dalje...
> Elem, reši stvar: svakom programskom procesu dodeli neko
> ime, pa to trpaj u neki privremeni stek. Ako user iz
Ima jedan manje-više pouzdan brojač: to je vreme. Informacija
o satu, minutu i sekundi može se spakovati u ne više od tri
čitljiva bajta. Kada tražiš od za to namenjene funkcije novo
tmp ime, na proj procesa sa logovanja dodaj ova tri bajta,
sačekaj sekundu (da zabraniš da neko otvori pet prozora u
sekundi:) i vrati tmp ime. Na ovaj način izbegavaš klasičan
brojač, ali praviš gužvu na disku ako ne brišeš ove fajlove.
Ima situacija kada ne znaš kada je fajl slobodan za brisanje
(print queue na primer). Sa klasičnim brojačem koristiš ista
imena fajlova kao u prethodnoj seansi, pa ih ima ipak ograničen
broj.
Više taskova sa klasičnim brojačem zahteva zapisivanje na
disk radi komunikacije sa drugim taskovima.
> drugog taska pokuša da pokrene isti programski deo
> (deluje nebulozno), zabrani :) Logično je da neće da
> pravi isti izveštaj u oba taska. Ali postoji mogućnost
Štaviše, uopšte nije nelogično, već vrlo verovatno.
Milan
baze.podataka.233pedjak,
-> #210, pedjav> po istoj datoteci i zapisu) moram nekako da izvedem zaključavanje
> zapisa. Pošto nemam ama baš nikakvo iskustvo sa SHARE i mehanizmima
> za zaključavanje pod DOS-om molim one koji su upućeni u problematiku
> da mi objasne kako SHARE radi i kako se izvodi zaključavanje cele
> datoteke i jednog njenog dela. Pomoglo bi i upućivanje na neku
> literaturu.
Da bi mogao da zaključavaš slogove u nekom multitasking okruženju,
potrebno je da prethodno učitaš SHARE. Ukoliko radiš pod nekom
mrežom, to nije potrebno, jer sam mrežni softver ima ugrađen SHARE
mehanizam. Dalje, za sve operacije zaključavanja datoteka i slogova
koriste se dve dosove funkcije:
DOS open file
-------------
AH=3DH
AL=sa kakvim atributima se otvara fajl ( read/write+mrežni atributi )
DS=SEG filename
DX=OFS filename
INT 21H
DOS Control Record Access
-------------------------
AH=5CH
AL=0/1 ( 0 - zaključavanje, 1 - otključavanje )
BX=handle
CX=FILE_OFFSET_HI_WORD
DX=FILE_OFFSET_LO_WORD
SI=RECORD_LEN_HI_WORD
DI=RECORD_LEN_LO_WORD
INT 21H
Kao što vidiš funkcije zaključavanja slogova se mogu lako
implementirati u bilo kom modernom jeziku. Ali, pošto vidim da radiš
u C++, u C-u već postoje gotove funkcije koje omogućavaju
zaključavanje slogova. Za otvaranje fajlova koristi sopen koji barata
datotekama na handle nivou, a za zaključavanje funckiju locking.
Pogledaj i /rsoft/r068cht.zip, dat je jedan mali primer na tu temu
chat između dva noda na mreži.
p.s. ove funkcije postoje u MS C-u, za Borland nisam siguran.
baze.podataka.234djelovic,
-> #233, pedjak> ove funkcije postoje u MS C-u, za Borland nisam siguran.
Ih, pa nemoj da vređaš :). BC++ ne samo da nudi Microsoftovu funkciju
locking, nego i nudi mnogo komfornije lock i unlock.
baze.podataka.235neman,
-> #223, djelovic> Zasto? Taj slog se otkljuca cim se korisnik sledeci put
> uloguje. Nema nikakve nekonzistentnosti i nikakvog
> reindeksiranja jer je zapravo tabela
Zato sto dok se korisnik ponovo ne uloguje ( a recimo slucajno ispadne )
ti nemas pojma da li on stvarno radi, tj. morao bi da uporedjujes listu
korisnika koju mozes da dobijes preko Novell API-ja, a cemu onda dodatna
baza ?. Da, da, treba podesiti vreme ocitavnja stanja radnih stanica.
baze.podataka.236neman,
-> #231, mdrazic> I ovde je trivijalno ograniciti istovremeni broj usera.
Mislim da Novell ima mogucnost zabrane prijave korisnika pod istim
username-om. Definisi zatim grupu koja pristupa tom programu i to je to.
baze.podataka.237djelovic,
-> #235, neman> Zato sto dok se korisnik ponovo ne uloguje ( a recimo slucajno ispadne )
> ti nemas pojma da li on stvarno radi, tj. morao bi da uporedjujes listu
> korisnika koju mozes da dobijes preko Novell API-ja, a cemu onda dodatna
> baza ?. Da, da, treba podesiti vreme ocitavnja stanja radnih stanica.
Dodatna baza radi ograničenja maksimalnog broja ljudi koji koriste program
i radi određivanja jedinstavnenog broja za svaki proces nezavisno od OS-a na
kome se sve to izvršava.
baze.podataka.238misa.m,
-> #162, ndragan>> ...uglovi na okvirima koji imaju nešto jednostrukih i nešto dvostrukih...
Što ne uradiš običnu zamenu, ništa se ne gubi u izgledu:
repl all details with chrtran(details,"ÍĚËŻ║","┌┐└┘│")
baze.podataka.239misa.m,
-> #213, max.headroom>> USE baza ORDER pol
>> t5 = SECO()
>> BROWSE FOR pol = "M" NOWAIT WINDOW prozor
Kada već ovako lepo testiraš Fox ubaci ako te ne mrzi i varijantu koja
bi trebalo da bude efikasnija od Rushmore tehnologije u ovom poslednjem
slučaju, odnosno kada je sam uslov u master indeksu:
use baza order pol
if seek("M")
brow while pol = "M" nowait
endif
baze.podataka.240evlad,
-> #226, max.headroom>> Joj, to je :) Hvala - reko', Fox mi pobrljavio (a do sada nisam bas
>> previse kalemio sa matricnim stampacima; plus sto nemam nikakav Ref.
>> menjual).
Ako nemas YUSCII slova na svedskom setu moze se font download-ovati,
ali na samo 6 mesta. Ako ti to treba javi mi se na mail posto je malo duze.
baze.podataka.241nbatocanin,
-> #218, max.headroom> Ako user iz drugog taska pokuša da pokrene isti programski deo
> (deluje nebulozno), zabrani :) Logično je da neće da pravi isti
> izveštaj u oba taska.
Ne bih rekao :) Na primer, jedan proces traži zbirni izveštaj o
prodaji u poslednjih mesec dana, a drugi od početka godine, zbog
poređenja. Ja sve privremene datoteke kreiram tako da budu
jedinstvene za svaki proces - tako nema problema makar svi
istovremeno tražili isti izveštaj. Biće reči u novim Računarima :)
baze.podataka.242misa.m,
Mala uporedna analiza korišćenja memorije i veličine Fox-ovih
run-time izlaza na jednoj maloj aplikaciji (sve u KB). Ponekad
i samo par KB memorije više mnogo znači.
A B C D E
-----------------------------------------------------------
FOXR+APP 265(512) 471(3676) 38582
Comp EXE 275(513) 471(3676) 49182 22130 47205
Stan EXE 272(517) - 1303087
Ext EXE - 495(3768) 1355963 751590 776988
-----------------------------------------------------------
A - Standard: slobodna osnovna i do 1MB memorija (pokrenut sa -x)
B - Extended: slobodna osnovna i ukupno rezervisana XMS memorija
C - Veličina aplikacije na disku
D - Veličina nakon pakovanja sa ARJ a
E - Isto kao D, stim što je aplikacija napravljena sa Encrypt opc.
Mašina je 386/40 sa 8MB, QEMM 7.04, Fox je 2.6 DOS
baze.podataka.243max.headroom,
-> #223, djelovic> Zašto? Taj slog se otključa čim se korisnik sledeći put
> uloguje.
Zar neće izabrati novi nezaključan record iz baze?
baze.podataka.244max.headroom,
-> #224, nbatocanin> Hm, ovo mi nije baš najjasnije. Zašto bi kreiranje u RAM
> disku bilo sigurnije od kreiranja na disku? I kakve veze
> ima random ime sa sadržajem baze?
Dobro, ovo je reply na moje pisanije. Nisi me razumeo - pričao sam o
malim temporary bazama (što se RAM diska tiče), ali drugi deo (random
ime i sadržaj baze) nisam dovodio ni u kakvu vezu :)
baze.podataka.245max.headroom,
(SQL SELECT nastavak...)
Wildcard (*)
------------
Wildcard se u SQL komandi može pojaviti samo u listi polja. Kada se
umesto naziva polja navede *, u rezultat se ubacuju sva polja iz
navedene baze, odn. moguće je navesti * posle naziva radne oblasti.
Primer:
SELECT * FROM baza1, baza2 ;
WHERE b1art = b2art
SELECT baza1.*, baza2.polje1, baza2.polje2 ;
FROM baza1, baza2 ;
WHERE b1art = b2art
U rezultat su (prvi primer) uključena sva polja iz obe baze (BAZA1.DBF i
BAZA2.DBF). U drugom primeru u rezultat su uključena sva polja iz
BAZA1.DBF baze i polja POLJE1 i POLJE2 iz BAZA2.DBF baze.
AS (Alias za naziv kolone)
--------------------------
Znate i sami da je dosta nezgodno gledati BROWSE ili neki report kada
su nazivi kolona (Headings, parametar :H u BROWSE-u) identični
nazivima polja u bazi (npr. "red_br_a" ili "datrodj"). SQL SELECT
parametar AS nam omogućava da nazive kolona koje se pojavljuju u
rezultatu predefinišemo. Primer:
SELECT datrodj AS datum_rodj, pbr AS post_broj ;
FROM baza1
Rezultujući BROWSE će imati nazive kolona "datum_rodj" i "post_broj".
Alias ime kolone ne sme prelaziti 10 karaktera, i ne sme sadržati
spejsove. Nezgoda je što ovaj parametar nije definisan ANSI/ISO
standardom, pa će tako kreirani query biti neportabilan (neće moći da
se seli na druge platforme).
DISTINCT (zabrana ponavljanja)
------------------------------
DISTINCT eliminiše duplicirana polja iz rezultata. Na primer, ako
želimo listu imena i svih zaposlenih u firmi, koristićemo:
SELECT DISTINCT ime ;
FROM baza1
Međutim, ako u rezultat ubacimo još jedno polje:
SELECT DISTINCT ime, prezime ;
FROM baza1
Pojavljivaće se duplirana imena u slučajevima kada su prezimena
različita. Evo šta SQL radi kada naiđe na DISTINCT:
- kreira se pomoćna baza koja sadrži sve vrednosti iz zadatog polja.
- nad tom bazom se kreira unique indeks (odn. na polju (poljima) koje
je obeleženo sa DISTINCT).
- SQL tada primenjuje kreirani indeks na privremenu bazu i u
rezultat povlači samo podatke iz indeksa. Daklem, bez duplikata.
Međutim, sve ovo ume i da potraje...
WHERE
-----
Najčešće nam nije namera da u rezultat query-ja guramo sve vrednosti
iz polja, tj. potrebno nam je da polja koja će stići u rezultat
odgovaraju nekom uslovu. Za to nam je potrebna neka vrsta filtera. Ako
koristimo SET FILTER komandu nad bazom iz koje rezultate vadimo sa
SQL SELECT-om, nećemo postići ništa, jerbo se eksterni filteri
ignorišu. Zato u sledećem primeru kao rezultat dobijamo sva polja iz
baze:
USE baza1
SET FILTER TO UPPER(republika) = "SRBIJA"
SELECT ime, prezime, republika FROM baza1
Za željeni rezultat potrebno je sledeće:
SELECT ime, prezime, republika ;
FROM baza1 ;
WHERE UPPER(republika) = "SRBIJA"
Filteri i podfilteri
--------------------
Podfiltere je moguće praviti sa AND i OR. Može ih biti koliko hoćete
unutar jedne WHERE opcije. Primer:
SELECT racun, predracun
FROM racuni, predrac
WHERE racun = predracun ;
AND UPPER(ime) = "MARKO" ;
AND UPPER(prezime) = "CICIĆ" ;
AND datum >= š01.01.94ć ;
AND datum <= š10.01.94ć
Kao rezultat se dobija lista racuna i predracuna (sa identičnim
brojevima) koje je kupio Marko Cicić u periodu od 01.01. do 10.01.
1994. godine. Još jedan primer:
SELECT racun, predracun
FROM racuni, predrac
WHERE racun = predracun ;
AND UPPER(ime) = "MARKO" ;
AND UPPER(prezime) = "CICIĆ" ;
OR datum >= š01.01.94ć ;
AND datum <= š10.01.94ć
Rezultat je identičan rezultatu iz prethodnog primera, sa tom razlikom
što se izbacuju i računi/predračuni koji su ili pisani na Marka Cicića,
ili pripadaju navedenom vremenskom periodu.
JOIN
----
Kada u query-ju imamo posla sa više baza, potrebno je da primenimo
specijalni tip WHERE opcije, zvane "join". Join uspostavlja relaciju
bilo one-to-one, bilo one-to-many tipa nad bazama navedenim posle
FROM. Ako se, pak, ne koristi JOIN, SQL primenjuje sistem po kome su
svi zapisi iz BAZA1.DBF baze povezani sa svim zapisima iz BAZA2.DBF
baze. U slučaju da baza1 ima 10,000 zapisa, a baza2 200,000 zapisa,
rezultat sadrži 2,000,000 zapisa. To ume da POTRAJE.
Ograničenja su sledeća: nemože se imati query u kome je jedna baza
povezana relacijom sa više od jedne baze-roditelja. Na primer, ako je
baza RACUNI (brojevi računa i suma sa računa) povezana relacijom
one-to-many sa bazama SPECIFIK (brojevi računa, stavke sa računa i
cene), odn. PLACENO (brojevi računa i datumi prispelih uplata na
iste), nije moguće generisati rezultat koristeći jednostavno:
SELECT * FROM racuni, specifik, placeno ;
WHERE specifik.brracuna = racuni.brracuna ;
AND placeno.brracuna = racuni.brracuna
jer SQL poredi sadržaje polja iz više baza sa sadržajem polja u jednoj
bazi, pa se kao rezultat dobija jedan zapis za svaki od zapisa u
child-bazi, i tako za svaku relaciju. Jendostavnije, dobija se višak
zapisa :)
BETWEEN
-------
Koristi se da se utvrdi da li vrednosti polja odgovaraju zadatom
intervalu, sa tim da vrednosti polja ne smeju biti drugačijeg tipa od
onog u uslovu. Primer:
SELECT brracuna FROM racuni ;
WHERE datum BETWEEN š01.01.94ć AND š10.01.94ć
IN
--
IN se koristi kada želimo poređene sadržaja navedenog polja sa
definisanim skupom vrednosti. Primer:
SELECT brracuna FROM racuni ;
WHERE UPPER(kupac) IN("INTERSOFT","COMTRADE","ABC COMPUTING")
Rezultat su svi brojevi računa koji su izdati firmama Intersoft,
ComTrade i ABC Computing. Kao i u BETWEEN-u, vrednosti polja ne smeju
biti drugačijeg tipa od onog navedenog u uslovu. Takođe, moguća je i
sledeća kombinacija:
SELECT brracuna FROM racuni ;
WHERE UPPER(kupac) NOT IN("čIKA COMP","MIKA COMP")
Pa se kao rezultat dobijaju brojevi računa koji NISU izdati firmama
čika Computers i Mika Computers.
(Nastavak o SQL SELECT sledi...)
baze.podataka.246mdrazic,
-> #230, jmilovic> Zanima me koji se software za baze podataka pokazao kao
> najbolji pod UNIX operativnim sistemom ???
Oracle 7 je po reklamama šio ostale po brzini otprilike
duplo. Kako, ne znam. Najavljuje se Oracle 8 (višestruki
commit, replikacija tabela,... koliko sam čuo).
Ne znam ima li DB2 za Unix. Zavisi i na kojoj platformi.
Milan
baze.podataka.247mdrazic,
Evo stigla mi je pod ruku jedna bibliografija iz oblasti
projektovanja i CASE-a. Ko ima informacije o nekoj od
knjiga (kakva je, sadržaj, gde se nalazi itd.) molim da
javi ovde.
1. Paul T. Ward, Stephen J. Mellor
Structured Development for Real Time Systems (Vols I-III)
Yourdon Press, 1985.
2. Derek J. Hatley, Imtiaz A. Pirbhai
Strategies for Real-Time System Specification
Dorset House, 1987.
3. Meiler Page-Jones
Practical Guide to Structured Systems Design (Second Edition)
Yourdon Press, 1987.
4. Tom DeMarco
Structured Analysis and Systems Specification
Yourdon Press, 1978.
5. E. N. Yourdon
Modern Structured Analysis
Yourdon Press, 1988.
6. S. Shlaer, S. Mellor
Object Oriented Systems Analysis
Yourdon Press, 1989.
7. M. McMenamin, J. F. Palmer
Essential Structured Analysis
Prentice-Hall, 1984.
8. B. Dickinson
Developing Quality Systems
Yourdon Press, 1989.
9. P. Chen
The Entity-Relationship Approach to Logical Database Design
QED Information Sciences, 1977.
10. James Martin, Carma McClure
Structured Techniques for Computing
Prentice-Hall, 1985.
11. Michael Jackson
System Development
Prentice-Hall Intl., 1983.
12. E. N. Yourdon, L. L. Constantine
Structured design
Prentice-Hall, 1979.
13. C. Gane, T. Sarson
Structured Systems Analysis: Tools and Techniques
Prentice-Hall, 1979.
14. B. Dickinson
Developing Quality Systems (second edition)
Yourdon Press, 1989.
15. Carma McClure
CASE Is Software Automation
Prentice-Hall, 1988.
16. R. Elmasri, S. Navathe
Fundamentals of Database Systems
The Benjamin/Cummings Company Inc., 1989.
17. Peter Coad, Edward Yourdon
Object Oriented Analysis (second edition)
Yourdon Press, 1990.
18. Rex Hogan
A Practical Guide to Database Design
Prentice-Hall, 1990.
19. C. Fleminf, B. VonHalle
Handbook of Relational Database Design
Addison-Wesley, 1989.
20. Larry Towner
CASE Concepts and Implementation
McGraw Hill, 1989.
21. James Martin
Information Engineering (Books 1-3)
Prentice-Hall, 1989.
Ako neko ima još neku referencu u vezi projektovanja,
molim da doda.
Posebno molim kolege sa FONa i ETFa da provere ima li nešto
od ovoga u njihovoj biblioteci.
Milan
baze.podataka.248ppekovic,
-> #230, jmilovic>> Zanima me koji se software za baze podataka pokazao kao najbolji pod
>> UNIX operativnim sistemom ???
Teško je reći koji je najbolji, ali je najpopularniji svakako
ORACLE.
Paya
baze.podataka.249djelovic,
-> #243, max.headroom> > Zašto? Taj slog se otključa čim se korisnik sledeći put
> > uloguje.
>
> Zar neće izabrati novi nezaključan record iz baze?
Ma hoće, ali sam odgovarao na zamerku da će u slučaju pada mašine slog
ostati zaključan. Bez obzira da li mreža vrši automatski logout, sve se dovede
na meste čim se korisnik opet uloguje.
baze.podataka.250max.headroom,
-> #232, mdrazic> Štaviše, uopšte nije nelogično, već vrlo verovatno.
Znaem, znaem :) Zato sam i dao primere sa datumima (nisam mislio da
prog. task bude otvaranje prozora :)
baze.podataka.251max.headroom,
-> #241, nbatocanin> Ne bih rekao :) Na primer, jedan proces traži zbirni
> izveštaj o prodaji u poslednjih mesec dana, a drugi od
> početka godine, zbog
Buhuhuu, pa ja sam ispod ovog citata dao još dva reda teksta u kojima
objašnjavam da to ne važi kada task ima drugačiji parametar (npr.
izveštaj sa drugačijim datumom, ili, npr. izveštaj za drugu firmu)...
Mislio sam da se beleži u formatu: ime_taska+parametar. Medžutim ;),
ako user pokuša da pokrene ISTI report sa ISTIM parametrima, tada on
prosto ubija dosadu testirajući program, i ima da mu sledi poruka
"Bolje igraj Tetris" :)
Nego, videste li onaj Tetris za Fox? Zamislite koji je to komercijalni
udar za end-usera :)
baze.podataka.252max.headroom,
-> #237, djelovic> Dodatna baza radi ograničenja maksimalnog broja ljudi koji
> koriste program
Baš sam počeo da pišem o Fox-ovom LAN interface-u kada mi neko reče da
to stavim u fajl. Tu je lepo objašnjeno kako skinuti broj aktivnih
usera.
baze.podataka.253mdrazic,
-> #236, neman> Mislim da Novell ima mogucnost zabrane prijave korisnika
> pod istim username-om. Definisi zatim grupu koja pristupa
> tom programu i to je to.
Ja teram korisnike da se prijavljuju i u paket. Ne može mi
tamo neki supervisor da radi ako mu ne dozvolim :)) .
U principu imena u mreži i u paketu mogu biti različita.
Pošto isti program (mora da) radi i u mrežnom okruženju i
na običnom PC-ju, ne bakćem se čitanjem Novell username-a,
mada i to ima dobrih strana.
Milan
baze.podataka.254pedjak,
-> #234, djelovic>> ove funkcije postoje u MS C-u, za Borland nisam siguran.
> Ih, pa nemoj da vređaš :). BC++ ne samo da nudi Microsoftovu
> funkciju locking, nego i nudi mnogo komfornije lock i unlock.
Ih :) na radim sa BC++, pa sam se odmah ogradio, da ne ispadne
posle da pričam bezveze :)
baze.podataka.255ndragan,
-> #238, misa.m/ repl all details with chrtran(details,"ÍĚËŻ║","┌┐└┘│")
To nije problem, za aplikaciju ionako generišem sopstveni *help.dbf,
koji izbegava čudna slova, a za pendžersku verziju napokon generišem
zglavan .rtf koji se uredno kompajlira. A u tu priču sa generisanjem
.RTF fajla sam uleteo upravo zato što ne mogu da promenim font u
dos_style help pendžeru, gde su okviri još najmanji problem - mnogo veći
problem je kodna strana tog fonta. Nikad ne znam da li treba da mu dam
memo polje za 1250 ili 852.
baze.podataka.256ndragan,
-> #184, max.headroom/ rešenje. (Dobro, ovo nikome ne pada na pamet da koristi iz stojednog
/ razloga, ali hint je interesantan)
Radio sam nešto slično kod nekih prepisa iz baze u bazu u stilu "ajde
sad da prebacimo ove naloge iz fakturisanja u analitiku i glavnu
knjigu". Pošto nije nikad sigurno da se prepis pušta prvi put, kao ni da
li ima isti broj slogova ili ne, ciljna baza je bila indeksirana po
broju naloga i kontu, pa su se svi slogovi koji su već postojali
praznili (izuzev broja naloga), i prepis je išao po principu "ako nađeš
slog sa ključem m.nalog+chr(254), gazi slobodno, inače pravi nov". Tako
je, istina, ponekad ostajalo nešto slogova sa chr(254) u kontu, ali
garant praznih po svim drugim pitanjima pa su se mogli ladno ignorisati.
Inače, taj štos nije loš ako rutinu za upis pišeš peške i taj se trik
pojavljuje regularno (u svim bazama itd). Ostaje još samo da se
povremenu uradi Pack Memo, što opet treba sračunati kada treba da se
radi.
BTNJ, jel neko napisao funkciju koja bi umela da vrati količinu bačenog
prostora u .fpt fajlu, pa da onda malo proračunamo kad je zrelo za
pakovanje, ili čak za pregenerisanje baze sa drugom veličinom bloka.
baze.podataka.257ndragan,
-> #203, max.headroom/ inkriminisanog dela programa biti iznova kreirane pod random imenom, a
/ posle upotrebe obrisane. Da ne bih gušio, poenta je u sledećem: ako se
/ ispostavi da neka temporary baza treba da postoji, gurnite je u RAM
/ disk. Manje-više što je brže, nego je _pouzdanije_.
Ne volim da se oslanjam na to da se neka baza nalazi na direktoriju, i
da ima strukturu koju treba da ima; više volim da program sadrži
strukturu, tj
Create Table/Cursor trt_mrt (polje1 c(13), ...)
Naravno, vrlo retko pišem takve rutine... napisao sam programče koje ih
generiše. Štaviše, kad menjam strukturu, izmenim je u takvoj rutini, jer
nikad nisam siguran da neću kroz pet minuta odzipovati bazu sa starom
strukturom ;).
baze.podataka.258ndragan,
-> #222, neman/ A uzgred minus je situacija kada aplikacija pukne tj. neregularno :)
/ zavrsi rad.
Baš i nije neki minus - slog je ostao zaključan, piše čiji je, ako broj
potrošenih slogova ne premašuje bonus, korisnik može ponovo da se zakači
itd. Nije loše, mogao bih da probam (mada meni i ne treba, jer sam u
položaju da propišem strogo jednokratno prijavljivanje).
S druge strane, mislim da je zaključavanje sloga malo skupo rešenje,
troši se po jedna brava za svakog korisnika; lakše bi bilo da se postavi
indikatorsko polje i da se kontroliše iz aplikacije te da ladno otkačiš
ponovo prijavljenog korisnika. Ovako ostavljaš mreži da se petlja sa
bravama svaki put kad neko pristupi toj bazi.
baze.podataka.259ndragan,
-> #236, neman/ Mislim da Novell ima mogucnost zabrane prijave korisnika pod istim
Na novelu 4.x (valjda i na 3.*) za svakog korisnika imaš varijantu da
definišeš najveći broj istovremenih prijava; difolt je 3 a niko te ne
sprečava da staviš 1.
baze.podataka.260ndragan,
-> #204, max.headroom/ sledećem otvaranju iz baze bivaju izbrisane sve definicije indeksa i
/ greška se više ne javlja, ali to nipošto ne rešava problem :)
Upravo tako, moraš sam da ga rešiš :).
Naime, difolt ponašanje je da se prilikom otvaranja baze sa kršnim .cdx
fajlom isti jednostavno ignoriše, i to tako što se u zaglavlju baze isti
komplet zaboravi. Ja upravo tako i indeksiram, prvo obrišem .cdx sa
diska, pa otvorim bazu; foks javi grešku, koju odignorišem (dobro,
presretnem) i reagujem tako da bazu otvorim ponovo, i onda _pravim_ nov
.cdx fajl.
Naravoučenije: aman ljudi, svi smo se po jednom zeznuli stavljajući
Reindex u proceduru za indeksiranje. To pada na prvom indeksu sa
oštećenim hederom. Procedura za indeksiranje treba (mora!) da sadrži
kompletnu informaciju o ključevima i eventualnim filtriranim indeksima,
a ni u kom slučaju ne sme da zavisi od toga da li na disku već postoji
indeksni fajl i u kakvom je stanju.
p.s. problem je čak i ako se to desi kad smo kod korisnika - ko će se
setiti naziva, redosleda i tačnih indeksnih pojmova za sve tegove, a?
baze.podataka.261ndragan,
-> #205, max.headroom/ Rešenje ovog problema sastoji se u sledećem: indeksirajte bazu (u
/ kojoj važi SET DELETED ON) po još jednom ključu -
Da, tako nešto piše i u helpu, mada mi se baš i ne sviđa previše. Ovo je
u stvari problem tipa "starim putem pa bez drumarine ili obratno". S
jedne strane, ako nemam mnogo obrisanih slogova, cela priča me se ne
tiče previše, i samo me nervira što uopšte tretira te obrisane slogove
/zar nisu mogli da drže i brojač obrisanih slogova u zaglavlju baze/,
ali me se tiče što mi sve radi dovoljno sporije. Select count() upravo
služi brojanju neobrisanih slogova (ukupan se ionako dobija sa recc());
s druge strane, inde on dele() to trt_mrt goji .cdx fajlove i usporava
pristup istima čisto zbog veličine (jes' da ima ukupno dva indeksna
pojma, ali zato ima po bar tri bajta za svaki slog, plus režija u
zaglavljima blokova). Sve skupa, opet treba da proračunavamo kad nam se
šta isplati.
baze.podataka.262ndragan,
-> #206, max.headroom/ SQL SELECT ignoriše ORDER postavku, te tako ne pati od pomenutih
/ "stomačnih tegoba".
Jes', ali u helpu isto kaže da i Select radi brže ako baza ima order 0;
nemam pojma zašto, ali ako su to napisali isti ljudi koji su to i
pravili, valjda oni znaju.
baze.podataka.263ndragan,
-> #207, max.headroom/ Eto - zaključke izvlačite sami :)
Jel to beše tek od 2.5 ili 2.6 uvedeno Browse ... Rest, tako da se uradi
jedno Seek ili Locate, pa onda Browse For ... Rest, tako da ni ne
pokušava da gleda bazu do tog mesta, nego odmah skače na taj slog i
gleda ostatak. Trebalo bi da je brže od svega.
baze.podataka.264max.headroom,
(Nastavak SQL SELECT...)
LIKE
----
žesto se dešava da ne želimo tačno poređenje dva izraza, odn. da imamo
potrebu da samo deo jednog izraza tražimo u drugom. Za to se kod SQL
SELECT-a koristi LIKE opcija, sa odatkom % ili _ operanda.
% - Koristi se da se zameni proizvoljan broj karaktera. Posebno je
koristan za pretrage po memo-poljima. Primer:
SELECT roba.brartikla, roba.opis, racuni.brracuna ;
FROM roba, racuni ;
WHERE racuni.brartikla = roba.brartikla ;
AND roba.opis LIKE "%Patike%"
Rezultat su svi brojevi artikala zajedno sa opisima, a koji su izdati
po fakturama. Uslov je i taj da se u opisu robe mora nalaziti reč (deo
reči) "Patike". Opis može biti i memo-polje. U rezultujućem polju OPIS
mogu se naći "Crvene Patike", kao i "Patike Zelene" :)
_ - (Underscore) Ovaj wildcard je sličan DOS-ovom ?. On zamenjuje
jedan karakter u izrazu. Na primer:
SELECT roba.brartikla, racuni.kupac, racuni.brracuna ;
FROM roba, racuni ;
WHERE racuni.brartikla = roba.brartikla ;
AND racuni.kupac LIKE "M_rko"
Rezultat su svi brojevi artikala zajedno sa opisima, a koji su izdati
po fakturama. Uslov je i taj da se u imenu kupca pojavljuje "Marko"
ili "Mirko". Normalno, džoker-znake _ i % moguće je i kombinovati
unutar jednog izraza. Međutim, u slučaju da u izrazu tražimo upravo
neki od ta dva znaka (% ili _), koristimo opciju ESCAPE. Primer:
SELECT roba.brartikla, racuni.kupac, racuni.brracuna ;
FROM roba, racuni ;
WHERE racuni.brartikla = roba.brartikla ;
AND racuni.kupac LIKE "%/%%" ESCAPE "/"
Znači, u imenu kupca tražimo znak "%". Karakter koji je naznačen posle
ESCAPE je karakter posle koga se nalazi znak koji se ne prevodi.
Dakle, ako smo za ESCAPE karakter naznačili "/", tada i u izrazu,
odmah posle ESCAPE karaktera (%/%%) mora da postoji vrednost koja se
neće prevoditi kao wildcard - u ovom slučaju to je znak "%".
SQL i makroi
------------
SQL komanda bez problema koristi makroe (macro substitution), i što je
najvažnije, makro se u query-ju prevodi samo jednom. Primer:
baza1 = "BAZA.DBF"
baza2 = "LISTA.DBF"
SELECT * ;
FROM (baza1) ;
WHERE baza = &baza2
A makroi se mogu koristiti čak i kod LIKE klauzule, radi poređenja:
naziv = "Patike"
SELECT roba.brartikla, roba.opis, racuni.brracuna ;
FROM roba, racuni ;
WHERE racuni.brartikla = roba.brartikla ;
AND roba.opis LIKE "%&naziv%"
SQL i veličina slova (Case Sensitivity)
---------------------------------------
SQL je case-sensitive, tj. pravi razliku između velikih i malih slova.
Npr. ako se u polju ime nalazi "Marko", tada poređenje tipa ime =
"MARKO" daje False rezultat. Zato bi valjalo navesti jedno UPPER.
SQL i indeksi
-------------
WHERE opcija koristi Rushmore i indekse da bi ubrzala pretragu. SQL
može koristiti sve tipove indeksa: structural CDX (tag), external CDX
ili external IDX. Međutim, da bi SQL mogao da iskoristi eksterne
indekse, pre pozivanja SELECT komande potrebno je takve indekse i
otvoriti. Primer:
USE baza INDEX idxfajl, extcdx
Sortiranje rezultata sa ORDER BY
--------------------------------
ORDER opcija može biti primenjena na proizvoljan broj polja, što znači
da se rezultujuća baza može sortirati po proizvoljnom broju
parametara (odn. onoliko polja koliko se nalazi u listi polja posle
SELECT). Primer:
SELECT republika, ime ;
FROM baza ;
WHERE republika IN ("SRBIJA","CRNA GORA") ;
ORDER BY republika, ime
Rezultujući BROWSE će prikazati podatke sortirane po republikama, a
unutar njih po imenima. Sortiranje je ASCENDING (default, od A do Z),
što se može i promeniti dodavanjem opcije DESCENDING (od Z do A).
Moguće je čak kombinovati ASCENDING (ne navode se eksplicitno) i
DESCENDING parametre. Primer:
SELECT republika, ime ;
FROM baza ;
WHERE republika IN ("SRBIJA","CRNA GORA") ;
ORDER BY republika, ime DESCENDING
U rezultatu će podaci biti prikazani po republikama (prvo Crna Gora,
zatim Srbija - od A do Z), a unutar tako isortiranih podataka
sortiraju se imena od Z do A (DESCENDING). Konačno, moguće je
rezultujuću bazu (sa ORDER BY) sortirati i po rednom broju polja
navedenog u listi polja posle SELECT (korisno ako sortiramo po poljima
koja sadrže neki UDF ili neku Fox-ovu f-ju tipa UPPER() ili LEFT()).
Primer isti kao i prethodni:
SELECT republika, ime ;
FROM baza ;
WHERE republika IN ("SRBIJA","CRNA GORA") ;
ORDER BY 1, 2 DESCENDING
Funkcije za rad sa kolonama
---------------------------
U listi polja je moguće navesti bilo koju od sledećih funkcija:
AVG(ime_polja) - Prosek za navedeno polje. Polje mora sadržati samo
numeričke vrednosti.
SUM(ime_polja) - Suma za navedeno polje. Polje mora sadržati samo
numeričke vrednosti.
MIN(ime_polja) - Najmanja vrednost u navedenom polju. Dozvoljeni
tipovi podataka su: Numeric, Character i Date.
MAX(ime_polja) - Najveća vrednost u navedenom polju. Dozvoljeni
tipovi podataka su: Numeric, Character i Date.
COUNT(ime_polja) - Broj zapisa u kojima se pojavljuje određeno polje.
Taj broj zavisi isključivo od filtera koji se
primenjuje nad bazom. Zato se umesto (ime_polja)
može navesti i * wildcard.
SELECT SUM(cena), artikal ;
FROM racuni ;
WHERE datum = š10.01.94ć
Navedeni primer daje summary rezultat cena za svaki artikal prodat
10.01.1994., ali sve to u jednom zapisu (pogledati GROUP BY za
drugačiju izvedbu). Rezultate je moguće i sortirati pomoću ORDER BY:
SELECT SUM(cena), artikal ;
FROM racuni ;
WHERE datum = š10.01.94ć ;
ORDER BY artikal, 1 DESC
Moguće je koristiti i opciju DISTINCT za sve f-je za rad sa kolonama
osim MIN() i MAX(). Npr:
SELECT AVG(DISTINCT cena), artikal ;
FROM racuni
Ali pažnja - moguće je imati samo jedan DISTINCT u listi polja.
Sledeći primer neće raditi:
SELECT DISTINCT AVG(DISTINCT cena), artikal ;
FROM racuni
I još nešto: COUNT() f-ja neće dozvoliti upotrebu DISTINCT opcije ako
je ime polja zamenjeno sa * (wildcard), npr. COUNT(DISTINCT *). Da bi
se uradilo DISTINCT, u COUNT()-u se mora navesti i ime polja.
I još jedna sitnica :) - nije moguće izvršavati "nested" f-je za rad
sa kolonama, tipa:
SELECT SUM(AVG(cena)) FROM racuni
Jerbo Fox prijavljuje grešku "AVG.PRG cannot be found".
(Nastavak SQL SELECT sledi...)
baze.podataka.265zoranv,
Jedan problem vazna za Fox Pro za Win 2.5.
Kako da se postigne poravnanje teksta uz desnu marginu u jednoj od kolona
u BROWSE prozoru?
baze.podataka.266zoranv,
Da li neko zna da li postoji grupa za Fox Pro za WIndows?
Ja sam zainteresovan ...
baze.podataka.267dr.grba,
-> #263, ndragan>> Jel to beše tek od 2.5 ili 2.6 uvedeno Browse ... Rest, tako da se uradi
>> jedno Seek ili Locate, pa onda Browse For ... Rest, tako da ni ne
Eto, a mene si zimus zezao zbog "tek sad uvedenog" SCOPE indeksa u Clipper.
(:
baze.podataka.268pedjav,
-> #233, pedjak> Da bi mogao da zaključavaš slogove u nekom multitasking okruženju,
> potrebno je da prethodno učitaš SHARE. Ukoliko radiš pod nekom
> mrežom, to nije potrebno, jer sam mrežni softver ima ugrađen SHARE
Dobro, to je sve OK i jasno mi je. Ali tu se sad postavlja još jedan
problem - dead-lock? Da malo pojasnim problem:
Proces A je zaključao jedan slog i zahteva drugi slog koji, međutim,
drži proces B, koji istovremeno zahteva baš onaj slog koji drži
proces A. Tako se stvara jedna beskonačna petlja u kojoj dva procesa
čekaju da budu oslobođeni slogovi koji im trebaju trošeći
procesorsko vreme.
U praksi se može dogoditi da jednu takvu petlju čini veći broj procesa.
Mene sada interesuje da li SHARE o svemu ovome vodi računa pre nego što
dozvoli zaključavanje nekog sloga ili ću sam morati da napišem neku
rutinu koja će to regulisati (napr. neće dozvoliti zaključavanje
ukoliko će to dovesti do pojave dead-locka).
baze.podataka.269max.headroom,
-> #262, ndragan> Jes', ali u helpu isto kaže da i Select radi brže ako baza
> ima order 0;
Hmmm... tada je baza već otvorena, pa je i logično - SQL SELECT nema
potrebu da istu ponovo "fizički" otvara, već je iskopira u drugu radnu
oblast (USE...AGAIN). Verovatno grešim.
baze.podataka.270max.headroom,
-> #263, ndragan> gleda ostatak. Trebalo bi da je brže od svega.
Da, ja sam računao na ver. 2.00. Ipak, 2.5 for DOS/WIN je još uvek u
fazi razbucavanja :)
baze.podataka.271max.headroom,
(Nastavak SQL SELECT...)
GROUP BY
--------
Ranije sam pomenuo primer:
SELECT SUM(cena), kupac ;
FROM racuni ;
WHERE artikal = "Cipele"
Daklem, kao rezultat se dobija samo jedan zapis, a mi smo želeli
zbirno izračunati koliko je koji kupac kupio cipela, odn. jedan zapis
po kupcu (sa sub-totalom za svakog kupca). Za takvo nešto potrebno je
koristiti GROUP BY opciju. Ona grupiše rezultat po navedenom parametru
(nazivu polja). Primer koji to radi:
SELECT SUM(cena), kupac ;
FROM racuni ;
WHERE artikal = "Cipele" ;
GROUP BY kupac
Kada Fox izvršava query sa GROUP BY, on kreira jednu međubazu u koju
prenosi sadržaje svih navedenih polja iz liste polja, kao i polja
navedena iza GROUP BY. To znači da rezultat možemo grupisati i po
polju koje se ne pojavljuje u rezultatu. Tada se polja filtriraju po
uslovu koji stoji posle WHERE. Potom se podaci grupišu i nad njima se
izvršava SUM() ond. neka druga SQL f-ja. Posle GROUP BY se može
navesti proizvoljan broj polja, pa je moguća i ova kombinacija:
SELECT artikal, SUM(cena), kupac ;
FROM racuni ;
GROUP BY artikal, kupac
Još nešto - GROUP BY radi brže od DISTINCT, pa je, ako želimo
grupisanje podataka neke velike baze (a ne želimo redundantne zapise),
grupisanje potrebno uraditi po nekom unique polju (U prethodnom
primeru bi se mogla otvoriti i baza ROBA.DBF, iz koje bi se vadile
šifre artikala - one se sigurno ne ponavljaju).
HAVING
------
Pošto smo sa GROUP BY sredili da dobijamo subtotale, javlja se sledeći
problem - kako ustanoviti kriterijum koja će se grupa pojavljivati u
izveštaju, a koja neće? Nije moguće koristiti WHERE opciju jer ona ima
uticaj samo na originalnu bazu, dok je nama potreban filter za
međubazu kreiranu od GROUP BY. HAVING opcija nam omogućava upravo to -
koje će grupe preći u međubazu i pojaviti se u izveštaju. Kontrola se
vrši uglavnom AVG(), SUM() ili nekom sličnom SQL f-jom, a koja može i
ne mora biti ista kao i SQL f-ja u listi polja. Primer:
SELECT SUM(cena), kupac ;
FROM racuni ;
WHERE artikal = "Cipele" ;
GROUP BY kupac ;
HAVING SUM(cena) > 0
Tako da query omogućava pregled samo onih grupa kojima je subtotal
veći od nule.
(Dešava se da programer uradi sledeće:
SELECT * FROM racuni HAVING artikal = "Cipele"
što se izvršava sto puta sporije, a Rushmore-u ne pada na pamet da ga
gleda. Najpravilnija kombinacija je:
SELECT * FROM racuni WHERE artikal = "Cipele" )
U KOM OBLIKU ĆE BITI REZULTAT?
------------------------------
FoxPro 2.5 omogućava direkciju izlaza (SELECT INTO) u: CURSOR, DBF
(TABLE) i ARRAY. Rezultat se može smestiti i u ASCII FILE ili biti
poslat na PRINTER. Može se koristiti INTO ili TO opcija, ali ne obe
odjednom (iako će SQL dati prednost INTO opciji).
INTO CURSOR
-----------
SELECT "cursor" je privremena baza na koju se primenjuje filter -
sada, zavisno od veličine tog temporary fajla, on će biti ili u
memoriji, ili na disku. I to su uglavnom read-only baze. Međutim, ako
se podaci dobijeni kroz query žele zadržati za dalju upotrebu (npr.
njihovo propuštanje kroz novi query), najbolje je raditi smeštanje
podataka ne u "cursor", već u "dbf" (ili "table"). Ali ako je IPAK
potrebno imati tu privremenu bazu na disku (dakle, da budemo sigurni
da je ona i na disku, a ne da se samo povlači po memoriji), koristimo
sledeće:
- AS opciju za zaglavlja polja.
- Korišćenje izraza u listi polja koji nije samo puko ime polja.
- GROUP BY ili ORDER BY opciju.
- Neka SQL f-ja za operacije nad kolonama (poljima) - AVG(), SUM()...
Pretpostavimo da pokušate da koristite "cursor" da bi podatke iz njega
prebacili u neku drugu bazu. Tada je neophodno znati da je "cursor"
neka postojeća baza na disku, a ne njena kopija u memoriji. Ako
"cursor" baza (sa odgovarajućim filterom) postoji na disku, APPEND
FROM komanda će ignorisati filter uspostavljen SELECT komandom i
dodati sve zapise iz izvorne baze. Da bi se odredilo da li imate
filtrirani ili "pravi" cursor, treba posle završenog query-ja uneti
sledeće:
xx = DBF()
Pa ako je xx baza sa nastavkom .TMP, u pitanju je "pravi" cursor.
Međutim, još uvek se ne možete pozvati na alias radne oblasti (u ovom
slučaju ime cursor-a), jer kada se koristi APPEND FROM, mora se
navesti i ime baze. Tada se radi sledeće:
SELECT * FROM racuni ;
WHERE datum BETWEEN š01.01.94ć AND š10.01.94ć ;
INTO CURSOR kursor ORDER BY datum
SELECT baza
APPEND FROM (DBF("kursor"))
Još nešto - pazite šta se događa sa filtriranim cursor-om u
višekorisničkoj sredini, jer je on, jednostavno, baza na koju se
primenjuje filter. Svaka izmena u originalnoj bazi dovodi do promene
resultata u cursor-u.
INTO ARRAY
----------
SELECT kupac, brracuna ;
FROM racuni ;
WHERE artikal = "Cipele" ;
INTO ARRAY matrica
Padžnja :) - ako nema rezultata, nema ni matrice. Daklem, mora se
proveriti postojanje iste pre njene dalje upotrebe. Najbolji trik je
proverom vrednosti u _TALLY sistemskoj promenljivoj, posle izvršenog
SELECT-a. Primer:
IF _TALLY = 0 && Nema elemenata u matrici, tj. nema matrice
..........
ENDIF
Takođe, nemojte vršiti prenos podataka u matricu ako niste sigurni
kolika je veličina rezultata. Maksimalni broj elemenata jedne matrice
(FoxPro 2.5) je 65,000, a može zafaliti i memorije. U oba slučaja Fox
prijavi grešku.
INTO TABLE / DBF
----------------
Od rezultata query-ja kreira permanentnu bazu. Primer:
SELECT kupac, brracuna ;
FROM racuni ;
WHERE artikal = "Cipele" ;
INTO TABLE baza
Pažnja - ako je SET SAFETY OFF, Fox ne prijavljuje nikakvu poruku u
slučaju da je ime baze navedeno posle INTO TABLE isto kao i ime neke
već postojeće baze (makar ona bila i otvorena), stara baza će biti
zatvorena i nova će pretrčati preko nje (!).
TO FILE
-------
Prebacuje podatke dobijene query-jem u ASCII fajl. Primer:
SELECT kupac, brracuna ;
FROM racuni ;
WHERE artikal = "Cipele" ;
TO FILE fajl.txt ADDITIVE
TO PRINTER
----------
Prebacuje podatke dobijene query-jem na printer. Primer:
SELECT kupac, brracuna ;
FROM racuni ;
WHERE artikal = "Cipele" ;
TO PRINTER NOCONSOLE
baze.podataka.272nbatocanin,
-> #268, pedjav> Mene sada interesuje da li SHARE o svemu
> ovome vodi računa pre nego što dozvoli zaključavanje nekog
> sloga ili ću sam morati da napišem neku rutinu koja će to
> regulisati (napr. neće dozvoliti zaključavanje ukoliko će
> to dovesti do pojave dead-locka).
Nikako. Ovo je problem koji SHARE uopšte i ne može rešavati.
baze.podataka.273gcurcic,
-> #244, max.headroom¨˙> Dobro, ovo je reply na moje pisanije. Nisi me razumeo - pričao sam o
¨˙> malim temporary bazama (što se RAM diska tiče), ali drugi deo (random
A zašto ne iskoristiš ADDUSER i za svaku radnu stanicu definišeš direktorijum
za .TMP baze?
baze.podataka.274mdrazic,
-> #268, pedjav> Dobro, to je sve OK i jasno mi je. Ali tu se sad postavlja
> još jedan problem - dead-lock?
>
> broj procesa. Mene sada interesuje da li SHARE o svemu
> ovome vodi računa pre nego što dozvoli zaključavanje nekog
> sloga ili ću sam morati da napišem neku rutinu koja će to
> regulisati (napr. neće dozvoliti zaključavanje ukoliko će
> to dovesti do pojave dead-locka).
Nema teorije da unapred znaš šta će neko drugi zaključati, pa
nikakva rutina za otkrivanje takvih stvari tu ne pomaže.
Stvar je ipak razrešiva. Kada praviš transakciju (upisivanje
na jedno ili više mesta) radiš na sledeći način:
1. (faza širenja)
Pokušaš da zaključaš SVE potrebne tabele. Ako uspeš ideš
na sledeći korak. Ako ne uspeš, tipični scenario je da opet
probaš određeni broj puta. Kada oceniš da nema šanse da
SVE zaključaš, onda odustaješ od transakcije i otključavaš
sve što si do tada zaključao.
2. Ako si došao dovde, znači da su sve potrebne tabele uspešno
zaključane. Niko te sad ne može sprečiti da završiš transa-
kciju. Upisuješ sve što imaš.
3. (faza skupljanja)
Po završenom upisivaju otključaš sve tabele.
Veoma je bitno za komotan rad više korisnika da u ove tri faze
NEMAŠ stanje čekanja (ne daj bože neko editovanje) koje koči
ostale korisnike. Bitno je da se sve tri faze što brže završe
da tabele ne budu dugo zaključane.
Pročitaj lepu knjižicu Suada Alagića: Relacione baze podataka.
Milan
baze.podataka.275mjevta,
-> #264, max.headroom>> MAX(ime_polja) - Najveća vrednost u navedenom polju.
>> Dozvoljeni tipovi podataka su: Numeric, Character i Date.
Još uvek koristim FoxPro 2.0 pa me zanima kako u FoxPro - u
2.6 funkcioniše SQL u jednom konkretnom slučaju. Elem:
SELECT MAX( datum ), Ime, ... FROM maticna INTO CURSOR cur ;
WHERE _neki_uslov
... pokupi najveći datum ali ubaci ostale podatke iz poslednjeg?!?
sloga u tabeli. Alternativno rešenje ..
SELECT DISTINCT datum, Ime, ... FROM maticna INTO CURSOR cur;
WHERE datum IN ( SELECT MAX( datum ) FROM maticna ) AND ;
_neki_uslov
... radi ali nisam testirao performanse na vecoj količini podataka.
Kako to radi u 2.6 ?
baze.podataka.276dr.grba,
-> #274, mdrazic>> Stvar je ipak razrešiva. Kada praviš transakciju (upisivanje
>> na jedno ili više mesta) radiš na sledeći način:
Scenario je egzaktan i jasan. Ali kako se u ovu priču uklapa neregularni
prekid bilo koje vrste u slučajnom trenutku? Znaš na šta mislim: recimo
prekid kabla ili nestanak struje na klijentovom računaru, baš neposredno
posle zaključavanja tabela...
baze.podataka.277pedjak,
-> #268, pedjav> Dobro, to je sve OK i jasno mi je. Ali tu se sad postavlja još jedan
> problem - dead-lock? Da malo pojasnim problem:
> Proces A je zaključao jedan slog i zahteva drugi slog koji, međutim,
> drži proces B, koji istovremeno zahteva baš onaj slog koji drži
> proces A. Tako se stvara jedna beskonačna petlja u kojoj dva procesa
> čekaju da budu oslobođeni slogovi koji im trebaju trošeći
> procesorsko vreme.
Naravno da je to problem, zato ih moraš sam izbeći. Najpre,
nastojiš da slog držiš zaključanim što je moguće manje vremena,
čisto da upišeš izmene. Drugo, prilikom pokušaja zaključavanja
sloga, koji je već zaključan, DOS vraća informaciju da je slog već
zaključan. Šta tada činiti..? Ne treba neprestano pokušavati sa
zaključavanjem tog sloga, em što nema nekog naročitog smisla, em
što dolazi do naglog pada performansi mreže. Šta se radi: sačeka
se u proseku od 0.5-1.0 sec pa se onda pokuša ponovo. Broj pokušaja
svesti na neku razumnu meru, na primer 10-20 puta. Ako i posle toga
ne uspeš da zaključaš slog, onda program treba da prijavi grešku.
Moraš nastojati da izbegneš situacije koje dovode do ded-loka,
pisanjem programa koji takve situacije izbegavaju.
baze.podataka.278max.headroom,
-> #273, gcurcic> A zašto ne iskoristiš ADDUSER i za svaku radnu stanicu
> definišeš direktorijum za .TMP baze?
U suštini, nisam mislio na Fox-ove sveprisutne TMP baze, već na one
koje provejavaju kroz program - deo auditorijuma :) predlaže da se
takve stvari organizuju od strane samog programera, u memoriji (dakle,
pišeš vlastiti source za rad sa bazama, a koji u 99% slučajeva koristi
matrice). Normalno je da postane nezgodno ako TEMPDIR našteluješ na
RAM drajv, a ono TMP pređe tu granicu :)
baze.podataka.279max.headroom,
-> #274, mdrazic> Nema teorije da unapred znaš šta će neko drugi zaključati,
> pa nikakva rutina za otkrivanje takvih stvari tu ne
> pomaže.
Varijanta 2:
- prepišeš ono što želiš da edituješ u mem.var.1 i u mem.var.2
(ništa se ne zaključava)
- edituješ mem.var.1
- pogledaš da li je sadržaj sloga sada različit od mem.var.2
(ako jeste, neko je u međuvremenu pisao u njega, pa onoga koji je
upravo završio sa editovanjem o tome obavestiti)
- zaključaš record
- upišeš mem.var.1 u record
- otključaš record
baze.podataka.280mdrazic,
-> #279, max.headroom> Varijanta 2:
>
> - prepišeš ono što želiš da edituješ u mem.var.1 i u
> mem.var.2 (ništa se ne zaključava)
> - edituješ mem.var.1
> - pogledaš da li je sadržaj sloga sada različit od
> mem.var.2
...
To je ta ista varijanta, samo se nisam osvrtao na problem
editovanja, već posle toga kako upisati transakciju a da
ne dođe do deadlock-a.
Milan
baze.podataka.281mdrazic,
-> #276, dr.grba> Scenario je egzaktan i jasan. Ali kako se u ovu priču
> uklapa neregularni prekid bilo koje vrste u slučajnom
> trenutku? Znaš na šta mislim: recimo prekid kabla ili
> nestanak struje na klijentovom računaru, baš neposredno
> posle zaključavanja tabela...
Da se razumemo: bilo je reči o tome kako sprečiti deadlock.
Ako neko ostavi zaključane tabele posle pada, tu nema pomoći
nego otkriti ko ih drži, i 'pospremiti' za njim. Pravi
problem je da ne uđeš u deadlock na sred transakcije, pa
si nešto upisao, a ostalo ne možeš.
Milan
baze.podataka.282mdrazic,
-> #277, pedjak> Moraš nastojati da izbegneš situacije koje dovode do
> ded-loka, pisanjem programa koji takve situacije
> izbegavaju.
Imam jedan takav program. Ništa ne upisuje na disk i
dosad nijedan deadlock (kuc,kuc) ;)
baze.podataka.283misa.m,
-> #264, max.headroom>> ORDER opcija može biti primenjena na proizvoljan broj polja, što znači
>> da se rezultujuća baza može sortirati po proizvoljnom broju
>> parametara (odn. onoliko polja koliko se nalazi u listi polja posle
>> SELECT).
Mala dopuna, ORDER BY ne mora biti iz liste izlaznih polja već može biti
bilo koje polje tabela (osim memo i general). Ovo važi od verzije 2.5 i dalje.
baze.podataka.284misa.m,
-> #266, zoranv>> Kako da se postigne poravnanje teksta uz desnu marginu u jednoj od kolona
>> u BROWSE prozoru?
Isto kao i u DOS verziji:
browse fields title:P='@j' font "FoxFont",10
Problem ustvari nastaje za neproporcionalne fontove jer se dužina polja
računa na osnovu neke srednje veličine fonta a prava zavisi od konkretnih
znakova u samom polju. Jedini način je da upotrebiš neki od proporcionalnih
fontova kao npr FoxFont.
>> Da li neko zna da li postoji grupa za Fox Pro za WIndows?
Zašto grupa? Grupa predstavlja samo ograničenje na 12 korisnika i nema
razloga da se o jednom sve popularnijem paketu pravi grupa. Jedino ako
max.headroom nastavi ovako snažno, možda dobijemo temu :) i to jedino
ako nekome bude previše Foxa u ovoj temi.
BTW Grupa FOX je postojala (mislim i da postoji još uvek) ali je pre nekih
godinu dana zamrla. Vlasnik je max.headroom.
baze.podataka.285max.headroom,
-> #280, mdrazic> ne dođe do deadlock-a.
Izvin'te na digresiji (pakovao sam bazu), ali ne pratih raspravu u
celini pa mi se stoga javlja problem razumevanja "dead lock"-a. Šta mu
to dođe? (ja sam video na delu "lunch-time lock", a za ovaj prvi
značenje nagađam :) )
baze.podataka.286tetragon,
-> #171, max.headroom¸> IF fp_int86( 33, čaRegs )
¸> nReturn = aRegs(1) % 256
¸> IF nReturn < 0
¸> nReturn = nReturn + 256
¸> ENDIF
¸> ENDIF
Da li funkcija fp_int86() postoji u FP2.5/DOS ?
Ako nema, da li ima načina da se "ugradi", (biblioteka...) ?
Pozdrav, Zlatko
baze.podataka.287vgenije,
-> #282, mdrazicProgramiram vec jedno vreme u pascalu.Cinim mi da imam znanja koje bi
zadovoljilo moje potrebe.Koji mi jezik preporucujete za baze podataka
pod uslovom da bude objektni.
p.s.dali paradox moze da radi kao objectni jezik i kako
baze.podataka.288mdrazic,
-> #285, max.headroom> celini pa mi se stoga javlja problem razumevanja "dead
> lock"-a. Šta mu to dođe? (ja sam video na delu
> "lunch-time lock", a za ovaj prvi
Skini temu ponovo pa vidi... :)
Ukratko: Dva usera treba da zaključaju bazu A i bazu B.
Ne pitaj zašto, ali 1. user prvo zaključa A, a drugi
prvo zaključa B. Zatim obojica pokušavaju da zaključaju
onu preostalu, ali ne mogu. To se zove 'deadlock'.
Izlaz je da neko mora popustiti (prekinuti transakciju)
da bi se baze mogle normalno koristiti.
Uzgred, nije deadlock karakterističan samo za baze.
Za programiranje višeprocesorskih ('paralelnih') računara
postoji prigodan jezik OCCAM (čita se okam) i kod njega
je glavni problem u komunikaciji između procesa na raznim
procesima. Tu se često desi deadlock pošto ako procesor
čeka nešto od drugog, ovaj od trećeg i tako zatvore krug,
eto belaja. Studenti su u šali jezik zvali:
OCCAM - deadlock-am
Milan
baze.podataka.289mdrazic,
-> #287, vgenije> Programiram vec jedno vreme u pascalu.Cinim mi da imam
> znanja koje bi zadovoljilo moje potrebe.Koji mi jezik
> preporucujete za baze podataka pod uslovom da bude
> objektni.
Trenutno je lepa kombinacija Clipper 5.2 (imamo ga) sa
Class(y) bibliotekom (nemamo je još, oko $150 u USA).
Ovo gornje je po rečima Ricka Spencea (guru za Clipper)
idealno za treniranje za budući Visual Objects (VO).
Dok Clipper radi pod DOS-om (ima biblioteka da može da
radi i pod Windowsima), dotle će VO da radi pod Windowsima
u startu, biće 99% kompatibilan sa Clipperom, imaće
prave objekte, drajvere za DBF, SQL, ODBC, funkcije za
Windows kerefeke biće nalik na Visual Basic. VO bi
trebalo da se pojavi do kraja godine.
Uprkos kompatibilnosti, velika promena nije toliko sam
Windows koliko prelaz na event-driven programiranje
nasuprot dosadašnjem modalnom.
Naravno, ako želiš, možeš raditi i u C++ sa svim lepim
(portabilnost,...) i ružnim stranama (nije komforan kao
prethodni, manje pratećih biblioteka za baze,...).
Milan
baze.podataka.290max.headroom,
-> #284, misa.m> BTW Grupa FOX je postojala (mislim i da postoji još uvek)
> ali je pre nekih
Ja, lično, nisam za grupu. Konferencija je sasvim prihvatljivo mesto
da se raspravlja o ovakvim temama. Pre neki dan sam na Hellas BBS-u
video znatnu količinu fajlova za Fox, pa ću se već potruditi da ovde
prenesem najzanimljivije detalje...
baze.podataka.291max.headroom,
Spisak programa iz dir-a CLIPPER na HELLAS BBS-u:
NAZIV VELICINA DATUM OPIS SADRZAJA DATOTEKE
============ ======== ======== ============================================
52AN00.ARJ 16298 12-05-93 Spisak nepravilnosti u CA-Clipper 5.2
52CAPI.ARJ 112568 02-20-94 Clipper 5.2C Technical ref. book
52CUS.A01 183559 02-20-94 Update sa Clipper 5.2C US verzije 1/2
52CUS.A02 180901 02-20-94 -đđ- 2/2
AE501A.EXE 10328 07-18-93 Bug fix za fju. AEVAL za Clipper 5.01A
BLI201NG.ZIP 29148 02-20-94 Update za Blinker 2.01 Norton Guide
BLINK201.ZIP 144540 02-20-94 Update za Blinker 2.01 compiler
BLINKER3.A01 150559 03-31-94 Instalaciona verzija Blinker-a 3.0 #2/5
BLINKER3.A02 150651 03-31-94 Instalaciona verzija Blinker-a 3.0 #3/5
BLINKER3.A03 150659 03-31-94 Instalaciona verzija Blinker-a 3.0 #4/5
BLINKER3.A04 34373 03-31-94 Instalaciona verzija Blinker-a 3.0 #5/5
BLINKER3.ARJ 150559 03-31-94 Instalaciona verzija Blinker-a 3.0 #1/5
BUMENU14.ZIP 13466 02-20-94 Bulaja Menu System ver. 1.4
C50XP300.A01 105881 02-20-94 Biblioteka raznih fja za Clipper 5.01 1/2
C50XP300.ARJ 106357 02-20-94 -đđ- 2/2
C52TN1.ARJ 4736 02-20-94 Technical notes za Clipper 5.2 (prvi tom)
CL-YUSRT.ZIP 3471 01-18-93 Sortiranje indeksa po YU standardima
CL5103.ZIP 32490 02-20-94 Spisak bugova u Clipper 5.01
CLDEBUGE.ARJ 8565 02-20-94 Kako koristiti Clipper debugger
CLHLP23.ZIP 175854 02-20-94 Help sistem za Clipper 5.01/S87
CLIP52A.ZIP 97590 02-20-94 Update sa verzije 5.2 US
CLIPDIAL.ZIP 10720 01-18-93 Biblioteka za rad sa modemom
CLIPFPCX.ZIP 38235 02-20-94 Prikaz .PCX za verzije S87/5.XX (EGA i VGA)
CLIPGR12.ZIP 66609 11-22-90 Graficke rutine iz clippera
CLIPGR21.ZIP 153742 02-20-94 Graficka biblioteka za verzije S87/5.XX
CLIPINT.ARJ 4853 06-08-92 Pozivanje interapta iz clippera
CLIPINT.ZIP 6012 02-20-94 Pozivanje interapta iz Clipper-a
CLIPTOOL.ARJ 11087 02-20-94 Biblioteka fja za Clipper (Goranr sa Sezama)
CLIP_52B.ZIP 5811 02-20-94 Noviteti u Clipper 5.2B
CLIP_52C.ZIP 4634 02-20-94 Noviteti u Clipper 5.2C
CLPATCH.ZIP 46408 02-20-94 Patch.exe potreban za update Clipper 5.XX
CLUG0194.ARJ 37748 02-20-94 Listing Clipper korisnickih grupa u svetu
CRC32.ZIP 6606 02-20-94 Funkcija za racunanje 32-bit CRC (asm)
CT_BLI.ARJ 4406 02-20-94 Automatski overlay uz Blinker
DBUPLUS.ARJ 67359 02-20-94 Update za Clipper 5.2 (DBU)
DENTAL1.ZIP 344176 11-24-93 Aplikacija za zubnu ordinaciju
DGXGENER.ARJ 223978 11-16-93 Generator dge src-a za dBase, Clipper i Fox
Uploaded by: Cedomir Suljagic
DISCLIPP.ZIP 109920 01-18-93 Clipper dekompajler
DM_101.EXE 18689 01-14-94 Demo maker (dodatak za Vern 6 library)
FEDO10.ARJ 27164 02-20-94 OOP zamena za MemoEdit()
FIXLIB2.ZIP 16680 02-20-94 Koriscenje 5.01 bibl. iz verzije 5.02
FLIP1.ZIP 360088 02-28-94 Graficka biblioteka za Clipper 1/4
FLIP2.ZIP 361803 02-28-94 -đđ- 2/4
FLIP3.ZIP 360795 02-28-94 -đđ- 3/4
FLIP4.ZIP 129856 02-28-94 -đđ- 4/4
FPCLIP.ZIP 16674 08-16-93 ZA Cliper
FRANK.ARJ 243255 02-20-94 Frankie lib. User Interface Engine v. 2.01
FRANKG.ARJ 87571 02-20-94 Frankie lib. Norton Guide v. 2.01
FRANKN.ARJ 12007 02-20-94 Frankie lib. Newsletter v. 2.01
FRANKR.ARJ 67101 02-20-94 Frankie lib. Reference v. 2.01
FT_DOC.ARJ 30249 02-20-94 Kreiranje NG iz source koda
FXCOLOR.ARJ 56249 02-20-94 Specijalni efekti sa bojama za Clipper 5.2
GENIFER.ZIP 256649 12-05-93 Generator aplikacija
IE52NG.ARJ 8982 12-05-93 NG o I/O error handlerima za Clipper 5.2
ISNET.ARJ 3017 02-20-94 patch za Netto.lib
LLIBCA.ARJ 122034 02-20-94 MSC 5.1 lib. za vezu Clipper <-> C
NEDESC11.ARJ 4787 02-20-94 Spisak fja. Netto.lib 1.1
NETGUIDE.ZIP 28400 08-16-93 Primeri za rad pod Novellom iz clippera
NETTOL.ZIP 168283 02-20-94 Novell NETWARE API lib. za Clipper 5.2
NETTOS11.A01 113435 02-20-94 Netware Clipper lib. source code 1/2
NETTOS11.A02 110604 02-20-94 -đđ-
NFDESC.ARJ 14348 01-10-92 Nanforum library toolkit
NFLIB.ARJ 167326 01-10-92 --đđ--
NFLIB21.ARJ 172416 02-20-94 NanForum Toolkit lib. ver. 2.1
NFLIB_CH.ARJ 4746 02-20-94 Header fajlovi (.CH) za Nflib21
NFPAT.ARJ 24607 01-10-92 --đđ--
NFPAT.ZIP 58077 02-20-94 Patches za NFlib21 (source...) 1...7
NFPAT8.ZIP 13259 02-20-94 Patches za NFlib21 8 deo
NFSRC.A01 150265 01-10-92 --đđ--
NFSRC.ARJ 159186 01-10-92 --đđ--
NFSRC21.A01 163620 02-20-94 Nanforum Toolkit v 2.1 source 1/2
NFSRC21.ARJ 164314 02-20-94 -đđ- 2/2
NUM2STR.ZIP 4469 02-20-94 Konverzija brojeva u slovni oblik
OBJECTCL.A01 176334 02-20-94 OOP biblioteka za Clipper 5.01 2/4
OBJECTCL.A02 176480 02-20-94 -đđ- 3/4
OBJECTCL.A03 174072 02-20-94 -đđ- 4/4
OBJECTCL.ARJ 176375 02-20-94 -đđ- 1/4
OCLIP.ZIP 17482 03-26-92 Object Oriented Lib. za Clipper
ONOTES.ZIP 29002 02-09-93 Koriscenje objektno orijentisanih biblioteka
PKV4.ZIP 15847 08-16-93 Rad sa zip 2.0 arhivama iz clippera
PPUPD1.ZIP 96842 10-04-91 1/2 Zastita Clipper programa
PPUPD2.ZIP 30332 08-18-93 2/2 --đđ--
PROPLUS.ZIP 273913 04-16-91 Biblioteke za zastitu Vasih Clipper programa
PUSHBU.ARJ 21788 02-20-94 Pushbutons za GET sistem
RADIOBUT.ZIP 5160 08-18-93 Source za radiobuttons u Clipper-u
RCMPLB20.ZIP 26120 01-11-94 kompresija za kliper
Uploaded by: Cedomir Suljagic
RPCXLB10.ZIP 196669 02-20-94 Clipper lib. za prikaz .PCX
RSHPCX12.ZIP 7056 08-16-93 Prikaz PCX iz Clipper-a
SG202.ZIP 13472 09-21-92 Scrolled GET's (skrolujuci GET, source)
SIX15_P1.ZIP 61027 02-20-94 Fix za SIx driver v 1.5
SPRINGB.ZIP 59545 10-26-91 Poziva drugi program dok se ucitava Vasa
Clipper aplikacija
STRALEY.ZIP 29194 02-20-94 Diskusija tvorca Clippera o "reusable system"
SUBNTX2.ZIP 62154 02-20-94 Filtriranje slogova u .NTX datotekama
TBMORE.ZIP 8705 12-05-93 Opis TBrowse bug-a
VERN_SIX.ZIP 6781 10-18-93 Spisak funkcija u Vern Six's Clipper 5.x
biblioteci
VS_904.A01 185609 10-18-93 Vern Six's Clipper ToolBox V.9.04
biblioteka #1
VS_904.A02 185628 10-18-93 Vern Six's Clipper ToolBox V.9.04
biblioteka #2
VS_904.A03 182629 10-18-93 Vern Six's Clipper ToolBox V.9.04
biblioteka #3
baze.podataka.292max.headroom,
FoxPro Editor Enhancements
by
Fred Wampler
Ph (615)247-6674
Dodaje još jedan popup u sistemski meni.
Popup sadrži svu silu korisnih (i manje korisnih) alatki za
debugovanje korisnikovih programa.
fpedfn2.zipbaze.podataka.293nbatocanin,
-> #288, mdrazic> Uzgred, nije deadlock karakterističan samo za baze.
Preciznije, javlja se svuda gde ima upravljanja deljenim resursima.
baze.podataka.294max.headroom,
-> #288, mdrazic> Izlaz je da neko mora popustiti (prekinuti transakciju)
> da bi se baze mogle normalno koristiti.
A i bilo bi logično :) Mislim, pre pokretanja transakcije prvo se
provere uspeli lock-ovi, pa ako su svi .T. onda giljaj, a ne da te
sistem odjedared iznenadi (a ti baš otišao na pauzu da nešto gricneš).
baze.podataka.295max.headroom,
-> #289, mdrazic> Class(y) bibliotekom (nemamo je još, oko $150 u USA).
VGENIJE, u međuvremenu pogledaj FoxPro for Windows (ako ti se baš 'oće
da radiš pod Prozorima).
baze.podataka.296max.headroom,
-> #292, max.headroomIzvinjenije :) U poruci 11.292 - FPEDFN2.ZIP
E, ali nije ZIP nego ARJ (greškica)
baze.podataka.297mdrazic,
-> #294, max.headroom>> Izlaz je da neko mora popustiti (prekinuti transakciju)
>> da bi se baze mogle normalno koristiti.
>
> A i bilo bi logično :) Mislim, pre pokretanja
> transakcije prvo se provere uspeli lock-ovi, pa ako su
> svi .T. onda giljaj, a ne da te sistem odjedared
> iznenadi (a ti baš otišao na pauzu da nešto gricneš).
To što je ovo logično meni i tebi, ne znači da je i drugima:)
Puno se poletaraca u ovom poslu opeklo po ovom pitanju. Ali
zato postoje knjige (recimo Suad Alagić: Relacione baze podataka)
pa se tamo pročita šta je drugima bio problem i kako treba raditi.
Ako pretpostavimo da učenje komandi i funkcija programerima nije
problem, onda vidim dva ključna prelaza od programiranja na
recimo dBaseIII+ do programiranja za Windows u mreži:
1. Prelaz sa 'single user' mašine na mrežu. Na mreži više
ne možeš očekivati da te išta čeka na disku što očekuješ, a ako
i postoji, ko zna da li je u poslednjoj milisekundi neko to
promenio, obrisao,... . Za svaku transakciju moraš prvo da
pripremiš teren, pa da je obaviš pazeći da ne zagušuješ druge
korisnike. Ovde se menja i filozofija otvaranja baza i indeksa,
zaključavanje tabela, editovanje itd. Video sam puno 'mrežnih'
verzija paketa koji sve otvaraju ekskluzivno - radi na mreži,
ali samo po jedan korisnik istovremeno.
2. Prelaz sa modalnog na 'event driven' programiranje. Tu već
ne znaš ni šta ti korisnik (sve) radi, kuda klikće mišom, koje
je sve procese pokrenuo (recimo otvorio više prozora za koji je
zadužen isti deo programa). Za ovo mu dođe prirodno da se koristi
neki objektno orijentisani jezik (CA-Visual Objects biće takav).
Milan
baze.podataka.298mdrazic,
-> #295, max.headroom> VGENIJE, u međuvremenu pogledaj FoxPro for Windows (ako ti
> se baš 'oće da radiš pod Prozorima).
Uz sav respekt prema proizvodu (Fox) i firmi (Microsoft) ipak
ću da sačekam CA-Visual Objects koji plasira firma orijentisana
na softver za veće sisteme pa sa client/server aplikacijama
neće biti problema. Jezik je objektni, ima sve lepe osobine
nasleđene iz Clippera (slično kao Fox), radi pod Windowsima, a
poznato je da je za Clipper (biće i za VO) najveće tržište
raznih biblioteka, RDD (database drajvera) i utilitija.
U startu ima DBF, SQL i ODBC drajvere, a kome treba još nešto,
lako se doda. Veza sa asemblerom i C jezikom je jako korisna:)
Usto Clipper je oduvek pravio kao izlaz standardni EXE fajl.
Milan
baze.podataka.299dejanr,
-> #298, mdrazic>> Uz sav respekt prema proizvodu (Fox) i firmi (Microsoft) ipak
>> ću da sačekam CA-Visual Objects koji plasira firma orijentisana
>> na softver za veće sisteme pa sa client/server aplikacijama
>> neće biti problema.
Zanimljiva stvar, u poslednjem PC Magazine-u (15. septembar) su
testirali relacione baze podataka. Ono što me je začudilo je da
ni Clipper (ni bilo šta od CA) nisu uopšte ni uzeli u obzir.
Ne znam zašto.
Editor's Choice je bio Access 2.0, dok su negde odmah iza njega
Paradox za Windows i FoxPro za DOS i Windows. Access po performansama
nije baš briljirao (FOX je redovno bio bolji) ali je izabran zbog
izuzetne fleksibilnosti, mogućnostima provere podataka, konzistencije
relacija itd.
Doduše, PC Magazine je uvek bio sklon Microsoft-u ;)
baze.podataka.300.marko.,
Ima li neko iskustva, pozitivna/negativna sa kursom ORACLE-a koji organizuje
"Vinca" institut.
Kazu mi (preko telefona) da su autorizovani, pa zna li neko koliko je to
tacno, s obzirom na sankcije (nicim izazvane :)).Usput mi rekose da njihove
diplome priznaju i napolju (daju diplomu i na Engleskom).
Unapred hvala na odgovoru!
baze.podataka.301mdrazic,
-> #299, dejanr> Zanimljiva stvar, u poslednjem PC Magazine-u (15.
> septembar) su testirali relacione baze podataka. Ono što
> me je začudilo je da ni Clipper (ni bilo šta od CA) nisu
> uopšte ni uzeli u obzir. Ne znam zašto.
Evo zašto: Clipper i nije baza podataka! Clipper je samo
(odličan) jezik za pisanje aplikacija, a ranije se zvao
prevodilac za dBase programe. Pošto nemać integrisanu
okolinu kao u dBase, FoxBase Clipper nije zgodan korisnicima
koji ujedno nisu i programeri. Da ne pominjemo interpreter
naredbi!
Pre godinu ili nešto više u Data Based Advisor-u (časopis
specijalizovan za baze na PC-ima) je bila anketa među
korisnicima o dobrim i lošim stranama raznih softvera za
baze. Na početku je bilo i napomenuto da Clipper iskače iz
opšte slike pošto je to samo jezik. Na testovima brzine,
mogućnosti, generisanja reporta i sl. testirali su za
Clipper verovali ili ne, DBU (tj. ono što ide u paketu).
Na tim testovima je lošije prošao od nekih konkurenata, ali
ubedljivo najviše ocene je (od korisnika) Clipper dobio za
bogatstvo jezika i snagu istog.:)))
Normalno, i ja se slažem da je Fox mnogo bolji po mogućnostima
od DBU.EXE .
Ista firma koja izdaje Data Based Advisor počela je da izdaje
i Clipper Advisor (dvomesečno) a tek kasnije se pojavilo
dBASE Advisor a ako postoje Fox Advisor, Access Advisor to je
tek od ovog leta možda.
Milan
baze.podataka.302vlador,
-> #301, mdrazic> Evo zašto: Clipper i nije baza podataka! Clipper je samo
Ali, u PC Worldu od maja ove godine je takođe bio uporedni test baza podataka
ali je tu bio i Clipper!
baze.podataka.303mdrazic,
-> #302, vlador> Ali, u PC Worldu od maja ove godine je takođe bio uporedni
> test baza podataka ali je tu bio i Clipper!
Šta su testirali i kako je prošao?
baze.podataka.304max.headroom,
Svima onima koji imaju pristup Internet-u, preporučujem:
FOXWISHčMICROSOFT.COM
baze.podataka.305max.headroom,
FOXDCOMP
A DECOMPILER FOR FOXBASE PROGRAMS
by
Doyle and Associates
FOXDCOMP is a program reads a precompiled Foxbase program
and recreates the original program source. This is an essential
utility for the Foxbase environment that can be used for the
following purposes:
- Recreating lost, unavailable, or destroyed source code.
This will allow modifications to an existing system
without starting from scratch.
- As an aid in understanding a purchased compiled package
that was delivered without source code. This can be
a very useful tool when adding a customized front-end
to a purchased compiled system.
- To view the source code of professionally-developed
systems in order to learn programming techniques
used to create efficient, reliable, and visually-
appealing systems.
FEATURES
- Simple DOS command-line operation.
- Correctly decompiles programs compiled with
Foxbase version 2.1 or lower.
- Written in efficiently structured C language
for FAST execution.
- Fully indented source code is produced.
- Language keywords are printed in capital letters.
Variable name are printed in lower-case.
- Macros, arrays, user-defined functions, and
functions with variable arguments are fully
supported.
Doyle and Associates
101 Westminster Road
Rochester, NY 14607
Telephone: (716) 461-1148
baze.podataka.306max.headroom,
BROWSE komanda & mrežno okruženje
NOREFRESH opcija
BROWSE prozor će biti "osvežavan" onoliko puta koliko je navedeno pri
setovanju SET REFRESH komande. Ako se želi "statičan" BROWSE prozor,
tj. prikaz podataka uzetih u određenom momentu bez daljeg obaziranja
na to da li je došlo do promene sadržaja nekog od njih, iza BROWSE
komande navodi se NOREFRESH opcija. U slučaju da je potrebno prikazati
neki read-only fajl, poželjno je navesti i NOREFRESH opciju, jerbo se
performanse time poboljšavaju. Međutim, čak i ako se ova opcija navede
(a nije u pitanju read-only fajl), i započne se sa editovanjem
podataka, editovani zapis će ipak biti pročitan sa diska (tj. biće
"svež").
TIMEOUT opcija
Uvek koristite ovu opciju BROWSE komande. žak i ako je postavite na
jedan sat, i to će biti bolje nego da BROWSE prozor "čeka" i troši
vreme serveru zahtevajući sveže podatke. Zna se kako je narod aljkav,
odn. kako voli da odluta od terminala - a te momente softver bi trebao
da prepozna.
Popravljanje BROWSE performansi
- Smanjite broj kolona (polja). Najčešće se BROWSE koristi bez liste
polja koje treba prikazati, tj. prikazuju se sva polja iz baze.
Dakle, redukujte broj dostupnih polja (BROWSE FIELDS) što više.
- Smanjite broj redova (zapisa) prikazanih na ekranu. Što je manje
zapisa prikazano, to BROWSE brže "osvežava" prozor.
- Ukinite relacije, ili bar redukujte njihov broj. Ako se vrši BROWSE
samo jedne baze, tada je mnogo bolja izvedba primeniti ručni SEEK,
ako slučaj već nalaže, tj. ako se krene sa editovanjem nekog
zapisa. Evo primera: zamislite pet baza - jedna sadrži imena
takmičara, druga njihove datume rođenja, treća postignute
rezultate, četvrta adrese, a peta plasman na tekućem takmičenju.
Kada se radi BROWSE takmičara, tada je za pretpostaviti da će se
uvesti relacije kojima ćemo na ekranu u istom redu za svakog
takmičara imati prikazane sve ostale relevantne podatke. Medžutim,
;), svakako je brže pre BROWSE-a ukinuti relacije, a po
aktiviranjui sa ON KEY LABEL uraditi SEEK u svakoj bazi i tako na
ekranu prikazati ostale podatke, a pomoću BROWSE-a samo imena
takmičara (primer glup ali ukazuje na suštinu ekonomisanja sličnog
tipa :)
- Učestalost osvežavanja (SET REFRESH). Što je ona veća, performanse
opadaju. Na primer, u bazama u kojima se promene vrše retko (baza
dobavljača, na primer), ova cifra treba da bude velika (tj.
osvežavanje se vrši u većim vremenskim razmacima - 300 sekundi ili
više). Ako se, pak, zaželi edit određenog zapisa, uvek se dobija
najsvežija informacija.
- Fizički sortirajte bazu. FoxPro nije jedina aplikacija koja
inteligentno koristi keševe i bafere; većina mrežnih operativnih
sistema koristi disk-keš da poboljša performanse. Kada se zatraži
zapis iz DBF fajla, FoxPro konvertuje broj zapisa u ofset u fajlu.
Tada traži od mreže podatke sa pomenute ofset lokacije, u dužini
od onoliko bajtova kolika je veličina zapisa. Mreža ispunjava
zahtev, ali takođe kopira taj sektor u svoj vlastiti interni keš.
Ako je dužina sektora (mreža) 4,096 bajtova, na primer, i dužina
zapisa 64 bajta, tada sektor prekopiran u keš sadrži tekući zapis,
zajedno sa još 47 susednih :) Ali ako su zapisi sortirani fizički,
tada je mreži potrebno da pristupi disku tek posle svakih 48
zapisa. Ako se, međutim, zapis čita preko indeksa, brojevi zapisa
mogu biti razbacani po fajlu, smanjujući verovatnoću da će traženi
podatak biti moguće izvući direktno iz keša.
baze.podataka.307max.headroom,
Jeste li već čuli da... :)
FLOCK() i RLOCK() komande Fox-a "pate" od jednog nedostatka: naime,
raznorazne prethodne i buduće Fox razvojne aplikacije prepoznaju da je
fajl zaključan; ali, drugi xBASE paketi poput CA-Clipper-a - NE. Sledi
objašnjenje:
DOS 3.1 je predstavio novu funkciju koja bi trebala da bude korišćena
od strane programa glede kontrole shared pristupa podacima. Ta
LOCK/UNLOCK funkcija uzima četiri parametra: file handle, ofset,
veličinu, i fleg koji indicira da li je u pitanju lock ili unlock.
Kada se izvrši lock, svaki pristup tom delu fajla (odn. fajlu) je
zabranjen. Ali, trenutak... ako je pristup zabranjen, kako FoxPro čita
zaključani zapis? Odgovor na ovo pitanje je da su FoxPro dizajneri
iskoristili činjenicu da LOCK ne mora da bude fizički smešten u okviru
fajla. Kada FoxPro zaključa zapis, on preračuna ofset u fajl uzimajući
veličinu hedera + veličinu zapisa * broj zapisa (minus jedan). Potom
dodaje 40,000,000 heksadecimalno (ili 1,073,741,824) bajtova na ofset,
i zaključava tako dobijene bajtove u dužini zapisa. Fox ne zaključava
ofset unutar samog fajla. To omogućava read pristup fajlu, dok se
write pristup koordinira preko FoxPro programa.
Ekipa koja je osmišljala CA-Clipper koristila je sličnu strategiju da
dozvoli čitanje zaključanih zapisa. Nažalost, oni su uzeli jednu
milijardu kao ofset (a ne 40 miliona). I CA-Clipper zaključava samo
jedan bajt, a ne onoliko kolika je dužina zapisa. Tako, ako je
CA-Clipper-om zaključan deseti zapis, a isto se uradi i sa Fox-om,
operativni sistem misli da postoje dva lock-a: jedan na ofsetu
1,000,000,010, a drugi na drugom ofsetu. I eto haosa :)
baze.podataka.308max.headroom,
The GOFER UDF gofer()
Definition The gofer UDF allows the programmer to place
database information in picklist format in a FoxPro
browse window so a user can easily locate and accept or
reject items in the list. gofer() returns a .t. or .f.
reflecting the choice made.
gofer002.arjbaze.podataka.309sir.oracle,
Postovane kolege,
Iako ovo mozda nije najprikladnije mesto za oglasavanje ovakve vrste
pokusacu da vam za trenutak skrenem paznju ovim tekstom.
Ukoliko medju vama ima dobrih ORACLE programera, koji su spremni na
saradnju po pitanju izrade jednog vrlo kokretnog projekta sa vrlo konkretnim
rokom i vrlo konkretnim zadatkom, molio bih da mi se jave ili preko prijatelja
ostave svoje podatke u mail-u za korisnika sir.oracle (odnosno mene). Ocekujem
da ce u vasim dopisima biti puno pitanja, ali bih molio da u prvom dopisu koji
posaljete prilozite sledece podatke:
-Ime i prezime (obavezno)
-Username na sezam-u za slanje dopisa (obavezno)
-Godina rodjenja (opciono)
-Broj telefona (opciono)
-Gde radite (opciono)
-Koliko dugo radite u ORACLE-u (obavezno)
-Na kojim ste projektima radili do sad (opciono)
(njihov naziv i trajanje)
-Ostali licni i profesionalni podaci (opciono)
po vasem izboru
U odgovoru na vas dopis dobicete sto je moguce vise podataka o poslu i
projektu osim informacija koje predstavljaju poslovnu tajnu.
U OBZIR DOLAZE SVI OBLICI SARADNJE POCEV OD UGOVORA ZA "SLOBODNJAKE"
DO STALNOG ZAPOSLENJA ZA PROGRAMERE KOJI ZELE DA PROMENE RADNO MESTO.
Javite se na mail: sir.oracle, ocekujem vase dopise
ps. Rok za odgovor je 7 dana.
baze.podataka.310.ken.,
-> #307, max.headroom
> FLOCK() i RLOCK() komande Fox-a "pate" od jednog nedostatka:
> naime, raznorazne prethodne i buduce Fox razvojne aplikacije
> prepoznaju da je fajl zakljucan; ali, drugi xBASE paketi poput
> CA-Clipper-a - NE.
Clipper-a 5.2 cak i sam poseduje dve vrste zakljucavanja (za RDD NTX)
Default koje je kompatabilno sa starim nacinom zakljucavanja (Clipper 5.01)
i nova vrsta kod koje je ofset prebacen na FFFFFFFF (sto je najveci ofset
dozvoljen sistemom DOS-a - izvor Joseph D.Booth i Greg Lief)
Ako zelimo da imamo novi nacin zakljucavanja treba ulinkovati datoteku
NTXLOCK2.OBJ
Mislim, mada nisam imao prilike da probam da SIXCDX RDD za Clipper ima
mogucnost da radi kompatabilno sa FOX-om i da ne prave probleme jedan
drugom.
baze.podataka.311vlador,
-> #303, mdrazic>> Ali, u PC Worldu od maja ove godine je takođe bio uporedni
> Šta su testirali i kako je prošao?
Na žalost, nisam čitao, samo mi je tekst proleteo kroz ruke. O:)