CATEGORII DOCUMENTE |
Relatii intre tabele. Programe. Filtre.
FOR <conditie>
FREEZE <camp> - permite modificarea doar a valorilor campului specificat
NOAPPEND - interzice inserarea de inregistrari
NODELETE - interzice marcarea pentru stergere in fereastra BROWSE
NOMODIFY, NOEDIT - interzic modificarea inregistrarilor existente, dar permit adaugarea si stergerea de inregistrari
TITLE<string> - permite schimbarea titlului ferestrei BROWSE
VALID <conditie> permite verificarea corectitudinii inregistrarilor introduse
WHEN <conditie> - se evalueaza ori de cate ori pozitionam cursorul pe o noua inregistrare; in cazul in care conditia este adevarata, este permisa modificarea liniei respective, altfel nu.
FIELDS - permite vizualizarea si modificarea numai unei parti din campuri; se pot crea si campuri "imaginare" (campuiri calculate)
Clauza FIELDS are la randul ei o serie de parametri:
:R - campul vizualizat nu poate fi modificat
:V=<conditie> - permite efectuarea de validari suplimentare asupra datelor
:E=<string> - mesajul de eroare ce va fi afisat in status bar in cazul in care conditia din :V este falsa.
:B=<lim_inf>, <lim_sup> - permite incadrarea corecta a datelor introduse.
Intre tabele apar relatii, adica legaturi orientate care determina ca orice repozitionare a cursorului in primul tabel (tabel-parinte) sa atraga dupa sine o repozitionare a cursorului in cel de-al doilea tabel (tabel-copil). Pentru ca sa se poata realiza o relatie, este necesar ca intre cele doua tabele sa existe un camp comun.O relatie in care unei inregistrari din tabelul parinte ii corespunde exact o inregistrare in tabelul copil, se numeste relatie one-to-one. O relatie in care unei inregistrari din tabelul parinte ii pot corespunde zero, una sau mai multe inregistrari din tabelul copil relatia se numeste one-to-many.
SET RELATION - creeaza relatii one-to-one intre tabele.
SET RELATION TO
[<expr1> INTO <expN1> | <expC1>
[, <expr2> INTO <expN2> | <expC2> ]
[ADDITIVE]]
Exemplu: Indexati tabelul copil (SALARIAT) dupa campul comun (sdep):
Urmatoarea secventa de instructiuni creeaza o relatie one-to-one :
CLOSE DATABASES
USE salariat IN 1 INDEX idep.idx && tabel copil
USE departament IN 2 && tabel parinte
SELECT 2
SET RELATION TO dcod INTO 1
select 1
BROWSE NOWAIT
SELECT 2
BROWSE NOWAIT
SET SKIP - creeaza relatii one-to-many. Comanda se utilizeaza impreuna cu SET RELATION.
!!! Tabelul copil trebuie indexat dupa cheia externa (campul comun - sdep). Daca indexarea se face prin index compus structural, inainte de crearea relatiei se va executa comanda:
Altfel, daca se indexeaza prin index simplu, vezi exemplul anterior.
CLEAR
CLOSE DATABASES
USE departament in 0 && tabel parinte
USE salariat ORDER TAG depart in 0 && tabel copil
SELECT departament
SET RELATION TO dcod INTO salariat && stabilire relatie one-to one
SET SKIP TO salariat && relatie one-to-many
SELECT salariat
BROWSE NOWAIT
SELECT departament
BROWSE NOWAIT
RELATION() Returneaza campul pe care s-a facut legatura.
RELATION(<expN1>[, <expN2> | <expC>]). ExpN1 - numarul de ordine al relatiei. ExpC - alias-ul tabelului. ExpN2 - aria de lucru. Implicit foloseste aria de lucru curenta
TARGET() Returneaza alias-ul tabelului care este tinta unei relatii (specificat in clauza SET RELATION dupa INTO)
TARGET(<expN1>[, <expN2> | <expC>]) - la fel ca mai sus
? target(1)
a) IF <expresie_logica>
<set de instructiuni>
[ELSE
< set de instructiuni >]
ENDIF
b) FOR <memvar> = <expN1> TO <expN2> [STEP <expN3>]
<set de instructiuni>
[EXIT]
ENDFOR
memvar = variabila de memorie; expN= expresie numerica.
Exemplu: (afisarea numerelor impare de la 1 la 10)
CLOSE DATABASES
CLEAR
FOR mcount = 1 TO 10 STEP 2
? mcount
ENDFOR
Exemplu: (afisarea numelor tiparite cu majuscule, utilizand FOR)
SET TALK OFF
USE SALARIAT
GO TOP
STORE RECNO() TO I && STORE - comanda pentru atribuire; este utila atunci cand
&& stocam aceeasi valoare in mai multe variabile care vor aparea
&& in comanda separate prin virgule
STORE RECCOUNT() TO J
FOR mcount = I TO J
GOTO mcount
DISPLAY UPPER (snume)
ENDFOR
USE
c) DO WHILE <expr_logica>
<set instructiuni>
[
[EXIT]
Exemplu: (afisarea primelor 10 numere Fibonacci)
CLOSE DATABASES
CLEAR
STORE 1 TO t0
STORE 1 TO t1
?'t0=',t0
?'t1=',t1
i = 1
DO WHILE i<10
temp = t0 + t1
t0 = t1
t1 = temp
?'t'+alltrim(str(i,2)),'=', str(t1,2)
i=i+1
ENDDO
d) DO CASE
CASE <expL1> && expL = expresie logica
<set instructiuni>
[CASE <expL2>
< set instructiuni >
CASE <expLN>
< set instructiuni >]
[OTHERWISE
< set instructiuni >]
ENDCASE
Exemplu: (stabilirea in functie de luna curenta, a anotimpului in care ne aflam)
STORE CMONTH(DATE( )) TO luna
DO CASE
CASE INLIST(luna,'March','April','May')
STORE 'Este primavara!' TO anotimp
CASE INLIST(luna,'June','July','August')
STORE 'Este vara!' TO anotimp
CASE INLIST(luna,'September', 'October','November')
STORE 'Este toamna!' TO anotimp
OTHERWISE
STORE 'Este iarna!' TO anotimp
ENDCASE
WAIT WINDOW anotimp NOWAIT
e) SCAN - muta pointerul in tabelul current si executa un bloc de comenzi pentru fiecare inregistrare care indeplineste conditiile.
[<scope>]
[FOR <expL1>]
[WHILE <expL2>]
[<set_instructiuni>]
[LOOP]
[EXIT]
Exemplu: (afisarea salariatilor si acordarea unei mariri de 250 la salariul celor din departamentul 30, care castiga mai putin de 500)
close database
clear
use salariat
go 1
display all
scan all for scopii>1
if ssalariu<500
endif
endscan
display all
f) EXIT apare in blocuri de tipul DO WHILE, FOR sau SCAN. Transfera controlul la instructiunea imediat urmatoare blocului.
g)
Aplicatie: Parcurgeti tabela de angajati. Sumati salariile celor care lucreaza in departamentul 30 si au salariul mai mic decat media pe unitate. (Indicatie : calcul medie, parcurgere si pentru fiecare inregistrare, daca salariul e mai mare ca media sau nu lucreaza in departamentul 30, salt la sfarsitul ciclului, altfel continuare cu calculul sumei)
h) ACCEPT - citire variabila de la tastatura (sir de caractere)
[<expC>]
TO <memvar>
Exemplu:
? var_nume
i) WAIT [<expC>]
TO <memvar>
[WINDOW [NOWAIT]]
Exemplu :
WAIT WINDOW "numele noului client este: ";
+ var_nume NOWAIT
j) INPUT intoduce date de la tastatura; asemanator cu ACCEPT
Exemplu :
INPUT 'Dati numele noului client: ' TO var_nume
&&textul dat de la tastatura se scrie intre ghilimele
? var_nume
Interogari - modalitati de consultare a informatiilor din mai multe tabele. Se creaza o interogare (FILE -> NEW -> Query sau CREATE QUERY <nume_query>).
QBE (Query By Example) este un limbaj de interogare interactiv, care va permite sa spuneti sistemului ce doriti, si nu cum sa obtineti date din mai multe tabele (neprocedural). In linia de comanda poate scrie CREATE QUERY si se deschide editorul pentru query.
Reamintiti-va posibilitatile meniului Query, atunci cand este deschis un Query. Observati optiunile de adaugare sau eliminare de tabele din interogare - clauza FROM (a instructiunii SELECT din SQL), conditii de filtrare a inregistrarilor din rezultat - clauza WHERE, lista campurilor de afisat - lista SELECT, clauza de ordonare ORDER BY, clauza de grupare GROUP BY, clauza HAVING care pune conditii asupra gruparilor, butonul 'View SQL' (din toolbar-ul Query Designer sau din meniu) unde se poate consulta comanda SQL generata de ecran, si optiunea 'Run Query' din meniul Query.
Exercitii:
I. [BROWSE]
Sa se afiseze numele, prenumele, departamentul, salariul, comisionul si salariul anual al angajatilor, urmate de o coloana care va indica username-ul. Aceasta va fi constituita dintr-un sir de caractere format din: primele 2 caractere ale numelui, ultimele 3 caractere ale prenumelui, urmate de anul angajarii. Salariul anual se va calcula dupa formula: ssalariu*(1+spccomision/100)*12.
brow fields snume, sprenume, ssalariu, spccomision ;
salariu_anual=ssalariu*(1+spccomision/100)*12, ;
username=alltrim(left(snume,3))+alltrim(str(year(sdataang)))
Obs Reamintim ca ; este caracter de continuare al comenzii pe linia urmatoare.
2. Sa se deschida o fereastra Browse care afiseaza numele, prenumele si data angajarii. Sa se impuna sa nu se poata face modificari care nu respecta conditia ca prima litera din nume si cea din prenume sa fie majuscule.
brow fields snume :V=isupper(snume) :E='numele cu litera mare', sprenume :V=isupper(sprenume) :E='prenumele cu litera mare'
II. [Programe]
Fara a cunoaste codurile departamentelor, creati un program care sa afiseze pentru un departament date in felul urmator: departamentul .... are .....salariati.
Solutie: Se creeaza un index pe campul sdep.
Programul va utiliza urmatoarele comenzi: SET PATH TO, CLOSE DATABASES, WAIT WINDOW, EOF, DO WHILE. ENDDO.
set safety off && determina suprimarea afisarii unui avertisment inainte de suprascrierea
&& unui fisier
index on sdep to idep
set path to c:fpw26work
close all
clear
USE salariat in 1 index idep
list
wait window 'tabelul salariat'
use departament in 2
sele 2
list
wait window 'tabelul departament'
sele 1
GO 1
do while not eof()
nr=salariat.sdep
rec=recno()
* ?nr,'dep',sdep, rec
COUNT FOR salariat.sdep=nr TO numar
* ?numar
?'Departamentul ' +ltrim(str(nr))+' are ' +ltrim(str(numar))+' salariati'
go rec
do while nr = salariat.sdep && trecere la urmatorul cod de departament
skip
enddo
enddo
Sa se localizeze in tabelul DEPARTAMENT departamentul care contine in nume sirul 'are' si are cel putin 2 angajati. In functie de rezultat (FOUND() = .T. sau .F.) sa se dea mesajul potrivit.
close all
clear
USE salariat in 1
USE departament in 2
sele 2
locate for like('*are*',dnume)
do while found()
n=dcod
sele 1
count for sdep=n to x
if x>=2
?'departamentul'+str(n)+'are'+str(x)+'angajati'
endif
sele 2
continue
enddo
Obs: CONTINUE este comanda care determina continuarea cautarii incepute de ultimul LOCATE. Aceasta comanda nu este corecta daca nu a fost lansat un LOCATE inainte.
Calculati numarul salariatilor care castiga comision (in sensul ca valoarea campului scomision nu este NULL), media salariilor celor care au o adresa de e-mail in campul sinfo si suma salariilor pentru acei angajati care fac parte din departamentul cu numele 'Cercetare'.
close all
clear
USE salariat in 1
USE departament in 2
sele 1
count for ISNULL(spccomision)=.F. to x
?'Nr salariatilor care au comision: ' +str(x)
calculate avg(ssalariu) for like('*@*',sinfo) to y
?'Media salariatilor care au adresa de e-mail:'+str(y)
sele 2
locate for ALLTRIM(UPPER(dnume))='CERCETARE'
n=dcod
sele 1
calculate sum(ssalariu) for sdep=n to z
?'Suma salariilor angajatilor din departamentul Cercetare este:'+str(z)
Afisati pentru fiecare departament in parte un rand de genul:
Departamentul . cu codul . este de dimensiuni . (medii, mari, mici)
unde mici - sub 3 angajati, medii - 3-7 angajati, mari - peste 7 angajati.
close tables
clear
use salariat in 1
use departament in 2
sele 2
scan
nr=dcod
select 1
COUNT FOR salariat.sdep=nr TO numar
do case
case numar<3
s='mici'
case numar<=7
s='medii'
otherwise
s='mari'
endcase
select 2
?'Departamentul '+ dnume+' cu codul '+ltrim(str(nr))+' este de dimensiuni '+s
endscan
III. [Relatii intre tabele]
Sa se analizeze comenzile SET RELATION, SET SKIP si functiile RELATION() si TARGET().
Legati intre ele tabelele SALARIAT si DEPARTAMENT (dupa codul departamentului).
clear
close all
USE departament in 0 && tabel parinte ; IN 0 =>se deschide in zona de lucru
&& disponibila cu nr cel mai mic
USE salariat in 0 && tabel copil
sele salariat
INDEX ON sdep to idep
SELECT departament
SET RELATION TO dcod INTO salariat && stabilire relatie
SET SKIP TO salariat && One-to-many relatie
SELECT salariat
BROWSE NOWAIT
SELECT departament
BROWSE NOWAIT
Sa se afiseze numele departamentului si salariatii acestuia, pentru un cod de departament introdus de la tastatura. Daca nu exista inregistrari cu acest cod, sa se afiseze un mesaj corespunzator.
close all
clear
accept 'Introduceti codul departamentului ' to x
use salariat in 1
use departament in 2
sele 1
SELECT departament
SET RELATION TO dcod INTO salariat && stabilire relatie
SET SKIP TO salariat && One-to-many relatie
sele 2
locate for dcod=val(x)
if found()
?' in departamentul '+dnume+ " lucreaza: "
sele 1
do while sdep=val(x)
?snume+' '+sprenume
skip
enddo
endif
IV. [Filtre]
Salariatii si numele departamentelor din care fac parte. (ordonate dupa numele departamentului, si pentru nume egale de departament dupa numele salariatului descendent.)
<tabele> cele 2 tabele folosite : salariat si departament. Legatura dintre ele, conditia de join : salariat.sdep INNER JOIN departament.dcod. (ce se intampla daca nu punem conditie de join? Incercati, observati produsul cartezian dintre cele doua tabele).
<campuri> ce campuri vreau sa contina
<order by> dnume ascendent, nume+prenume descendent
Suma salariilor pe departamente;
<tabele> cele 2 tabele folosite : salariat si departament
<join> salariat.sdep INNER JOIN departament.dcod
<functii si expresii> SUM(ssalariu)
<campuri> ce campuri vreau sa contina (departament.dnume, SUM(ssalariu))
<grup> dcod sau sdep (de ce e echivalent?) (GROUP BY)
Nr. de salariati pe departamente.
<tabele> departament si salariat
<join> salariat.sdep INNER JOIN departament.scod
<functii> count(*) (numara inregistrarile)
<campuri> dcod, dnume, COUNT(*)
<grup > dcod
( modificare - comanda MODI QUERY sau File->Open->nume_query.qpr )
Analizati pentru fiecare interogare comanda SQL atasata!
Sa se listeze departamentele (numele acestora) in care exista salariati al caror salariu nu depaseste 300 unitati.
<tabele> cele 2 tabele folosite : salariat si departament
<join> salariat.sdep INNER JOIN departament.dcod
<campuri> ce campuri vreau sa contina (departament.dnume)
<filter> ssalariu < 300
<miscellaneous> se bifeaza "no duplicates"
14. Sa se listeze numele salariatilor si numele managerilor acestora.
<tabele> se va deschide de 2 ori tabelul salariat (la a doua deschidere, sistemul ii va atribui alias-ul salariat_a)
<join> salariat.smanager INNER JOIN salariat_a.scod
<campuri> salariat.scod, salariat.snume, salariat_a.scod, salariat_a.snume
15. Stergeti coloana sgrila din tabelul SALARIAT (in cazul in care exista). Sa se listeze numele salariatilor, numele departamentului in care lucreaza, salariul si grila de salarizare corespunzatoare.
<tabele> cele 3 tabele folosite : salariat, departament si grila
<join> salariat.sdep INNER JOIN departament.dcod; nu dam nici o conditie de join pentru grila
<filter> salariat.ssalariu BETWEEN grila.gmin, grila.gmax
<campuri> salariat.snume, departament.dnume, salariat.ssalariu, grila.gcod
Sa se creeze un filtru ce contine salariatii (nume, prenume) avand salariul mai mare de 3000, din departamentul 30.
Daca este folosit SET FILTER sunt afisate doar inregistrarile care satisfac o anumita conditie
Sintaxa este SET FILTER TO [<expL>] . De asemenea, functia FILTER() returneaza filtrul curent.
set exact off
set filter to ssalariu < 3000 and sdep = 30
disp snume,sprenume,ssalariu all
?filter()
set filter to && fara parametru => se elimina filtrul
disp all
Exemple:
a) Sa se creeze un filtru ce contine salariatii angajati in 2003, in ordine alfabetica dupa nume. (Observatie: pentru ordonare trebuie sa existe deja tag-ul snume in fisierul index structural: index on snume tag snume)
disp all
set filter to year(sdataang)=2003
disp all
set order to tag snume
disp all
b) Salariatii angajati in 1975 care au salariul*20% > 500. (cu DISPLAY .. FOR sau SET FILTER TO si DISPLAY).
Disp sdatanas,ssalariu for year(sdataang)=1975 and ssalariu*0.2 > 500
c) Salariatii cu salariul cuprins intre 300 si 500.
Disp for ssalariu>300 and ssalariu <500
Care este diferenta intre o simpla clauza FOR dintr-o comanda si un filtru? La ce credeti ca foloseste filtrul?
Problema 9, dar rezolvata prin filtre (query).
Rezolvare :
se face cererea cerere.qpr corespunzatoare urmatorului cod SQL :
SELECT DISTINCT Departam.dnume, Salariat.scod, Salariat.snume,;
Salariat.sprenume, Salariat.ssalariu;
FROM Departam, Salariat;
WHERE Salariat.dcod = Departam.dcod;
AND Departam.dcod = VAL(coddep)
- se scrie programul
close databases
clear
*coddep=0 && necesara pentru precizarea unei valori implicite pentru coddep
&& am comentat-o pentru ca am folosit mai jos "default", care realizeaza
&&acelasi lucru
@10,10 say 'Dati codul departamentului: ' get coddep default 0
read
use departament
go 1
store 0 to gasit && echivalent cu gasit=0
scan all
if dcod=val(coddep)
gasit=1
endif
endscan
if gasit=1
do cerere.qpr
else
? 'Departamentul cu codul ' + coddep +' nu exista'
endif
Obs: Pentru afisare si citire am utilizat comenzile @ < pozitie> SAY, @ <pozitie> GET care definesc campuri de iesire, respective de intrare. Pentru citirea efectiva din campul GET se utilizeaza comanda READ.
Sa se afiseze numele si prenumele celui mai bine platit salariat, precum si numele departamentului in care lucreaza. Daca exista mai multi salariati cu salariul maxim, se vor afisa numele, prenumele si departamentul fiecaruia.
- cererea cerere1.qpr:
SELECT Salariat.scod, Salariat.snume, Salariat.ssalariu, Departament.dnume;
FROM Salariat, Departament;
WHERE Departament.dcod = Salariat.sdep;
AND Salariat.ssalariu = salmax
programul :
close database
use salariat
CALCULATE MAX(Salariat.ssalariu) TO salmax
clear
? 'Salariul maxim este ' + ltrim(str(salmax))
display snume,ssalariu all
do cerere1.qpr
V. [Comenzi]
19. Analizati sintaxa comenzilor:
SET FIELDS, SELECT, JOIN, CREATE/MODIFY QUERY/VIEW, SET VIEW TO.
SET FIELDS - specifica ce campuri ale unui tabel pot fi accesate
SET FIELDS ON | OFF | LOCAL | GLOBAL
sau
SET FIELDS TO [[lista_campuri] | ALL]
ON -doar campurile specificate in lista pot fi accesate
OFF - toate campurile pot fi accesate
GLOBAL -pot fi accesate si campuri din alte zone
close all
use salariat in 1
use departament in 2
set fields on
disp all
set fields to departament.dcod,departament.dnume
sele 2
disp all
set fields off
disp all
set fields local
go 1
?departament.dnume
?recno(1) && verificati ca in zona 1 nu suntem pe ultima inregistrare
?salariat.snume && incercare esuata de acces la campul snume din alta zona
set fields global
disp salariat.sdep, dnume all
JOIN - creaza un .dbf prin jonctiunea a doua tabele existente
JOIN WITH <expN> | WITH <expC> TO <file> FOR <expL>
[FIELDS <field list> | FIELDS LIKE <skel> | FIELDS EXCEPT <skel>] [NOOPTIMIZE]
<expN>|<expC> reprezinta aria de lucru a celui de-al doilea tabel
Exemplu: - pentru fiecare salariat date personale plus nume departament
- tabele indexate dupa dcod
use salariat in 1
use departament in 2
join with departament to njoin.dbf for salariat.sdep=departament.dcod;
fields salariat.scod,salariat.snume,departament.dnume
use njoin.dbf
disp all
CREATE VIEW - creaza un fisier.vue care contine informatii diverse despre sesiunea curenta.
SET VIEW TO - deschide sau inchide fereastra view sau revenire in mediul fox
SET
SET VIEW TO <file> | ? - revenire in mediul fox
Exemplu:
create view vvv - creare vizualizare
set view on - deschidere + lucru
set view off - inchidere
set view on
set view to vvv.vue - intoarcere la conditiile initiale
20. Analizati functiile EOF, ROW,
a) EOF - determina daca s-a ajuns cu pointerul la sfarsitul fisierului .dbf (deschis in zona precizata sau cea curenta daca nu se precizeaza) si intoarce .T. daca pointerul e la sfrarsit si .F. in caz contrar
EOF([<expN> | <expC>]) - aria de lucru optional, daca nu - tabelul curent.
use salariat
go 4
?eof()
b) ROW/COL - returneaza linia/coloana pozitiei curente a cursorului. Este folosit pentru afisare pe ecran. In locul acestor functii poate fi folosit operatorul $.
Exemplu:
CLEAR
FOR i=1 TO 15
@ 1,i SAY '0'
@ i,1 SAY '0'
ENDFOR
SAY '-0-'
@ ROW( ) + 5,
@ $ + 5, COL( ) SAY '-0-'
c) PCOL/PROW - returneaza coloana/linia pozitiei curente a capului imprimantei. Depinde de setarile marginii din stanga
Exemplu:
@ PROW( ), PCOL( ) + 12 SAY '00000'
@ PROW( ), $+12 SAY '-----'
d) MESSAGE - returneza mesajul erorii curente ca sir de caractere sau continutul linei de program care a dus la eroarea respectiva. MESSAGE([1]) -se poate folosi argumentul optional 1 si se va intoarce linia de program care contine eroarea ; daca nu se foloseste argumentul 1 se va intoarce mesajul erorii
ON ERROR <comanda>. Executa comanda respectiva la aparitia unei erori. Fara parametrul <comanda> restaureaza tratarea implicita a erorilor.
Exemplu:
CLEAR
ON ERROR DO proc;
WITH ERROR( ), MESSAGE( ), MESSAGE(1), PROGRAM( ), LINENO( )
USE salariat
USE salariat IN 2
ON ERROR
PROCEDURE proc
PARAMETER errno, errmes, errline, errprog, errlno
? 'linia de cod care contine eroarea: ' + errline ;
+ ' pe pozitia ' + str(errlno, 2)
? 'numarul erorii: ' + STR(errno, 3) && sau direct STR(ERROR())
? 'mesajul erorii: ' + errmes && sau direct MESSAGE( )
? 'programul care a generat eroarea ' + errprog
e) DIFFERENCE - returneaza un intreg de la 0 la 4 care reprezinta diferenta fonetica relativa dintre doua expresii de tip caracter. 4 daca cele doua expresii sunt foarte appropriate, si 0 la polul opus
DIFFERENCE(<expC1>, <expC2>)
Exemplu:
clear
STORE 'informatica' TO nume1
STORE 'informator' TO nume2
STORE 'info' TO nume3
STORE 'matematica' TO nume4
? DIFFERENCE(nume1, nume2)
? DIFFERENCE(nume1, nume3)
? DIFFERENCE(nume1, nume4)
f) FV = valorile unei investitii in functie de plata initiala, dobanda si numarul de plati -
FV(<expN1>, <expN2>, <expN3>)
Exemplu:
STORE 1000 TO p && plata lunara
STORE .045/12 TO d && 4.5% dobanda anuala
STORE 24 TO t && perioada de timp de efectuare a platilor (24 luni)
? FV(p, d, t) && valoarea calculata
Aplicatie Valoarea unei investitii de 10.000, dupa 20 de luni, cu o dobanda de 7% pe luna.
? fv(10000,.07/1,20)
g) PAYMENT = plata pentru amortizarile unui credit - PAYMENT(<expN1>, <expN2>, <expN3>)
Exemplu:
STORE 100000 to principal && $100,000 credit
STORE .105/12 TO interest && 10.5% dobanda
STORE (20*12) TO payments && 20 de ani de plati lunare
? PAYMENT(principal, interest, payments)
Aplicatie: Sa se afiseze: "Azi.....la ora.....plata de amortizare a creditului este ....." (pentru niste valori date ale parametrilor).
Tema :
Sa se creeze un program care sa rezolve ecuatia a*x^2+b*x+c=0, unde coeficientii a, b, c sunt respectiv lungimile valorilor caracter snume, sprenume, sjob corespunzatoare inregistrarii curente.
Parcurgerea tabelului SALARIAT si afisarea liniilor una cate una.
Deschideti o fereastra de tip Browse care sa contina codul salariatului, numele, prenumele si o coloana care sa precizeze trimestrul in care s-a angajat.
browse fields scod, snume, sprenume, sdataang, ;
trimestru=iif(inlist(month(sdataang),1,2,3),1,;
iif(inlist(month(sdataang),4,5,6),2,;
iif(inlist(month(sdataang),7,8,9),3,4)))
Functia INLIST(expresie, valoare_1, valoare_2, ., valoare_n) intoarce .T. daca expresie se afla printre valorile specifocate, .F. altfel.
[EXIT] Parcurgeti tabela de angajati. Exista salariat angajat in 2000 ?(Indicatie: Parcurgere tabela, verificare a fiecarei inregistrari daca are year(sdataang) = 2000 si daca s-a gasit iesire din ciclare.)
Program prin care sa se marcheze pentru stergere, cerand de la tastatura confirmare individuala, salariatii cu salariul mai mic decat valoarea medie a tuturor salariilor din tabelul SALARIAT.
Idee de rezolvare:
close all
use salariat
list
AVERAGE Salariat.ssalariu TO media
store 0 to var
clear
accept 'Daca doriti sa marcati pentru stergere scrieti 1: ' to var
if val(var)=1
?
?'Media obtinuta este '+ltrim(str(media))
delete all for ssalariu<media
display scod,snume,ssalariu all
else
?'Nu s-a marcat nimic pentru stergere'
endif
Salariatii cu salariul cuprins intre 3000 si 5000.
a) Media salariilor pe orasele in care se afla departamentele (dloc);
b) Orasele care au media salariilor > 250.
Obs: Pentru impunerea de conditii asupra grupurilor realizate prin GROUP BY, se utilizeaza clauza HAVING.
Diferenta dintre conditia impusa la tab-ul FILTER din Query Designer si cea impusa la HAVING: conditia FILTER este evaluata pentru fiecare linie a tabelului, iar cea din HAVING este evaluata pentru fiecare grupare realizata prin GROUP BY.
Cati salariati sunt in Bucuresti? Creati un .DBF asociat filtrului ce contine doar salariatii din Bucuresti.
Obs: Pe toolbar-ul Query Designer se afla un buton Query Destination, care ne permite sa setam modul de livrare al rezultatului cererii: in fereastra Browse, pe ecran, in tabel etc.
9. Care este orasul cu cei mai multi angajati?
10.Departamentele in care media salariilor depaseste 3000.
11. Informatii complete despre directorii departamentelor
SELECT Departament.dmanager, Salariat.scod, Salariat.snume,;
Salariat.sprenume;
FROM Departament, Salariat;
WHERE Salariat.scod = Departament.dmanager
Sa se afiseze salariatii din departamentele localizate in orasele al caror nume incepe cu literele introduse de la tastatura. (de exemplu, va fi suficient sa tastam doar B, sau Bu, sau Buc etc pentru a obtine salariatii din Bucuresti). Pentru citire, se va folosi @ . say. get si comada read. Rezultatul cererii va fi stocat intr-un tabel.
Indicatie: Conditia de filtrare este:
LEFT(ALLTRIM(LOWER(dlocatie)), LEN(x))=ALLTRIM(LOWER(x))
unde x este variabila in care este citit sirul de caractere introdus de utilizator.
Obs: Pentru ca editarea unei conditii in fereastra Query Designer este destul de anevoioasa si presupune rescrierea acesteia daca s-a gresit ceva, se poate proceda astfel: se deschide fisierul .qpr corespunzator query-ului fie din Explorer -> click dreapta pe fisier -> Open With.-> Notepad sau din Fox prin comanda MODIFY COMMAND fisier.qpr. Astfel, se pot opera modificari chiar in comanda SQL.
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 2390
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved