Programul ACCESS pune la dispoziþia utilizatorilor mai multe metode de extragere a informaþiilor din bazele de date. Aceste metode se bazeazã pe conceptul de interogare query (interogare).
Interogãrile sunt mici programe care comandã extragerea adãugarea sau modificarea datelor dintr-un tabel. Interogãrile pot fi independente sau înglobate în formulare sau rapoarte, însã toate sunt construite cam în acelaºi mod.
Interogarea este necesarã atunci când nu avem nevoie de tot tabelul ci numai de articolele (sau poate numai de anumite pãrþi din articolele) care prezintã anumite particularitãþi, adicã îndeplinesc anumite criterii pe care ºtim precis cã nu toate articolele le pot îndeplini. Desigur nu ne opreºte nimeni sã facem o interogare ºi pe toate articolele din tabel, dar acesta ar fi un caz particular. Înterogarea în sine nu este altceva decât o comandã de genul "Selecteazã articolele care îndeplinesc condiþia . ºi fã cu ele .", unde condiþia este descrisã foarte clar, iar ce sã facã cu ele, iarãºi este precizat foarte bine. În aceste condiþii, interogarea poate cãpãta un nume ºi poate fi salvatã (stocatã) ºi apelatã ori de câte dorim. Access stocheazã interogãrile în douã moduri total diferite: prin grila QBE (Query By Example) ºi în limbaj SQL (Standard Query Language). Cum situaþia din baza de date se schimbã în timp, este normal ca ºi rezultatele obþinute cu o anume interogare, chiar dacã ea s-a pãstrat intactã, sã difere de la o etapã de timp la alta (exceptând cazul când între timp nu s-a mai schimbat nimic în baza de date). Rãspunsul la o interogare mai poate sã fie diferit de la o rulare la alta ºi pentru cã interogarea poate fi conceputã sã fie aplicatã pe fiºiere asemãnãtoare, dar diferite ca semnificaþie. De exemplu aceeaºi interogare poate fi aplicatã pe soldul de la magazia 1, dar poate fi aplicatã ºi pe soldul de la magazia 2. 121g66b În acest caz numele tabelului va fi un parametru pentru acea query.
Interogãrile care extrag date din tabele creeazã obiecte similare tabelelor (ca aspect ºi funcþionare). În afarã de interogãrile de tip Select, în Access pot fi folosite ºi alte tipuri de interogãri:
- Interogãri Delete ( de ºtergere) ºi Update (de actualizare), care ºterg sau modificã articolele ce îndeplinesc condiþiile impuse prin interogare;
- Interogãri Append (de adãugare în tabel) ºi Make-Table (care creeazã un tabel), care creazã date noi ºi le adaugã la tabele existente sau creeazã tabele noi;
- Interogãri Crosstab (încruciºate), care centralizeazã datele extrase din tabele contorizând ºi combinând datele din mai multe câmpuri sursã în unul sau mai multe câmpuri de ieºire.
Acesta este modul implicit de a crea interogãri. Pentru aceasta vom proceda stfel:
- In fereastra Database vom selecta Query ºi vom da clic pe New. Ca urmare pe ecran va apare caseta de dialog New Query, care ne va cere precizãri în legãturã cu metoda de generare a interogãrii.
- Vom alege Design View apoi Ok când va apare caseta de dialog Show Table ºi grila QBE, care pot fi vãzute pe pagina urmãtoare. Sã remarcãm cã o interogare se poate aplica nu numai pe un tabel ci ºi pe rezultatul unei alte interogãri, care aºa cum am precizat mai sus, se poate prezenta tot sub formã de tabel.
O interogare se ruleazã selectând butonul Run de pe bara cu instrumente. Revenirea în modul de afiºare Design, se face cu
butonul View de pe bara cu
instrumente.
Help on line se obþine, dând clic în rândul care ne intereseazã ºi apãsând apoi tasta F1.
Aceste interogãri reprezintã tipul implicit pentru care este pregãtit Access, când lansãm Query Design. Tabelul rezultat pe baza unei astfel de interogãri poate fi folosit ca suport pentru un formular, un raport sau o altã interogare.
În acest tip de interogãri, în grila QBE se mai
foloseºte o linie ºi anume linia Totals care se obþine dând clic pe
butonul cu acelaºi nume de pe bara
cu instrumente.
Rândul Total apare pe locul trei ºi acolo se pot introduce tot felul de funcþii statistice cum ar fi Sum, Avg, StDev, Var, funcþii care gestioneazã gruparea datelor (Last, First), sau funcþii care introduc expresii complexe în interogãri (Expression).
Expression evidenþiazã faptul cã intrarea din linia câmpului este o expresie care include funcþii statistice sau orice altã expresie. De exemplu Numeîntreg: [nume] & " " & [prenume] sau vânzãri:Sum([linie comandã].[pretunitar]*[cantitate]).
Remarcãm cã Expression ocupã pe linia Total locul ce ar putea fi ocupat de o funcþie statisticã, cum ar fi Sum, dar cu Expression pus pe linia Total, Sum (sau oricare altã funcþie), poate fi inclusã în expresia trecutã pe linia Field ca în fereastra de mai jos:
Mai
poate fi introdusã opþiunea Grouped By care realizeazã o grupare a
articolelor dupã valorile din câmpul a cãrui nume se gãseºte în linia Fields.
Aceste funcþii se pot obþine dintr-o listã ascunsã ce poate fi activatã pe linia Total, din orice coloanã, dând clic în extremitatea dreaptã a casetei situate la intersecþia liniei Total cu coloana ce ne intereseazã.
Funcþia selectatã se aplicã asupra valorilor din câmpul a cãrui nume este scris în coloana unde a fost plasatã funcþia sau dupã caz, asupra întregului articol, dar ele nu acþioneazã asupra înregistrãrilor care în câmpul ce face obiectul funcþiei conþin valoarea Null.
De exemplu funcþia Count doar numãrã articolele, nu executã operaþii asupra unui câmp anume, dar oricum aceste funcþii acþioneazã numai asupra articoleleor care au trecut testul impus de criteriul din linia Criteria.
Odatã introdus un criteriu, se pot introduce criterii adiþionale pe acelaºi câmp sau pe alte câmpuri.
Când se introduc expresii de tip criteriu, în mai multe celule de pe linia Criteria, Access le combinã folosind operatorii OR sau AND. Dacã expresiile sunt pe acelaºi rând, ele sunt legate cu AND. Dacã expresiile sunt pe rânduri diferite, între rânduri se considerã OR.
În grila QBE, momentul când se executã calculele depinde de locul unde am amplasat criteriul ºi anume:
- pentru ca înainte de a face calculele sã grupãm articolele pe categorii (de exemplu pe þãri, eventual ºi companii - aici intervine ºi ordinea amplasãrii câmpurilor) în linia Total, vom introduce Group By.
-
pentru a selecta rezultatele dupã ce am fãcut calculele, în coloana câmpului
implicat în calcule (prin operaþii specificate pe linia Total), pe linia
Criteria, vom introduce un criteriu privitor la rezultatele calculului.
Este cazul câmpului ExtendedPrice din exemplul alãturat, unde se
calculeazã suma acestui câmp, pentru toate articolele care au trecut filtrul cu
ShipCountry, dar din ele se vor afiºa doar sumele mai mici de 10000.
- pentru a limita înregistrãrile înainte ca ele sã fie grupate ºi înainte de a se face calcule, vom include în grilã ºi câmpurile pentru care se vor defini criteriile de limitare, iar criteriile se vor introduce pe linia Criteria ca în cazul câmpului Ship Country din exemplul de mai sus, unde pentru ShipCountry se admit doar valorile Canada sau UK.
Dacã
în interogare se executã calcule folosind linia Total (în exemplul de
mai jos se face o sumã pe Extended Price) ºi vrem sã limitãm intrarea
articolelor în calcule (de exemplu numai la cele cu Extended Price sub
500), vom deschide o nouã coloanã pentru câmpul implicat în operatia de pe
linia Total, iar criteriul pe cea de a doua apariþie a câmpului , îl vom
introduce cu ajutorul clauzei Where, plasatã pe linia Total.
Remarcãm cã un criteriu de limitare a întrãrii articolelor în calcul ar putea
fi provenit ºi din condiþii impuse asupra altui câmp decât cel implicat în
calcule. În acest caz, nu va mai fi o a doua apariþie a câmpului implicat în
operaþii ci în locul sãu, deci pe coloana unde se va introduce clauza Where,
va fi introdus numele câmpul implicat în condiþie.
Expresiile prin care se exprimã criteriile de pe linia Criteria, se pot introduce prin tastare sau folosind Constructorul de Expresii (Expression Builder). Pentru a obþine Constructorul de Expresii, daþi clic dreapta în celulã ºi apoi clic pe Build.
Dacã interogarea include tabele puse în relaþie, valorile ce le specificãm în criteriile privitoare la câmpuri, sunt sensibile la litere mari ºi mici, adicã valorile din criteriu trebuie sã se potriveascã cu cele din tabele ºi la caractere (conteazã dacã sunt scrise cu litere mari sau mici).
(pe linia Field) (pe linia Criteria)
OraºDestinaþie "London" Afiºeazã comenzi de expediere la
Londra
OraºDestinaþie "
afisa comenzi de expediere la
Londra sau Hedge End.
DataExpedierii Between #1/5/95# And #1/10/95# Foloseºte operatorul Between
.And. pentru a afiºa comenzi de expediere cuprinse între 5 Ian.
95 ºi 10 Ian.95
DataExpedierii #2/2/95# Afiºeazã comenzile expediate pe
Þarãdestinaþie In("
printre elementele mulþimii
[
Þarãdestinaþie Not "
afiºa comenzile expediate oriunde
cu excepþia USA
DenumireCompanie >="N" Afiºeazã comenzi expediate la
companiile ale cãror nume încep
cu litere de la N la Z.
NrCrtComandã Right([NrCrtComandã], 2)="99" Foloseºte funcþia Right pentru a
afiºa comenzi ale cãror numãr
curent (cheie) se terminã în 99.
DenumireCompanie Len([DenumireCompanie]) Foloseºte funcþiile Len ºi Val
>Val(30) pentru a afiºa comenzi pentru
companiile a cãror denumire este
mai lungã de 30 de caractere
NumeDestinatar Like "S*" Comenzi expediate clienþilor ale
cãror nume încep cu litera S
NumeDestinatar Like "*Imports" Comenzi expediate clienþilor ale
cãror nume se terminã cu
cuvântul "Imports".
NumeDestinatar Like "[A-D]*" Comenzi expediate clienþilor
a cãror nume începe cu litere de
la A la D.
NumeDestinatar Like "*ar*" Comenzi expediate clienþilor a
cãror nume include secvenþa de
litere "ar".
NumeDestinatar Like "Cristea Ion??" Comenzi expediate clienþilor
cu numele de Cristea iar prenu-
mele începe cu Ion, dar se ter-
minã cu douã litere necunoscute
Exemple cu expresii care folosesc câmpuri cu valoare necompletatã ( ºir de lungime zero sau valoarea Null)
Judeþuldestinaþie Is Null Afiseazã comenzile pentru clienþii ale cãror
câmpuri privitoare la Judeþuldestinaþie
sunt blanc sau conþin valoarea Null.
Judeþuldestinaþie Is Not Null Afiseazã comenzile pentru clienþii ale cãror
câmpuri privitoare la Judeþuldestinaþie
conþin o valoare.
Fax " " Afiseazã comenzile pentru clienþii care nu au fax
situaþie indicatã printr-un ºir de lungime zero,
plasat în câmpul Fax în loc de o valoare Null
sau blanc cum se pune la cei care au fax.
Exemple de expresii care calculeazã sau manipuleazã date calendaristice ºi apoi folosesc rezultatele drept criteriu
Datacerutã Between Date( ) And Foloseºte operatorul Between .And,
DateAdd("m", 3, Date( )) funcþiile DateAdd ºi Date pentru a afiºa comenzi cerute între data de astãzi ºi trei luni în urmã.
Datacomenzii < Date( )- 30 Foloseºte funcþia Date pentru a afiºa
comenzi mai vechi de 30 de zile
Datacomenzii Year([Datacomenzii])=1996 Foloseºte funcþia Year pentru a afiºa
comenzi cu datacomenzii în 1996
Datacomenzii DatePart("q", [Datacomenzii])=4 Foloseºte funcþia DatePart
pentru a afiºa comenzi pentru trimestrul IV
Datacomenzii DateSerial(Year Foloseºte funcþiile DateSerial, Year ºi
([Datacomenzii]), Month pentru a afiºa comenzi pentru
Month([Datacomenzii])+1, 1)-1 ultima zi a fiecãrei luni.
Datacomenzii Year([Datacomenzii])= Foloseºte funcþiile Year ºi Month
Year(Now()) And precum ºi operatorul And pentru a Month([Datacomenzii])= afiºa comenzi pentru luna ºi anul
Month(Now()) curent
Exemple de expresii care folosesc funcþii agregat (funcþii statistice ce se aplicã pe un domeniu definit)
Funcþiile agregat sunt:
Davg: calculeazã media unui set de valori asociate unui set de articole (domeniu)
Sintaxa: Davg(expr, domain[,criteria])
unde expr poate fi un identificator de câmp ce conþine valori numerice, domain poate fi un nume de tabel sau query ºi criteria poate fi o expresie ºir folositã pentru a restrânge domeniul de aplicare a funcþiei.
Dcount: determinã numãrul de articole ce se aflã într-un set specificat de articole.
Sintaxa: Dcount (expr, domain[,criteria])
Dlookup: aduce valoarea unui câmp anume dintr-un set specificat de articole
Dfirst, Dlast: aduce un articol aleatoriu dintr-un câmp al unui tabel sau query, când se doreºte orice valoare din acel câmp.
Dmin, Dmax: determinã valorile minimã ºi maximã dintr-un set de articole.
DstDev, DstDevP: estimeazã deviaþia
standard pe mulþimea de valori a unui set de articole. Exemplu: DStDevP(
"[Freight]",
"Orders", "[ShipCountry] = '
calculeazã deviaþia standard pentru populaþia comenzilor trimise cãtre
Dsum: calculeazã suma mulþimii valorilor dintr-un set specificat de articole.
Dvar, DvarP: estimeazã varianþa aplicatã pe mulþimea valorilor dintr-un set specificat de articole.
Exemple de expresii care folosesc funcþii agregat
Freight |
>(DStDev("[Freight]", "Orders") + DAvg("[Freight]", "Orders")) |
Foloseºte funcþiileDAvg ºi DstDev pentru a afiºa toate comenzile pentru care costul costul se ridicã peste medie plus deviaþia standard a costului transportului (livrãrii). |
Quantity |
>DAvg("[Quantity]", "Order Details") |
Foloseºte funcþia DAvg pentru a afiºa produse comandate în cantitãþi peste media cantitãþilor prevãzute în comenzi. |
Exemple de expresii care folosesc drept criteriu chiar rezultatul unei subquery
UnitPrice |
(SELECT [UnitPrice] FROM [Products] WHERE [ProductName] = "Fanta") |
Produse al cãror preþ este acelaºi ca al produsului "Fanta") |
UnitPrice |
>(SELECT AVG([UnitPrice]) FROM [Products]) |
Produse care au preþul unitar peste medie. |
Salary |
> ALL (SELECT [Salary] FROM [Employees] WHERE ([Title] LIKE "*Manager*") OR ([Title] LIKE "*Vice President*")) |
Salariile pentru toþi salariaþii de la Desfaceri, a cãror salariu este mai mare decât acela al salariaþilor care la rubrica Titlu/Funcþie au specificat "Manager" sau "Vice President" |
OrderTotal: |
> ALL (SELECT AVG([UnitPrice] * [Quantity]) FROM [Order Details]) |
Comenzi al cãror total pe comandã este mai mare decât valoarea medie a unei comenzi. |
Exemple de queries de tip Select
II. Elaboraþi o interogare care sã ne prezinte situaþia intrãrilor de la începutul anului, având câmpurile: nr_NIR, data_NIR, cod_mat, cantitate, pret de achiziþie.
III. Elaboraþi o interogare care sã ne prezinte situaþia
intrãrilor totale, pe materiale, de la începutul anului, având câmpurile:
cod_mat, total_cant_intrata.
IV. Completaþi tabelul STOC folosind o interogare conceputã de Dv. care va fi rulatã pentru fiecare material ºi pentru fiecare gestiune.
Problema se rezolvã în douã faze: În prima fazã se analizeazã situaþia din punct de vedere logic, iar în a doua fazã se transpune logica cu privire la modul de interogare, în modul de operare a grilei QBE.
- faza 1:
analizând structura tabelelor MATERIALE, MATERIALE CONSUMATE ºi NIR, precum ºi
legãturile dintre aceste tabele, determinate de cheile lor primare ºi externe,
putem observa cã pentru o magazie (gestiune), a calcula întrãrile (pentru firecare material) pe baza Nir-urile cu care
am completat baza de date pentru anul 2000, înseamnã a selecta materialele dupã
COD_MAT din [MATERIALE], pentru fiecare
material fãcând sumã de CANTITATE [MATERIAL_APROVIZIONAT], folosind în acest
scop relaþia MATERIALE COD_MAT MATERIALE_APROVIZIONATE NR_NIR NIR, unde COD
_GESTIUNE=1
Structura tabelelor implicate în aceastã interogare ca ºi legãturile dintre ele, sunt reprezentate pe pagina urmãtoare.
- faza doua
constã în a traduce obiectivul propus în faza întâia, în regulile de exprimare
folosite în grila QBE.
Imaginea grilei
care rezolvã acest obiectiv este datã mai jos. Din imagine se vede cã iniþial
s-a solicitat o grupare a materialelor din tabelul MATERIALE pe coduri, ceea ce
este foarte simplu, pentru cã aceste coduri sunt unice, dar în cadrul acestei
grupãri, articolele corespunzãtoare, deci cele din tabelul
MATERIALE_APROVIZIONATE, vor fi grupate fiecare pe codul venit din tabelul
MATERIALE. Totusi la aceastã grupare care în cadrul unui cod de material se
concretizeazã ºi cu o însumare (Sum), nu sunt admise decât înregistrãrile a cãror
Nr_NIR ne duc în tabelul NIR, la un Cod_Gestiune egal cu 1 (evident pentru
magazia 2 Cod_Gestiune va trebui sã fie egal cu 2 , º.a. m.d.)
Rulând de trei ori interogarea de mai sus, deci odatã pentru fiecare gestiune, vom obþine trei tabele pe care le vom putea folosi la completarea tabelului STOC. Desigur aceastã soluþie este una de început, deoarece se poate concepe o interogare care sã ia în calcul ºi soldul existent la data începerii evidenþei din tabelul materiale aprovizionate, chia dacã soldul la acea datã era unul diferit de zero. Pentru simplificare, în exemplul nostru, soldul la data începerii evidenþei, era zero la toate materialele, astfel cã soldul calculat cu interogarea este ºi soldul absolut pentru fiecare material în parte.
V. Completaþi câmpul valoare facturã folosind o interogare proiectatã de Dv. în acest scop. În aceastã problemã vom lua fiecare facturã (Group By) ºi pentru fiecare facturã, vom parcurge toate articolele din MATERIALE_APROVIZIONATE. Dacã Nr_Nir din articolul luat din MATERIALE_APROVIZIONATE, ne duce la un NIR, al cãrei NR-Facturã este egal Nr-Facturã pentru care calculãm în acel moment valoarea facturii, atunci articolul din MATERIALE_APROVIZIONATE, va contribui la creºterea valorii facturii prin faptul cã produsul Preþ_Achiziþie*Cantitate, va fi însumat la valoarea factu-rii, Val_Facturã. Rezultatul acestui raþionament este concretizat în grila QBE de mai jos:
De exemplu vrem sã vedem primele 5 facturi având valorile
cele mai mari. Formularea SQL a unei asemenea interogãri este datã în imaginea
alãturatã. Pentru aceasta am elaborat normal interogarea cu grila QBE,
doar cã am fãcut o sortare dupã câmpul valoare din facturã, în ordine
descrescãtoare (descending), folosind linia Sort. În timp ce mã aflam cu
cursorul în coloana acestui câmp, am selectat butonul ºi de acolo am ales
valoarea 5. Acest buton oferã
posibilitatea sã alegem primele 5, 25, 100 articole sau 5%, 25% ºi All (toate
înregistrãrile). Atenþie! Sortarea trebuie fãcutã în concordanþã cu ordinea
cerutã de acest tip de interogare, dacã sortarea s-a fãcut dupã alte câmpuri
sau în ordinr inversã decât trebuie rezultatele vor fi incorecte.
Dacã este cazul, în loc de câmpuri putem folosi expresii care implicã câmpuri, iar dacã asupra acelor expresii trebuie sã efectuãm operaþii cu funcþii statistice ca Sum, Avg, etc. putem specifica funcþia în linia Total. Dacã o astfel de funcþie este cazul sã fie implicatã chiar în expresia câmpului calculat, atunci pe linia Total se specificã Expression.
Dacã totuºi în privinþa câmpului calculat ar trebui specificat ceva în linia Total, atunci pe coloana urmãtoare se ve relua câmpul calculat, de astã datã doar cu numele, iar în linia Total, putem pune funcþia de care este nevoie.
Crearea ºi folosirea interogãrilor Delete (de ºtergere)
O interogare Delete eliminã înregistrãri din tabelul de bazã. Este bine ca înainte de a rula o astfel de interogare sã facem o salvare a tabelului de bazã ºi sã simulãm rularea interogãrii, afiºând interogarea în modul de afiºare Datasheet, pentru a anticipa efectele interogãrii. În modul de afiºare Datasheet, se poate intra din modul Design, alegând meniul View ºi opþiunea Datasheet. Dacã suntem de acord sã se ºteargã articolele pe care le-am vãzut acolo, vom reveni în modul Design ºi apoi vom alege butonul Run din bara de instrumente a Query Designer-ului. Urmeazã un mesaj de avertizare ºi dacã s-a selectat butonul Yes, înregistrãrile respective vor fi ºterse.
În principiu, o astfel de interogare ºterge numai înregistrãrile care îndeplinesc condiþiile impuse asupra câmpurilor specificate în linia Field. Dacã se doreºte ºtergerea tuturor informaþiilor dintr-un tabel, se va deschide interogarea în modul de afiºare Design ºi în final, steluþa din panoul Relationship, aflat deasupra grilei QBE, va fi trasã în linia Field, sau se va da pe ea dublu clic. Dacã nu am specificat de la început cã dorim sã creem o interogare de tip Delete, este timpul s-o facem acum, folosind opþiunea Delete din meniul Query sau butonul Query Type, prezentat pe pagina anterioarã.
În acel moment liniile Sort ºi Show vor fi înlocuite cu linia Delete. Câmpurile asupra cãrora vrem sã impunem criterii vor fi plasate pe coloanele urmãtoare, iar criteriile vor respecta regulile generale privitoare la criterii aºa cum au fost ele prezentate la interogãrile de tip Select.
În afarã de criteriile impuse asupra înregistrãrilor ce vor fi ºterse, mai trebuie sã þinem seamã de relaþiile dintre tabelul ale cãrui înregistrãri vor fi ºterse ºi alte tabele.
Astfel, dacã acest tabel este implicat prin cheia sa primarã, într-o relaþie cu alt tabel (copil, primul fiind tabel pãrinte) ºi opþiunea Cascade Delete Related Records a fost activatã în fereastra Edit Relationship, încã de la proiectarea bazei de date sau ulterior, la ºtergerea unui articol din tabelul pãrinte, toate articolele din tabelul copil, a cãror cheie (consideratã externã faþã de fiºierul pãrinte), au aceeaºi valoare cu cheia primarã a articolului ºters, vor fi ºterse. Dacã opþiunea Cascade Delete Related Records, nu este activatã, Access nu va da voie sã ºtergem articole din tabelul pãrinte, pânã ce nu vom ºterge articolele din tabelul copil, corespunzãtoare articolelor ce vor fi ºterse din tabelul pãrinte. Dacã am avut de gând sã ºtergem doar articole din tabelul pãrinte ºi opþiunea Cascade Delete Related Records era activatã, am pierdut articolele din baza de date copil pe care nu voiam sã le ºtergem. Deci atenþie, mare atenþie!
Acestea opereazã aproape în acelaºi mod ca ºi interogãrile de tip Delete, doar cã efectul lor în ce priveºte relaþiile între tabele va depinde de opþiunea Cascade Update Related Fields ce se poate activa tot din fereastra Edit Relationship. Practic cu aceastã interogare se poate selecta un subset de înregistrãri în vederea actualizãrii. De fapt interogarea aceasta face ºi modificãrile specificate, iar rezultatele interogãrii nu pot fi anulate decât restaurând întreaga bazã de date, aºa cã ºi înainte de rularea unei astfel de interogãri, va trebui sã salvãm tabelul, sau dupã caz baza de date ce va fi afectatã.
Ce fel de modificãri face o astfel de interogare? Sunt modificãri ce pot fi exprimate prin valori specifice câmpurilor. De exemplu putem înlocui un furnizor cu altul, selectând toate articolele referitoare la primul ºi apoi înlocuind codul primului cu al celui de al doilea.
Când alegem acest tip de interogare liniile Sort ºi Show vor fi înlocuite cu linia Update To, unde se va introduce noua valoare a câmpului ce urmeazã a fi modificat. Evident câmpul trebuie adus în linia Fields, iar în coloana lui sau dupã caz a altui câmp, trebuie sã introducem criteriu de selectare pentru actualizare. Astfel în exemplul cu furnizorii în coloana cod_furnizor, vom introduce la criteriu codul vechiului furnizor, iar în linia Update To, vom introduce codul noului furnizor. Deoarece vom dori sã previzualizãm efectul interogãrii în modul de afiºare Datasheet, în exemplul de mai sus am vedea doar coduri de furnizori, ceea ce nu ne-ar edifica supra efectului actualizãrii. De aceea ar trebui sã implicãm în query ºi unele câmpuri care nu trebuie modificate, cum ar fi nume_furnizor. Alt motiv pentru care putem introduce câmpuri ce nu fac obiectul modificãrii este nevoia uneori de a face selectãri pe criterii ce se aplicã altor câmpuri decât cele ce urmeazã a fi modificate. Indiferent de motiv, câmpurile care apar într-o astfel de interogare dar nu trebuie modificate, vor avea prevãzut, în coloana lor, pe linia Update To, denumirea câmpului pusã între paranteze drepte, adicã le modificãm ºi pe ele, dar defapt nu le modificãm, în schimb vor apare ºi ele în Datasheet view, pentru ca noi sã vedem mai clar cui se aplicã modificãrile cerute. În exemplul cu furnizorii, dacã am renunþat la un furnizor, în afarã de modificarea câmpului furnizor, din tabelul Produse, probabil cã va trebui ºters funizorul din tabelul Furnizori, lucru ce se poate face direct în modul DataSheet selectând înregistrarea ºi ºtergând-o cu tasta Delete sau folosind o interogare de tip Delete, ceea ce ar fi exagerat!
Adãugarea unor înregistrãri într-un tabel existent cu ajutorul interogãrilor Append
La selectarea acestui tip de interogare, suntem solicitaþi sã dãm numele tabelului la care se vor alipi înregistrãrile furnizate de interogare; linia Show este înlocuitã cu Append To, iar linia Sort rãmâne în grilã. Înterogare se traduce prin "Insert în tabelul .ceea ce vom selecta cu criteriile. din tabelul.doar de acolo unde este îndeplinitã condiþia."
Pe linia Append To se vor introduce numele câmpurilor care în procesul de adãugare de articole, vor primi valori, adicã acolo se vor introduce câmpuri din tabelul destinaþie, în timp ce sus, pe linia Field, vom avea denumiri de câmpuri din tabele sursã.
Mare atenþie trebuie acordatã câmpurilor cheie primarã (în cazul în care nu sunt de tipul Autonumber), în sensul cã printre câmpurile din tabelul destinaþie, ce vor primi valori în procesul de adãugare de articole, trebuie sã fie ºi câmpul cheie primarã, dacã un asemenea câmp existã. Evident cã aceste valori nu vor fi acceptate decât dacã nu duplicã cheile existente. La adãugare sunt verificate ºi regulile de validare în sensul cã la câmpuri omoloage ele trebuie sã fie aceleaºi.
Acestea opereazã la fel ca ºi interogãrile Select, exceptând faptul cã atunci când selectãm tipul Make-Table, ni se cere numele tabelului ce va fi creat. Grila QBE rãmâne ca la interogãrile de tip Select. La rulãri repetate, Access ºterge tabelul din rularea precedentã ºi îl creazã din nou, ceea ce impune atenþie sã nu dãm unui tabel astfel creat, numele unui tabel de bazã din compunerea bazei de date pentru cã vom rãmâne fãrã el. Odatã selectat tipul Make-Table, restul decurge ca la orice interogare de tip Select. Ceea ce este specific acestui tip de interogare este faptul cã însereazã înregistrãrile selectate într-un tabel nou.
Crearea ºi utilizarea interogãrilor Crosstab (încruciºate)
Pentru a folosi o interogare Crosstab, datele din sursa de date trebuie sã aibã urmãtoarele caracteristici:
- sã existe o valoare care se repetã în mai multe înregistrãri, evident în acelaºi câmp;
- sã existe un câmp care se preteazã la centralizare (cantitãþi vândute, sume încasate, etc.);
- sã existe un câmp pentru care se poate face centralizarea ( de ex. o datã calendaristicã sau o zonã geograficã);
O interogare Crosstab, centralizeazã datele într-un tabel de bazã, sortându-le pe linii ºi coloane unde:
- titlurile de linii conþin numele elementelor/datelor care trebuie centralizate (produse individuale, sau agenþi de vânzãri);
Termenul de linie
derivã dintr-o structurã arborescentã a unor date, care în final, dupã
dezvoltarea arborelui se intersecteazã cu o coloanã (una singurã), dar care
poate fi defalcatã pe mai multe coloane (subcoloane). trim I trim II trim III trim IV
produs
De exemplu;
În acest exemplu , dezvoltând produsele dupã nume, apoi dupã clienþi ºi în final dupã ani, va rezulta câte un rând pentru fiecare sfârºit de ramurã a arborelui. Acel rând se va inter-secta cu o coloanã, de exemplu cu total vânzãri (defalcat pe trimestre). De fapt despre aceste rânduri este vorba, dar în tabel titlurile lor apar ca titluri de coloane, deoarece liniile sunt valori ale aceleeºi coloane. Astfel din structura de mai sus, va rezulta tabelul:
Linii |
Vânzãri pe produs, pe client, pe an ºi pe trimestre |
|||||
produs |
clienti |
anul |
trim I |
trim II |
trim III |
trim IV |
Coca Cola |
Ionescu | |||||
Coca Cola |
Vasilescu | |||||
Coca Cola |
Catargiu | |||||
Drojdie |
Ionescu |
| ||||
Drojdie |
Oniºor |
- titlurile de coloane conþin o descriere a modului în care sunt centralizate datele (pe date calendaristice, sau pe regiuni);
- celulele de la intersecþiile liniilor ºi coloanelor
conþin datele centralizate.
Interogarea Crosstab, Quarterly Orders byProduct, elaboratã pentru trei tabele a cãror machetã completã este vizibilã în imaginea din stânga, reflectã structura arborescentã de mai sus.
În acest tabel denumirea unui produs se repetã pentru fiecare client. Sunt selectate numai vânzãrile pe 1995, defalcate trimestrial.
Grila QBE, pentru aceastã interogare este datã mai jos sub forma a douã fragmente, deoarece s-a dorit sã se prezinte expresiile complete care au stat la baza acestei interogãri
Privind structura arborescentã de mai sus, se vede clar cum se justificã apartanenþa coloanelor ProductName, CustomerID ºi OrderYear la categoria denumiri de rânduri.
Echivalentul SQL al acestei interogãri este urmãtorul:
TRANSFORM Sum(CCur([Order Details].[UnitPrice]*[Quantity]*(1-[Discount])/100)*100) AS ProductAmount
SELECT Products.ProductName, Orders.CustomerID, Year([OrderDate]) AS OrderYear
FROM Products INNER JOIN (Orders INNER JOIN [Order Details] ON Orders.OrderID = [Order Details].OrderID) ON Products.ProductID = [Order Details].ProductID
WHERE (((Orders.OrderDate) Between #1/1/95# And #12/31/95#))
GROUP BY Products.ProductName, Orders.CustomerID, Year([OrderDate])
PIVOT "Qtr " & DatePart("q",[OrderDate],1,0) In ("Qtr 1","Qtr 2","Qtr 3","Qtr 4");
Paºii pentru elaborarea grilei QBE a unei interogãri Crosstab, dupã ce s-a selectat tipul interogãrii ºi s-au selectat tabelele ºi câmpurile implicate în interogare sunt urmãtorii:
- Pentru câmpurile a cãror valoare dorim sã aparã ca denumire de rând, vom da clic pe rândul Crosstab ºi apoi clic pe opþiunea Row Heading din lista ascunsã care apare. Pentru aceste câmpuri, în rândul Total vom lãsa opþiunea implicitã Group By.
- Pentru câmpurile a cãror valoare dorim sã aparã ca denumire de coloanã, vom da clic pe rândul Crosstab ºi apoi clic pe opþiunea Column Heading. Vom putea alege Column Heading numai pentru un câmp, iar în rândul Total, pentru acel câmp, vom lãsa opþiunea implicitã Group By. Implicit, denumirile de coloane sunt sortate în ordine alfabeticã. Modificãri se pot face cu proprietatea ColumnHeadings.
- Pentru câmpurile a cãror valoare dorim s-o folosim în tabelare încrucisatã, vom da clic în rândul Crosstab si apoi pe optiunea Value. numai un câmp poate fi pus pe optiunea Value.
In linia Total a acestui câmp vom selecta tipul de funcþie agregat (Sum, Avg, sau Count) pe care o dorim pentru tabulare încruciºatã.
- Pentru a specifica criteriile de limitare (filtre) pe denumiri de rânduri, înainte de a se efectua calculele, vom introduce expresii/filtre în linia Criteria pentru un câmp calificat în celula Crosstab drept Row Heading. De exemplu putem afiºa total vânzãri pentru produsele dintr-o anumitã categorie, cum ar fi peste, carne, etc.
- Pentru a specifica criteriile de limitare a înregistrãrilor, înainte ca denumirile de rânduri sã fie grupate ºi înainte ca sã se execute tabularea încruciºatã, vom adãuga câmpul pentru care dorim sã introducem criteriu în grilã, vom da clic pe linia Total în dreptul acelui rând, lãsãm celula Crosstab goalã, ºi apoi vom introduce un criteriu (expresie) în rândul Criteria.
Valoarea realã a interogãrilor constã în capacitatea acestora de a relaþiona date din surse de date diferite ºi de a le returna sub forma unui tabel unitar. Sã ne amintim de interogarea propusã pentru calculul adaosului la stoc, în cazul materialelor intrate în gestiunea unei magazii pe baza articolelor introduse de noi în tabelul Materiale Aprovizionate. Pentru a realiza acea interogare a fost nevoie de trei tabele: Materiale, Nir ºi Materiale Aprovizionate: se lua pe rând câte un material din nomenclator ºi se cãuta prezenta sa în articolele din Materiale Aprovizionate. Când se gãsea acolo un articol bun, se verifica în tabelul Nir, dacã Nir-ul cu care a venit trimitea materialul la gestiunea pentru care calculam adaosul la stoc. Dacã rãspunsul era afirmativ, materialul se însuma la cantitatea rezultatã din însumarea articolelor bune precedente, iar în final acela era surplusul de stoc pentru materialul curent.
Pentru a folosi mai multe tabele ca bazã pentru o interogare, tabelele trebuie puse în relaþie sau asociate. Asocierea (Join) este fuzionarea a douã tabele pe baza unei chei comune. De regulã este vorba de o cheie primarã (ceea ce atribuie tabelului rolul de tabel pãrinte) ºi o cheie externã, care nu trebuie sã fie cheie primarã, dar sã aibã aceeaºi semnificaþie ºi proprietãþi ca ºi chie primarã. Cheia externã conferã tabelului din care face parte, rolul de tabel copil, ºi defineºte o relaþie de tip una la mai-multe.
De regulã, în manualele de baze de date, acest tip de relaþie între bazele de date s-a descris cu tabela pãrinte în stânga ºi cea copil în dreapta, relaþia plecând de la tabelul pãrinte/sursã spre cel copil/destinaþie.
Între douã tabele se pot defini douã tipuri de relaþii: internã (Inner Join) ºi externã (Outer Join). Prin operaþia bazatã pe Inner Join se extrag toate înregistrãrile din tabela sursã care au înregistrãri echivalente în tabela de destinaþie (pentru care câmpurile de legãturã sunt identice).
Prin operaþia bazatã pe Outer Join se extrag toate înregistrãrile din tabela sursã, iar din tabelul destinaþie numai acele înregistrãri a cãror cheie este egalã cu o cheie din tabelul sursã. Problema este cã aici prin sursã ºi destinaþie nu mai înþelegem pãrinte ºi copil, ci tabela luatã ca reper prin adãugarea termenului de stânga sau dreapta. Astfel existã Left Outer Join, când sursa este tabelul pãrinte, dar existã ºi Right Outer Join când sursa este tabelul copil. Remarcãm cã alternativa de a pleca din tabelul pãrinte Left Outer Join cu un articol ºi de a gãsi în tabelul copil cel puþin un articol cu cheia externã având aceeaºi valoare cu cheia primarã aleasã, se poate încheia fãrã nici un articol. De exemplu avem un nomenclator cu toate materialele posibile, dar multe dintre ele încã nu au fost procurate niciodatã. În acest caz, pentru astfel de materiale, în tabelul copil (Materiale aprovizionate), nu vom gãsi nici un articol. În cazul articolelor din tabelul pãrinte care nu au corespondent în tabelul copil, câmpurile corespunzãtoare tabelului copil, vor rãmâne goale.
Mai existã ºi categoria asocieri intrinseci (self joins), care se realizeazã pe câmpuri aparþinând aceluiaºi tabel. Aceste câmpuri folosesc valori cu aceeaºi semnificaþie, dar cu rol diferit. De exemplu în tabelul Angajaþi avem un câmp numit cod_pers, dar ºi un câmp numit ºef-direct, care nu poate lua valori decât din câmpul cod_pers. În aceste condiþii între câmpul cod_pers ºi ºef_direct se poate crea o relaþie intrinsecã sau self Join.
Concluzionãm cã relaþiile dintre tabele pot fi de trei tipuri ºi anume: inner join, outer join ºi self join. Când vrem sã creem o interogare pe baza a mai multe tabele, din fereastra Data Base, vom selecta Queries/New/Design View/Ok. Apare caseta de dialog Show Table, alegem tipul de sursã de date pentru interogare (Tables, Queries sau Both)
ºi apoi selectãm tabelele sau interogãrile de care avem nevoie. Eliberând caseta Show Table, în partea de sus a grilei QBE, mai exact în panoul Relationship vom avea macheta fiecãrui tabel sau interogare apelatã. Dacã între aceste tabele sau interogãri nu au fost stabilite relaþii permanente încã de când s-a terminat descrierea tabelelor, sau nu ne convin unele din aceste relaþii, le putem ºterge pe acestea din urmã ºi putem crea alte relaþii dar temporare. Cu alte cuvinte nici ºtergerile de relaþii permanente ºi nici crearea de relaþii în panoul Relationship din grila QBE, nu afecteazã relaþiile permanente create între tabele cu opþiunea Relationship din meniul Tools. Acelaºi lucru este valabil ºi pentru cazul cã am ºters din panoul Relationship un tabel apãrut accidental acolo (un tabel de care nu aveam nevoie). O astfel de operaþiune se poate face dând clic dreapta pe tabelul respectiv ºi apoi selectând opþiunea Remove Table din meniul imediat care apare.
În aprecierea relaþiilor permanente vom þine seamã dacã ele impun restricþii de integritate referenþialã sau nu, ceea ce în caz afirmativ, se poate vedea prin îngroºarea capetelor liniilor de relaþie dintre tabele ºi prin marcarea lor cu 1 sau cu ¥
Pentru a schimba tipul de asociere selectaþi legãtura printr-un clic de mouse apoi executaþi dublu clic pe legãturã pentru a deschide caseta de dialog Join Properties.
Din aceastã casetã se poate alege unul din tipurile Inner Join, Left Outer Join sau Right Outer Join.
Dacã între douã tabele sau interogãri nu existã legãturi permanente ºi nu avem ce modifica, putem crea o relaþie temporarã procedând ca ºi în caseta Relationship folositã la declararea relaþiilor permanente, adicã trãgând câmpul cheie primarã spre câmpul cheie externã. Odatã rezolvatã problema unor legãturi adecvate între tabele sau interogãri, putem trece la redactarea interogãrii dupã toate regulile specifice prezentate la tipul de relaþie pe care dorim sã o creem. Reamarcãm cã odatã stabilite legãturile între tabele ºi aduse câmpurile în linia Field, ele pot fi folosite de programator (ºi vor fi tratate de Access) ca ºi cum ar aparþine aceluiaºi tabel!
Existã cazuri în care este necesarã o interogare pentru a genera o valoare ce va fi folositã de altã interogare. Aceste interogãri pot fi construite împreunã sau separat.
Când sunt construite separat, dupã ce s-a elaborat ºi testat prima interogare, o vom aduce în panoul Relationship deschis pentru a doua interogare, în linia Table vom introduce numele interogãrii, iar în linia Fields vom introduce nume de câmpuri din interogare. Tabelele de care are nevoie prima interogare nu trebuie sã fie aduse împreunã cu ea, în panoul Relationship al celei de a doua interogãri.
O altã modalitate de folosire a unei interogãri vechi în una nouã este de a introduce în expresii criteriale sau de altã naturã chiar textul SQL al vechii interogãri. Acest text se obþine având interogarea veche deschisã în mod Design ºi apoi alegând din meniul View, modul de vizualizare SQL. Textul poate fi copiat în clipboard ºi depus în grila QBE a noii interogãri. În acest caz nu este necesarã prezenþa tabelului produs de vechea interogare în panoul Relationship al grilei QBE a noii interogãri.
În exemplul de mai jos avem o interogare care listeazã produsele a cãror preþ este peste preþul mediu. Pentru a calcula preþul mediu se foloseºte o interogare al cãrei echivalent în SQL este folosit direct în linia Criteria pentru a genera limita pentru care un preþ poate fi selectat ca fiind peste preþul mediu. În acest caz, preþul mediu putea fi calculat ºi direct cu funcþia agregat Davg().
Parametri sunt folosiþi pentru a obþine seturi de criterii redactate ad-hoc de cel care a lansat interogarea. De exemplu, nu ºtim pentru ce þarã va dori utilizatorul sã obþinã lista cu comenzi pentru luna curentã. Totul a fost prevãzut în grila QBE, mai puþin criteriul privitor la þarã. Acolo, în loc sã se punã o valoare concretã ca în exemplele anterioare când am avut "Canada" or "UK", se va pune între paranteze drepte mesajul prin care cerem numele tãrii. De exemplu vom pune =[Numele tãrii] sau într-o altã situaþie în care se cere un interval de timp vom pune: Between [Data de inceput]and [Data de sfarsit] .
Când se ruleazã interogarea, se afiºeazã o casetã de
dialog ce afiºeazã textul pus între paranteze drepte ca o întrebare cãtre utilizator ºi o casetã de text, în
care utilizatorul poate completa rãspunsul sãu la întrebare, respectiv poate
completa criteriul care a cerut aceastã
informaþie. Dacã ni se pare greu de utilizat caseta de text din caseta Enter Parameter Value, o putem mãri cu Shift+F2, când va apare caseta Zoom. Remarcãm cã un text pus între paranteze drepte pentru a fi apoi afisat ca intrebare, este limitat la 40 de caractere. Aceastã limitare se poate ocoli cu un formular personalizat special destinat preluãrii parametrului respectiv.
Unele interogãri, cum ar fi cele de tip CrossTab, cele care folosesc câmpuri de tip Yes/No drept criterii, interogãrile care depind de criterii preluate din surse de date ODBC (Open DataBase - Conectivity), precum ºi cele care creazã diagrame, cer tipul de date al parametrilor. În acest caz, vom crea interogarea normal, dupã regulile de mai sus, dar în timp ce ne aflãm în modul Design, vom alege opþiunea Query de pe bara de meniuri, iar din submeniul afiºat, vom alege Parameters. Va rezulta o casetã Query Parameters cu coloanele Parameter ºi Data Type care ne permite sã specificãm tipul parametrului. Acolo la rubrica Parameter vom introduce numele câmpului pentru care se cere parametrul.
Proprietãþile interogãrilor pot fi precizate ºi modificate din submeniul View, opþiunea Properties . Pentru a configura proprietãþile unei interogãri va trebui sã selectãm interogarea dând clic pe fundalul panoului Relationship.
În fereatra cu proprietãþi carea apare, cele mai reprezentative sunt:
- Output All Fields (implicit No): Yes determinã returnarea tuturor câmpurilor din toate tabelele ºi interogãrile sursã ;
- Unique Value (implicit No): Yes determinã ca toate câmpurile din toate înregistrãrile returnate sã conþinã valori unice;
- Unique records (implicit No): se referã la înregistrãri identice. La Yes astfel de înregistrãri sunt permise la iesirea din interogare;
- Sourse Database/source Connect Str (baza de date sursã/parametrii de conectare la sursã ; implicit=Current); are sens când interogãm baze de date ce nu sunt legate la baza de date curentã din Access, ci la baze de date externe;
- Recordset Type (implicit Dynaset); are sens când folosim o interogare ca sursã de date pentru un formular ºi vrem sã împiedicãm utilizatorii formularului sã modifice datele prin formular;
- ODBC Timeout (timp de aºteptare pentru conectare la sursa ODBC; implicit 60 sec.);
- Filter. Filtrele sunt folosite pentru a limita numãrul de înregistrãri returnate de interogarea curentã, în funcþie de situaþie. Concret este vorba de condiþiile impuse pentru clauza Where.
- Order By; se enumerã aici numele câmpurilor (separate prin virgule), dupã care se vor ordona rezultatele interogãrii.
- Max Records (nr. max. de înreg.), reglementeazã numãrul maxim de înregistrãri care sã fie preluate de la interogare pentru a fi trimise surselor ODBC.
- Column Headings: utilã într-o interogare Crosstab, pentru a specifica coloanele din tabelul de date returnat de interogare, prin intermediul programelor, deci automat dupã nevoi;
- Destination Table/DB/Connect Str (tabel de dest./bazã de date/parametri de conectare): utilã în cazul interogãrilor Make-Table; când nu se gãseºte un tabel destinaþie în Baza de date. curentã, se foloseºte calea ºi opþiunile necesare pentru a-l crea într-o bazã de date externã;
- Use Tranzactions (implicit No): La opþiunea Yes nu scrie rezultatele pânã nu este completat tot tabelul de iesire; utilã atunci când acesta trebuie difuzat la mai mulþi utilizatori ºi dacã ar fi No, ar þine ocupate toate liniile pe tot timpul cât se fac calcule pentru elaborarea rezultatelor.
- Fail On Error (implicit No). La Yes anuleazã operaþia dacã întâlneºte o eroare. În cazul interogãrilor de actualizare ºi de ºtergere, ºi articolele procesate pânã la producerea erorii vor fi aduse la forma iniþialã, deci insuccesul sã fie total.
Notã: valorile întroduse pentru proprietãþi, se pierd la schimbarea tipului de interogare;
|