background image

Wydawnictwo Helion
ul. Koœciuszki 1c
44-100 Gliwice
tel. 032 230 98 63

e-mail: helion@helion.pl

Access. Analiza danych.
Receptury

Autor: Ken Bluttman, Wayne Freeze
T³umaczenie: Grzegorz Kowalczyk
ISBN: 978-83-246-1285-7
Tytu³ orygina³u: 

Access Data Analysis Cookbook

Format: B5, stron: 360

Korzystaj z bazy danych Access jak profesjonalista! 

• 

Jak stosowaæ wskaŸniki statystyczne do analizy danych biznesowych? 

• 

Jak rozszerzaæ funkcjonalnoœæ zapytañ SQL, stosuj¹c skrypty VBA? 

• 

Jak przetwarzaæ dane i przenosiæ je miêdzy bazami Access? 

Access to znane ju¿ narzêdzie s³u¿¹ce do wszechstronnego przetwarzania i analizy 
danych. Posiada sporo ukrytych mechanizmów, pozwalaj¹cych efektywnie wykonywaæ 
zadania, które pocz¹tkowo mog¹ wydawaæ siê skomplikowane. Ksi¹¿ka przedstawia 
przyk³ady kwerend, metody przenoszenia danych pomiêdzy bazami Access, obliczania 
wielu wskaŸników finansowo-biznesowych i sporo innych zagadnieñ – wszystko pod 
k¹tem analizy i przetwarzania danych. Ka¿da zaprezentowana receptura jest opatrzona 
kompletnym opisem rozwi¹zania problemu wraz ze szczegó³owym omówieniem metody 
postêpowania oraz analiz¹ kodu. 

Access. Analiza danych. Receptury to uniwersalny podrêcznik przeznaczony zarówno
dla pocz¹tkuj¹cych u¿ytkowników bazy danych Access, jak i doœwiadczonych.
Dziêki przejrzystemu jêzykowi i mnogoœci poruszonych zagadnieñ ka¿dy, niezale¿nie
od stopnia zaawansowania, mo¿e poszerzyæ swoj¹ wiedzê. Zawiera mnóstwo ciekawych 
wskazówek i technik u³atwiaj¹cych codzienn¹ pracê z bazami danych, co czyni j¹ 
atrakcyjn¹ nawet dla osób doskonale pos³uguj¹cych siê baz¹ Access. Jest to tak¿e 
kompendium wiedzy niezbêdnej ka¿demu, kto chce wyci¹gaæ ze zbiorów danych 
naprawdê cenne informacje. 

• 

Tworzenie kwerend ró¿nych typów 

• 

Wstawianie, aktualizacja i usuwanie danych 

• 

Przetwarzanie tekstu i liczb zapisanych w formie ³añcucha znaków 

• 

Zastosowanie tabel, modyfikacja zawartoœci systemu Windows, szyfrowanie danych 

• 

Wykorzystanie obiektu FileSystemObject, przetwarzanie danych XML oraz XSLT,

    komunikacja z bazami SQL 

• 

Rozwi¹zywanie problemów biznesowych 

• 

Obliczanie wskaŸników statystycznych 

Baza danych to fundament biznesu – zobacz, jak efektywnie ni¹ zarz¹dzaæ! 

background image

3

Spis tre

ļci

Przedmowa ...............................................................................................................................9

 1.  Tworzenie kwerend  .................................................................................................... 15

1.1. 

Wyszukiwanie niedopasowanych rekordów 

15

1.2. 

Zastosowanie operatorów AND i OR 

18

1.3. 

Kryteria wykorzystujñce operator IN 

21

1.4. 

Wyäñczanie rekordów z zapytania przy uĔyciu operatora NOT 

23

1.5. 

Parametryzacja zapytaþ 

25

1.6. 

Zwracanie n rekordów z górnej lub dolnej czöĈci zakresu wyszukiwania 

29

1.7. 

Zwracanie unikatowych rekordów 

32

1.8. 

Zwracanie losowo wybranych rekordów 

36

1.9. 

Dostrajanie wyszukiwania przy uĔyciu podzapytaþ 

38

1.10.  ãñczenie danych za pomocñ operacji UNION 

43

1.11.  Dynamiczne wstawianie pól w kwerendzie wybierajñcej 

46

1.12.  Zastosowanie aliasów do upraszczania wyraĔeþ SQL 

49

1.13.  Lewe sprzöĔenie zewnötrzne — tworzenie i zastosowanie 

50

1.14.  Prawe sprzöĔenie zewnötrzne — tworzenie i zastosowanie 

52

1.15.  Tworzenie peänego sprzöĔenia zewnötrznego 

54

 2.  Obliczenia w kwerendach ........................................................................................... 57

2.1. 

Obliczanie sum i wartoĈci Ĉrednich zbioru danych 

57

2.2. 

Obliczanie liczby elementów w danej grupie 

60

2.3. 

Zastosowanie wyraĔeþ w kwerendach 

62

2.4. 

Zastosowanie funkcji wäasnych w kwerendach 

64

2.5. 

Zastosowanie wyraĔeþ regularnych w kwerendach 

68

2.6. 

Iloczyn kartezjaþski, czyli jak otrzymaè wszystkie kombinacje danych 

71

2.7. 

Tworzenie i zastosowanie kwerend krzyĔowych 

75

background image

4

_

Spis tre

ļci

 3.  Kwerendy funkcjonalne  .............................................................................................. 81

3.1. 

Kwerendy aktualizujñce 

81

3.2. 

Doäñczanie danych 

86

3.3. 

Usuwanie danych 

91

3.4. 

Kwerendy tworzñce tabele 

95

 4.  Zarz

édzanie tabelami, polami, indeksami i kwerendami ..........................................99

4.1. 

Programowe tworzenie tabel 

99

4.2. 

Modyfikacja struktury tabeli 

106

4.3. 

Tworzenie i zastosowanie indeksów 

109

4.4. 

Programowe usuwanie tabel 

111

4.5. 

Programowe tworzenie kwerend 

112

 5.  Przetwarzanie ci

égów znaków  .................................................................................115

5.1. 

Wyodröbnianie wybranej liczby znaków z lewej lub prawej strony ciñgu
alfanumerycznego 

115

5.2. 

Wyodröbnianie znaków z äaþcucha znaków, kiedy znana jest pozycja
poczñtkowa i däugoĈè 

117

5.3. 

OkreĈlanie pozycji poczñtkowej znanego podciñgu znaków 

118

5.4. 

Obcinanie spacji z koþca äaþcucha znaków 

120

5.5. 

Usuwanie spacji z wnötrza äaþcucha znaków 

123

5.6. 

Zamiana jednego äaþcucha znaków na inny 

124

5.7. 

Konkatenacja äaþcuchów znaków 

126

5.8. 

Sortowanie liczb zapisanych w postaci tekstowej 

129

5.9. 

Kategoryzacja znaków na podstawie kodów ASCII 

132

 6.  Programowe przetwarzanie danych  ........................................................................ 135

6.1. 

Wykorzystywanie funkcji programu Excel z poziomu bazy Access 

135

6.2. 

Przetwarzanie danych przechowywanych w pamiöci 

140

6.3. 

Zastosowanie tablic wielowymiarowych 

143

6.4. 

Sortowanie tablic 

146

6.5. 

Späaszczanie struktury danych 

150

6.6. 

Rozszerzanie struktury danych 

154

6.7. 

Szyfrowanie danych 

156

6.8. 

Wyszukiwanie wartoĈci zbliĔonych do wzorca 

159

6.9. 

Przetwarzanie transakcyjne 

163

6.10.  Odczytywanie i zapisywanie danych z rejestrów systemu Windows 

165

6.11.  Przetwarzanie kodu HTML stron sieci WWW 

168

6.12.  Formatowanie raportów definiowanych przez uĔytkownika 

171

6.13.  Zaokrñglanie wartoĈci 

174

6.14.  Korespondencja seryjna 

177

6.15.  Tworzenie formularzy budowania kwerend 

180

background image

Spis tre

ļci

_

5

 7.  Import i eksport danych  ............................................................................................ 185

7.1. 

Tworzenie specyfikacji importu lub eksportu 

185

7.2. 

Automatyzacja operacji importu i eksportu danych 

191

7.3. 

Eksportowanie danych przy uĔyciu obiektu FileSystemObject 

194

7.4. 

Importowanie danych przy uĔyciu obiektu FileSystemObject 

196

7.5. 

Importowanie i eksportowanie plików przy uĔyciu XML 

201

7.6. 

Generowanie schematów XML 

204

7.7. 

Zastosowanie jözyka XSLT w operacjach importu i eksportu danych 

206

7.8. 

Wykorzystanie XML za poĈrednictwem parsera MSXML 

209

7.9. 

Odczytywanie i zapisywanie atrybutów XML 

213

7.10.  Tworzenie Ēródeä danych RSS 

215

7.11.  Przekazywanie parametrów do bazy danych SQL Server 

218

7.12.  Obsäuga wartoĈci zwracanych przez procedury osadzone bazy SQL Server  220
7.13.  Praca z typami danych bazy SQL Server 

221

7.14.  Obsäuga osadzonych znaków cudzysäowu 

223

7.15.  Importowanie kalendarza spotkaþ z programu Outlook 

224

7.16.  Importowanie wiadomoĈci poczty elektronicznej z programu Outlook 

227

7.17.  Importowanie listy kontaktów z programu Outlook 

229

7.18.  Importowanie danych z programu Excel 

232

7.19.  Eksportowanie danych do programu Excel 

235

7.20.  Wspóäpraca z programem PowerPoint 

237

7.21.  Wybieranie danych losowych 

240

 8.  Obliczanie daty i czasu  ..............................................................................................243

8.1. 

Obliczanie czasu 

243

8.2. 

Obliczanie czasu z uwzglödnieniem wyjñtków 

247

8.3. 

Przeliczanie stref czasowych 

249

8.4. 

Lata przestöpne w obliczeniach 

252

8.5. 

Rozkäadanie dat na elementy skäadowe 

253

8.6. 

Rozkäadanie czasu na elementy skäadowe 

256

8.7. 

Dodawanie wartoĈci reprezentujñcych czas 

257

 9.  Obliczenia biznesowo-finansowe ............................................................................ 261

9.1. 

Obliczanie Ĉredniej waĔonej 

261

9.2. 

Obliczanie Ĉredniej kroczñcej 

263

9.3. 

Obliczanie okresów zwrotu inwestycji 

264

9.4. 

Obliczanie stopy zwrotu inwestycji 

266

9.5. 

Obliczanie amortyzacji liniowej 

267

9.6. 

Tworzenie harmonogramu späaty kredytu 

270

9.7. 

Zastosowanie tabel przestawnych i wykresów przestawnych 

272

9.8. 

Tworzenie tabel przestawnych 

274

background image

6

_

Spis tre

ļci

9.9. 

Prezentacja danych na wykresach 

279

9.10.  Odszukiwanie trendów danych 

281

9.11.  Znajdowanie formacji „gäowa i ramiona” 

285

9.12.  Wyznaczanie wstög Bollingera 

295

9.13.  Obliczanie odlegäoĈci na podstawie kodów pocztowych 

298

 10.  Obliczenia statystyczne  ............................................................................................305

10.1.  Tworzenie histogramów 

305

10.2.  Obliczanie i porównywanie Ĉredniej, mediany oraz dominanty 

308

10.3.  Obliczanie wariancji zbioru danych 

311

10.4.  Obliczanie kowariancji dwóch zbiorów danych 

314

10.5.  Obliczanie korelacji dwóch zbiorów danych 

315

10.6.  Wyznaczanie wszystkich permutacji elementów zbioru danych 

316

10.7.  Wyznaczanie wszystkich moĔliwych kombinacji elementów zbioru danych  319
10.8.  Obliczanie czöstoĈci wystöpowania wartoĈci w zbiorze danych 

321

10.9.  Obliczanie rocznej stopy wzrostu 

322

10.10. Obliczanie funkcji rozkäadu prawdopodobieþstwa dla zbioru danych 

325

10.11. Obliczanie wartoĈci kurtozy 

327

10.12. Obliczanie wspóäczynnika asymetrii krzywej rozkäadu zbioru danych 

331

10.13. Procentowy podziaä zakresu wartoĈci zbioru danych 

333

10.14. OkreĈlanie rangi wartoĈci poszczególnych elementów danych 

335

10.15. Obliczanie wspóäczynników regresji liniowej 

336

10.16. Wyznaczanie zmiennoĈci danych 

338

Skorowidz .............................................................................................................................343

background image

81

ROZDZIA

Ĥ 3.

Kwerendy funkcjonalne

Kwerendy dzielimy na pasywne i funkcjonalne. Kwerendy pasywne, takie jak standardowe kwe-
rendy wybierajñce, zwracajñ zestawy rekordów speäniajñcych kryteria wyszukiwania, ale w Ĕaden
sposób nie modyfikujñ danych (kwerendy pasywne nie modyfikujñ danych w tabelach Ēródäo-
wych ani nie przechowujñ zwracanych rekordów däuĔej niĔ dana kwerenda jest aktywna).

Kwerendy aktywne mogñ modyfikowaè dane Ēródäowe, a zestawy rekordów zwracanych przez
takie kwerendy mogñ byè dostöpne w nieskoþczonoĈè. Na przykäad kwerenda usuwajñca, jak
sama nazwa wskazuje, usuwa rekordy z tabel Ēródäowych bazy danych — jest to procedura caä-
kowicie niszczñca dane. JeĔeli takie usuniöte informacje nie zostaäy wczeĈniej zapisane w kopii
bezpieczeþstwa, to ich odzyskanie nie bödzie moĔliwe. Kwerendy aktualizujñce równieĔ mogñ
modyfikowaè dane Ēródäowe, zmieniajñc informacje przechowywane w poszczególnych rekor-
dach — podobnie jak w przypadku kwerend usuwajñcych, jeĔeli aktualizowane rekordy nie
zostaäy wczeĈniej zapisane w kopii bezpieczeþstwa, to po ich aktualizacji przywrócenie poprzed-
nich wartoĈci nie bödzie moĔliwe.

Kwerendy doäñczajñce oraz kwerendy tworzñce tabele naleĔñ do grupy kwerend funkcjonal-
nych, które nie modyfikujñ danych Ēródäowych, ale za to powodujñ, Ĕe zwracane rekordy sñ
przechowywane däuĔej, niĔ wynosi czas aktywnoĈci kwerendy. Kwerendy doäñczajñce dodajñ
zwracane rekordy do istniejñcych tabel, a kwerendy tworzñce tabele umieszczajñ zwracane
rekordy w nowych tabelach. W tym rozdziale bödziemy szczegóäowo omawiali wszystkie cztery
rodzaje kwerend funkcjonalnych.

3.1. Kwerendy aktualizuj

éce

Opis problemu

Mamy danñ tabelö, której rekordy wymagajñ modyfikacji. Pole Nazwa stanu przechowuje dwu-
literowe skróty nazw stanów. Naszym zadaniem jest zamiana tych skrótów na peäne nazwy
stanów. Jak tego dokonaè?

background image

82

_

Rozdzia

ĥ 3. Kwerendy funkcjonalne

Rozwi

ézanie

Rozwiñzaniem problemu bödzie zastosowanie kwerendy aktualizujñcej, którñ moĔemy w prosty
sposób utworzyè z poziomu widoku projektu kwerendy. Aby tego dokonaè, naleĔy po przeäñ-
czeniu do widoku projektu kwerendy wybraè z menu gäównego polecenie Kwerenda/Kwerenda
aktualizujñca
, co spowoduje odpowiednie przygotowanie siatki projektu kwerendy.

W wersji Access 2007 naleĔy najpierw przy uĔyciu WstñĔki utworzyè pusty projekt kwerendy,
a nastöpnie na karcie Projektowanie w grupie Typ kwerendy kliknñè polecenie Aktualizuj.

Po utworzeniu kwerendy aktualizujñcej w siatce projektu kwerendy pojawi siö dodatkowy wiersz
o nazwie Aktualizacja do, natomiast zniknñ wiersze Sortuj i PokaĔ znane z kwerend wybierajñcych.

Na rysunku 3.1 przedstawiono projekt kwerendy aktualizujñcej, której zadaniem jest zastñpienie
w polu Nazwa stanu wszystkich wystñpieþ akronimu 

NY

 na peänñ nazwö 

New York

.

Rysunek 3.1. Prosta kwerenda aktualizujñca

Zwróèmy uwagö, Ĕe w wierszu Kryteria znajduje siö wartoĈè 

NY

 — jest to wartoĈè, która bödzie

poszukiwana i zamieniana na nowñ. WartoĈè wpisana w wierszu Aktualizacja do — 

New York

 —

to nowa wartoĈè, która zastñpi wartoĈè poszukiwanñ. Odpowiednie uĔycie kryteriów ma tutaj
ogromne znaczenie, bo przecieĔ chcemy zmodyfikowaè tylko rekordy, które w polu Nazwa stanu
majñ wartoĈè 

NY

.

Kwerenda aktualizujñca nie musi posiadaè klauzuli 

Where

 (która odpowiednio filtruje rekordy

i pozwala na aktualizacjö tylko tych, które sñ zgodne z podanym wzorcem wyszukiwania) —
kwerenda aktualizujñca moĔe aktualizowaè wszystkie rekordy w bazie. W pewnych sytuacjach
taki zakres dziaäania kwerendy moĔe byè bardzo poĔñdany, ale w naszym przykäadzie aktuali-
zacja wszystkich rekordów w tabeli klientów byäaby prawdziwñ katastrofñ (jak pamiötamy, jeĔeli
nie mamy kopii zapasowej tabeli, to nie moĔemy anulowaè zmian wprowadzonych przez kwe-
rendö aktualizujñcñ i przywróciè poprzedniej zawartoĈci tabeli).

Po uruchomieniu kwerendy na ekranie pojawi siö okno dialogowe z proĈbñ o potwierdzenie
zamiaru wykonania takiej operacji, przedstawione na rysunku 3.2. Aby kontynuowaè, naleĔy
nacisnñè przycisk Tak.

background image

3.1. Kwerendy aktualizuj

éce

_

83

Rysunek 3.2. Okno dialogowe z proĈbñ o potwierdzenie zamiaru wykonania aktualizacji

Przedstawiona powyĔej kwerenda aktualizuje nazwö tylko jednego stanu. Jest to rozwiñzanie do
przyjöcia, aczkolwiek uruchamianie podobnej kwerendy aktualizujñcej 50 razy (po jednej kwe-
rendzie aktualizujñcej dla kaĔdego stanu) moĔe byè dosyè czasochäonne i nuĔñce. Na szczöĈcie
istniejñ równieĔ bardziej efektywne metody.

Jednym  z  moĔliwych  rozwiñzaþ  jest  wywoäanie  z  poziomu  kwerendy  wäasnej  funkcji  prze-
twarzajñcej dane. W naszym przypadku taka funkcja powinna pobieraè akronim nazwy sta-
nu i zwracaè jego peänñ nazwö. PoniĔej przedstawiamy przykäadowy kod takiej funkcji:

Function new_state_name(current_state_name As String) As String
 new_state_name = current_state_name
   If current_state_name = "NY" Then new_state_name = "New York"
   If current_state_name = "CT" Then new_state_name = "Connecticut"
   If current_state_name = "MA" Then new_state_name = "Massachusetts"
   If current_state_name = "CA" Then new_state_name = "California"
End Function

Jak widaè, dla uproszczenia w kodzie naszej przykäadowej funkcji zakodowaliĈmy zaledwie
kilka akronimów nazw stanów, ale oczywiĈcie nic nie stoi na przeszkodzie, aby umieĈciè tam
wszystkie 50 nazw stanów (bñdĒ równie dobrze tylko niektóre, wybrane nazwy stanów). Kodo-
wanie wszystkich 50 stanów moĔe byè nieco Ĕmudnym zajöciem, ale przynajmniej w efekcie
otrzymamy dosyè uniwersalnñ, w peäni uĔytecznñ funkcjö.

Pierwszy wiersz kodu funkcji ustawia wynik dziaäania funkcji na wartoĈè bödñcñ argumentem
funkcji (bieĔñcy akronim nazwy stanu), dziöki czemu jeĔeli peäna nazwa stanu nie zostanie odna-
leziona, funkcja zwróci akronim nazwy stanu i w zasadzie w takim rekordzie nic siö nie zmieni.
JeĔeli jednak akronim bödñcy argumentem funkcji pasuje do któregoĈ z poleceþ 

If

, funkcja jako

wynik swojego dziaäania zwraca peänñ nazwö stanu.

Na rysunku 3.3 przedstawiono wyglñd siatki projektu takiej kwerendy aktualizujñcej. Zwróèmy
uwagö na fakt, Ĕe tym razem nie mamy ustawionych Ĕadnych kryteriów. Brak kryteriów wyszu-
kiwania wynika z prostego faktu, Ĕe chcemy przetwarzaè wszystkie rekordy tabeli. Sama funkcja
wywoäywana jest w wierszu Aktualizacja do, a jako argumentu wywoäania funkcji uĔywamy
wartoĈci pola Nazwa stanu.

Wyniki dziaäania kwerendy przedstawiono na rysunku 3.4. Jak widaè, dla tych stanów, które
zostaäy w funkcji odpowiednio zakodowane przy uĔyciu poleceþ 

If

, akronimy zostaäy zastñpione

peänymi nazwami stanów; dla wszystkich pozostaäych stanów oryginalne akronimy nie zostaäy
zaktualizowane.

Jeszcze innym sposobem dokonania konwersji akronimów na peäne nazwy stanów jest zastoso-
wanie wbudowanej funkcji 

Dlookup

. W naszym przykäadzie uĔyjemy tabeli Stany, przechowu-

jñcej nazwy stanów. Tabela posiada dwa pola: Akronim oraz Peäna nazwa stanu. Wyglñd tej tabeli
zostaä przedstawiony na rysunku 3.5.

background image

84

_

Rozdzia

ĥ 3. Kwerendy funkcjonalne

Rysunek 3.3. Zastosowanie wäasnej funkcji w kwerendzie aktualizujñcej

Rysunek 3.4. Wyniki dziaäania kwerendy aktualizujñcej

Rysunek 3.5. Tabela przechowujñca peäne nazwy stanów i ich akronimy

background image

3.1. Kwerendy aktualizuj

éce

_

85

Wyglñd siatki projektu kwerendy zostaä przedstawiony na rysunku 3.6.

Rysunek 3.6. Kwerenda aktualizujñca z funkcjñ DlookUp

Wywoäanie funkcji 

DlookUp

 nastöpuje w wierszu Aktualizacja do i wyglñda nastöpujñco:

DLookUp("[Pe

Īna nazwa stanu]";"Stany";"[Akronim]='" & [Nazwa stanu] & "'")

Peäna nazwa stanu oraz Akronim to nazwy dwóch pól tabeli Stany, a Nazwa stanu to pole w tabeli
Klienci. W tabeli Stany kaĔdy stan posiada swój rekord przechowujñcy peänñ nazwö stanu oraz
jej akronim. Dziöki takiemu rozwiñzaniu po uruchomieniu nasza kwerenda dokona zamiany
akronimów na peäne nazwy dla wszystkich 50 stanów (pod warunkiem oczywiĈcie, Ĕe w tabeli
Stany nie ma Ĕadnych bäödów).

Omówienie

Wszystkie kwerendy aktualizujñce, o których mówiliĈmy do tej pory, pracowaäy tylko na jednym
polu tabeli. Kod SQL kwerendy przedstawionej na rysunku 3.1 jest krótki i wyglñda nastöpujñco:

UPDATE Klienci SET Klienci.[Nazwa stanu] = "New York"
WHERE (((Klienci.[Nazwa stanu])="NY"));

Kod SQL kwerendy aktualizujñcej zawsze rozpoczyna siö od säowa kluczowego 

UPDATE

, po

którym nastöpuje nazwa tabeli i klauzula 

SET

 wskazujñca pole, które bödzie aktualizowane

(jednoczeĈnie moĔemy aktualizowaè wiöcej niĔ jedno pole, o czym bödziemy mówiè juĔ za
chwilö). Dowolne kryteria wyszukiwania uĔywane do ograniczenia liczby aktualizowanych
rekordów sñ definiowane w klauzuli 

WHERE

.

Kryteria wyszukiwania nie muszñ bazowaè na polu, które jest aktualizowane. W poprzednim
przykäadzie kryteria wyszukiwania operowaäy co prawda na aktualizowanym polu, ale porów-
najmy kod poprzedniej kwerendy z nastöpujñcym zapytaniem SQL:

UPDATE Klienci SET Klienci.[Nazwa stanu] = "New York"
WHERE (((Klienci.Miasto)="New York City"));

W tym przykäadzie pole Nazwa stanu jest aktualizowane tylko dla tych rekordów, w których pole
Miasto ma wartoĈè 

New York City

.

background image

86

_

Rozdzia

ĥ 3. Kwerendy funkcjonalne

Jedna kwerenda moĔe aktualizowaè dowolnñ iloĈè pól, aczkolwiek naleĔy pamiötaè o tym, Ĕe
dla wszystkich pól obowiñzujñ te same kryteria wyszukiwania zdefiniowane w kwerendzie. Na
rysunku 3.7 przedstawiono projekt kwerendy, która dla wszystkich klientów majñcych status

Nieaktywny

 ustawia wartoĈè trzech pól na 

Pusty

.

Rysunek 3.7. Kwerenda aktualizujñca kilka pól jednoczeĈnie

Kod SQL kwerendy przedstawionej powyĔej wyglñda nastöpujñco:

UPDATE Klienci_Status SET
Klienci_Status.[Nazwa klienta] = "Pusty",
Klienci_Status.Miasto = "Pusty",
Klienci_Status.[Nazwa stanu] = "Pusty"
WHERE (((Klienci_Status.Status)="Nieaktywny"));

Zgodnie z wymogami skäadni jözyka SQL kwerenda rozpoczyna siö od säowa kluczowego

UPDATE

, po którym nastöpuje nazwa tabeli i klauzula 

SET

. Nastöpnie wymieniane sñ wszystkie

pola, którym przypisywane sñ nowe wartoĈci. Kod kwerendy koþczy klauzula 

WHERE

 definiu-

jñca kryteria wyszukiwania (o ile oczywiĈcie takie kryteria zostaäy zdefiniowane).

3.2. Do

ĥéczanie danych

Opis problemu

Chcemy, aby rekordy zwracane przez danñ kwerendö byäy doäñczane do innej tabeli. Jak moĔna
tego dokonaè?

Rozwi

ézanie

Bardzo czösto spotykamy siö z koniecznoĈciñ archiwizacji starszych danych, zakoþczonych trans-
akcji i innych tego typu informacji. Zazwyczaj takie operacje sñ realizowane poprzez przenie-
sienie odpowiednich rekordów do innych tabel przechowujñcych zarchiwizowane czy teĔ histo-
ryczne dane. Takie tabele majñ zazwyczaj identycznñ strukturö jak tablice Ēródäowe, dziöki czemu
przenoszenie rekordów pomiödzy nimi jest bardzo proste i wygodne. Warto jednak pamiötaè
o tym, Ĕe nie jest to Ĕaden twardy wymóg — tabele przechowujñce dane archiwalne mogñ mieè

background image

3.2. Do

ĥéczanie danych

_

87

dodatkowe pola, w których umieszczane sñ takie informacje jak data przeniesienia rekordu do
archiwum, kto zatwierdziä archiwizacjö danego rekordu i tak dalej.

Prawdziwym woäem roboczym takich rozwiñzaþ jest jedna z kwerend funkcjonalnych — kwe-
renda doäñczajñca (ang. append query). Jak sama nazwa wskazuje, kwerenda doäñczajñca dodaje
rekordy do istniejñcej tabeli. Bardzo czösto doäñczane rekordy sñ pobierane z innej tabeli, ale
równie dobrze doäñczane rekordy mogñ byè generowane przez jakiĈ proces, wartoĈci poszcze-
gólnych pól mogñ byè wyliczane bñdĒ nawet mogñ byè pobierane z tej samej tabeli.

Doäñczajñc do tabeli rekordy pobierane z tej samej tabeli, naleĔy uwaĔaè, aby nie doszäo
do dublowania wartoĈci unikalnego klucza tabeli.

Na rysunku 3.8 przedstawiono tabelö Transakcje przechowujñcñ informacje o transakcjach doko-
nywanych przez poszczególnych klientów. Rekordy opisujñ transakcje przeprowadzane w róĔ-
nych dniach, opiewajñce na róĔne kwoty i posiadajñce róĔne statusy.

Rysunek 3.8. Tabela przechowujñca informacje o transakcjach

Jednym z zadaþ, które sñ czösto wykonywane w takich sytuacjach, jest wyczyszczenie tabeli ze
starych rekordów opisujñcych zakoþczone transakcje. ZaäóĔmy, Ĕe mamy do dyspozycji drugñ
tabelö, ArchiwumTransakcji, która przechowuje takie rekordy. W prosty sposób moĔemy teraz
utworzyè projekt kwerendy, która odfiltruje zakoþczone transakcje i umoĔliwi przeniesienie ich
do archiwum. Na rysunku 3.9 przedstawiono wyglñd projektu kwerendy doäñczajñcej, wyszu-
kujñcej  rekordy  majñce  datö  transakcji  wczeĈniejszñ  niĔ 

2006-04-01

  i  status 

Zrealizowana

.

Uruchomienie tej kwerendy spowoduje umieszczenie takich rekordów w tabeli ArchiwumTrans-
akcji
 (na rysunku 3.9 nie widaè tego wprost, ale tabela ArchiwumTransakcji zostaäa wybrana z listy
Nazwa tabeli podczas tworzenia kwerendy doäñczajñcej w oknie dialogowym Doäñczanie).

background image

88

_

Rozdzia

ĥ 3. Kwerendy funkcjonalne

Rysunek 3.9. Projekt kwerendy doäñczajñcej

JeĔeli struktura tabeli ArchiwumTransakcji jest identyczna jak tabeli Transakcje, to w wierszu Do-
äñczanie do
 nazwy odpowiednich pól pojawiñ siö automatycznie. JeĔeli doäñczamy rekordy do
tabeli o innej strukturze, to musimy röcznie wybraè odpowiednie pola Ēródäowe i dopasowaè
do nich pola docelowe.

Kod SQL kwerendy doäñczajñcej przedstawionej na rysunku 3.9 wyglñda nastöpujñco:

INSERT INTO ArchiwumTransakcji
( [ID klienta], [Data transakcji], [Kwota transakcji], Status )
SELECT Transakcje.[ID klienta],
Transakcje.[Data transakcji],
Transakcje.[Kwota transakcji],
Transakcje.Status
FROM Transakcje
WHERE (((Transakcje.[Data transakcji])<#2006-04-01#)
AND ((Transakcje.Status)="Zrealizowana"));

Kod SQL kwerendy doäñczajñcej rozpoczyna siö od säów kluczowych 

INSERT INTO

, po których

nastöpuje nazwa tabeli docelowej oraz umieszczona w nawiasach lista pól tabeli docelowej. Na-
stöpnie w skäadni kwerendy pojawia siö wyraĔenie 

SELECT

, które pobiera odpowiednie rekordy

z tabeli Ēródäowej (w naszym przypadku jest to tabela Transakcje), zgodnie ze zdefiniowanymi
kryteriami wyszukiwania. Warto zwróciè uwagö na fakt, Ĕe iloĈè pól wybranych z tabeli Ēró-
däowej musi odpowiadaè iloĈè pól w tabeli docelowej. Kwerenda doäñczajñca nie musi opero-
waè na wszystkich polach tabeli Ēródäowej.

Po uruchomieniu naszej kwerendy rekordy sñ dodawane do tabeli ArchiwumTransakcji. Ale to
dopiero poäowa caäej historii — wybrane rekordy zostaäy skopiowane do tabeli archiwalnej, ale
ich oryginaäy nadal istniejñ w tabeli Ēródäowej. Aby je usunñè, musimy uĔyè odpowiedniej kwe-
rendy usuwajñcej. Kwerendy usuwajñce zostanñ szczegóäowo omówione w podrozdziale 3.3.

Omówienie

PowyĔszy  przykäad  dobrze  ilustruje  typowy  sposób  dziaäania  kwerend  doäñczajñcych:  pod-
kwerenda wybiera z tabeli Ēródäowej odpowiednie rekordy, wyszukiwane w zaleĔnoĈci od zde-
finiowanych (bñdĒ nie) kryteriów wyszukiwania i nastöpnie wyszukane rekordy sñ doäñczane do
tabeli docelowej.

background image

3.2. Do

ĥéczanie danych

_

89

Teraz przyjrzymy siö innej metodzie wstawiania rekordów do tabeli, w której zamiast pól
z tabeli Ēródäowej do pól tabeli docelowej bödziemy bezpoĈrednio wstawiali odpowiednie
wartoĈci. W przedstawionym poniĔej kodzie SQL kwerendy doäñczajñcej rolö tabeli docelowej
nadal speänia tabela ArchiwumTransakcji, ale tym razem do tabeli docelowej wstawiamy zako-
dowane „na sztywno” wartoĈci zdefiniowane w klauzuli 

VALUES

. Warto zauwaĔyè, Ĕe wstawiane

wartoĈci muszñ byè umieszczone w nawiasach.

INSERT INTO ArchiwumTransakcji
VALUES (2000, #2006-04-10#, 35.25, "Zrealizowana");

Tworzñc takie kwerendy doäñczajñce, musimy pamiötaè o nastöpujñcych kluczowych elementach:

INSERT INTO <nazwa tabeli>

 to prawidäowy sposób rozpoczynania wyraĔenia SQL.

Za pomocñ klauzuli 

VALUES

 moĔna „na sztywno” zakodowaè wartoĈci wstawiane do tabeli.

Poszczególne wartoĈci muszñ byè odpowiednio dopasowane do typu poszczególnych pól
w tabeli, do których sñ wstawiane. WartoĈci numeryczne nie potrzebujñ Ĕadnych kwalifi-
katorów i mogñ byè wstawiane bezpoĈrednio w kodzie SQL kwerendy jako liczby caäkowite,
rzeczywiste itd. (na przykäad 

2000

 czy 

35.25

). Daty muszñ byè ujöte w znaki krzyĔyka 

#

(ang. hash), a tekst (ciñgi alfanumeryczne) musi byè ujöty w znaki apostrofu lub cudzysäowu
(oba warianty sñ dopuszczalne).

Cztery wartoĈci uĔyte w kodzie SQL poprzedniego przykäadu odpowiadajñ pod wzglödem typu
i kolejnoĈci czterem polom w tabeli docelowej, stñd nie istnieje tutaj koniecznoĈè definiowania
listy pól. Warto jednak powiedzieè, Ĕe zdefiniowanie w takim przypadku listy pól nie jest Ĕad-
nym bäödem, a co wiöcej, moĔe byè nawet rozwiñzaniem preferowanym ze wzglödu na wiökszñ
przejrzystoĈè kodu. W takim przypadku kod SQL kwerendy doäñczajñcej wyglñdaäby nastöpujñco:

INSERT INTO ArchiwumTransakcji
([ID klienta], [Data transakcji], [Kwota transakcji], Status)
VALUES (2000, #2006-04-10#, 35.25, "Zrealizowana");

Wyniki dziaäania obu przedstawionych kwerend sñ identyczne.

Zdefiniowanie nazw pól tabeli docelowej jest wymagane w sytuacji, kiedy wstawiane wartoĈci
nie sñ uäoĔone w odpowiednim porzñdku bñdĒ jeĔeli niektóre pola tabeli zostajñ pominiöte.
Przykäadowo: moĔemy wstawiè do tabeli nowy rekord, w którym ustawimy tylko wartoĈci pól
ID klienta oraz Kwota transakcji; wartoĈci innych pól mogñ nie byè jeszcze znane i dlatego zostaäy
pominiöte. Kod SQL kwerendy doäñczajñcej moĔe wyglñdaè w takiej sytuacji nastöpujñco:

INSERT INTO ArchiwumTransakcji ([ID klienta], [Kwota transakcji])
VALUES (2000, 35.25);

W tym przypadku ustawiamy jedynie wartoĈci dwóch pól. Taki sposób postöpowania jest naj-
zupeäniej prawidäowy, a wykonanie kwerendy zakoþczy siö powodzeniem, pod warunkiem Ĕe
pola, których wartoĈci nie ustawiamy, mogñ przyjmowaè wartoĈci puste.

Do

ĥéczanie rekordów ze zbioru rekordów

Polecenie 

INSERT  INTO

 jest  czösto  wykorzystywane w  procedurach  przetwarzajñcych  dane

VBA/ADO, gdzie tabela docelowa jest wypeäniana w miarö przechodzenia pötli przez kolejne
rekordy zbioru rekordów (ang. recordset), przykäadowo:

Sub append_routine()
  Dim conn As ADODB.Connection
  Set conn = CurrentProject.Connection
  Dim rs_transactions As New ADODB.Recordset

background image

90

_

Rozdzia

ĥ 3. Kwerendy funkcjonalne

  Dim ssql As String
  ' Pobieramy wszystkie rekordy z tabeli Transakcje
  ssql = "Select * From Transakcje"
  rs_transactions.Open ssql, conn, adOpenKeyset, adLockOptimistic
  Do Until rs_transactions.EOF
    ' Je

Īeli data transakcji to 1 kwietnia,

    ' wstawiamy rekord do archiwum i ustawiamy kwot

Ċ transakcji na 0

    If rs_transactions.Fields("Data transakcji") = #2006-04-01# Then
      ssql = "Insert Into ArchiwumTransakcji Values ("
      ssql = ssql & rs_transactions.Fields("ID klienta") & ", "
      ssql = ssql & "#" & rs_transactions.Fields("Data transakcji") & "#, "
      ssql = ssql & 0 & ", "
      ssql = ssql & "'April''s Fools Day — wszystko za darmo!')"
      conn.Execute ssql
    End If
  rs_transactions.MoveNext
  Loop
  ' usuwamy wszystkie rekordy z 2006-04-01 z tabeli Transakcje
  ssql = "Delete * From Transakcje Where "
  ssql = ssql & " Transakcje.[Data transakcji]=#2006-04-01#"
  conn.Execute ssql
  rs_transactions.Close
  Set rs_transactions = Nothing
  conn.Close
  MsgBox "Gotowe!"
End Sub

W tym przykäadzie zbiór rekordów (

rs_transactions

) zawiera wszystkie rekordy z tabeli Trans-

akcje. Podczas przetwarzania w pötli kolejnych rekordów ze zbioru procedura sprawdza, czy data
transakcji to 

2006-04-01

. JeĔeli tak, tworzone jest odpowiednie polecenie 

INSERT INTO

 jözyka

SQL. Przykäadowo:

INSERT INTO ArchiwumTransakcji Values
VALUES (106, #2006-04-01#, 0, 'April''s Fools Day — wszystko za darmo!');

UwaĔni Czytelnicy z pewnoĈciñ zwrócili uwagö na uĔycie podwójnego znaku apo-
strofu  w  ciñgu  znaków 

April''s

.  Taki  zapis  zapobiega  wystñpieniu  bäödu,  który

mógäby  siö  w  przeciwnym  razie  pojawiè  podczas  próby  wstawienia  ciñgu  znaków
zawierajñcego apostrof.

Procedura przedstawiona powyĔej kopiuje wszystkie rekordy z 1 kwietnia 2006 do tabeli archi-
walnej i jako kwotö transakcji ustawia wartoĈè 

0

. Po przejĈciu pötli przez wszystkie rekordy

zbioru wykonywana jest kwerenda usuwajñca wszystkie rekordy z 1 kwietnia 2006 z tabeli
Transakcje. PoniĔej przedstawiamy fragment kodu odpowiedzialny za usuwanie rekordów:

usuwamy wszystkie rekordy z 2006-04-01 z tabeli Transakcje
ssql = "Delete * From Transakcje Where "
ssql = ssql & " Transakcje.[Data transakcji]=#2006-04-01#"
conn.Execute ssql

UĔycie odpowiedniej procedury VBA do przechodzenia przez kolejne rekordy i podejmowanie
odpowiednich decyzji o doäñczaniu poszczególnych rekordów do innej tabeli jest Ĉwietnym
rozwiñzaniem zwäaszcza w sytuacji, kiedy warunki okreĈlajñce sposób przetwarzania stajñ siö
zäoĔone. Bo jak inaczej znaleĒè na przykäad rekordy, w których musimy zredukowaè kwotö
transakcji do 

0

, jeĔeli moĔemy to zrobiè tylko dla ĈciĈle wybranych klientów, dla transakcji

wykonanych tylko w kilku okreĈlonych dniach i tylko wtedy, gdy caäkowite saldo transakcji
takiego  klienta  jest  mniejsze  niĔ 

100

,  a  ostatnie  zlecenie  zostaäo  zäoĔone  nie  wczeĈniej  niĔ

30 dni temu?

background image

3.3. Usuwanie danych

_

91

Zdefiniowanie takich warunków w siatce projektu kwerendy moĔe byè niezäym wyzwaniem,
stñd znajomoĈè sposobu poäñczenia w procedurze VBA poleceþ jözyka SQL z instrukcjami warun-
kowymi moĔe byè bezcennñ pozycjñ w zestawie umiejötnoĈci kaĔdego uĔytkownika bazy danych
Microsoft Access.

3.3. Usuwanie danych

Opis problemu

Musimy usunñè z tabeli okreĈlone dane. Rekordy, które majñ byè usuniöte, muszñ speäniaè okre-
Ĉlone kryteria wyszukiwania, a pozostaäe rekordy muszñ pozostaè nienaruszone. W jaki sposób
moĔna bezpiecznie wykonaè takñ operacjö?

Rozwi

ézanie

Aby usunñè z tabeli rekordy speäniajñce okreĈlone kryteria wyszukiwania, naleĔy uĔyè kwerendy
usuwajñcej
 (ang. delete query). JeĔeli w takiej kwerendzie nie zastosujemy Ĕadnych kryteriów
wyszukiwania,  to  uĔywajñc  jej,  musimy  zachowaè  daleko  idñcñ  ostroĔnoĈè  —  kwerenda
usuwajñca uruchomiona bez kryteriów wyszukiwania moĔe caäkowicie wyczyĈciè zawartoĈè
tabeli.

Kwerendy  usuwajñce  powodujñ  usuniöcie  danych,  ale  pozostawiajñ  tabele.  Tabele
nie sñ usuwane.

Aby usunñè wybrane dane z tabeli, musimy utworzyè odpowiedniñ kwerendö usuwajñcñ, która
wybierze tylko rekordy przeznaczone do skasowania. Na rysunku 3.10 przedstawiono projekt
kwerendy, która usuwa rekordy klientów pochodzñcych ze stanu CA (California). Oznacza to,
Ĕe usuniöte zostanñ tylko takie rekordy, dla których pole Nazwa stanu ma wartoĈè 

CA

; inne

rekordy tabeli pozostanñ nienaruszone. Zawsze musimy pamiötaè, Ĕe mimo iĔ w siatce projektu
kwerendy na rysunku 3.10 umieszczone zostaäo tylko jedno pole, uruchomienie kwerendy nie
usuwa danych tylko z tego pola — zamiast tego w caäoĈci zostajñ usuniöte wszystkie rekordy
speäniajñce podane kryterium wyszukiwania. W siatce projektu kwerendy nie musimy umiesz-
czaè wszystkich pól rekordu; wystarczy umieĈciè tam pola, dla których definiujemy kryteria
wyszukiwania. Kiedy uĔywamy kwerendy usuwajñcej wszystkie rekordy z tabeli (czyli kwe-
rendy bez kryteriów wyszukiwania), wystarczy z okna tabeli przeciñgnñè gwiazdkö na siatkö
projektu kwerendy — gwiazdka oznacza po prostu wszystkie pola tabeli.

Aby utworzyè kwerendö usuwajñcñ, naleĔy po przejĈciu na siatkö projektu kwerendy wybraè
z menu gäównego polecenie Kwerendy/Kwerenda usuwajñca. W wersji Access 2007 wystarczy
w  tym  celu  skorzystaè  z  odpowiedniego  przycisku  na  WstñĔce.  Kod  SQL  kwerendy  przedsta-
wionej na rysunku 3.10 wyglñda nastöpujñco:

DELETE [Klienci].[Nazwa stanu]
FROM Klienci
WHERE ((([Klienci].[Nazwa stanu])="CA"));

background image

92

_

Rozdzia

ĥ 3. Kwerendy funkcjonalne

Rysunek 3.10. Kwerenda usuwajñca ze zdefiniowanymi kryteriami wyszukiwania

Jak widaè, kod SQL kwerendy jest relatywnie prosty. Jego skäadnia jest nieco zbliĔona do skäadni
kwerendy wybierajñcej 

SELECT

, z wyjñtkiem tego, Ĕe kod kwerendy usuwajñcej rozpoczyna siö

od säowa kluczowego 

DELETE

. Interesujñcy jest fakt, Ĕe „przesäanie” czy teĔ „wiadomoĈè” wyni-

kajñce ze skäadni powyĔszego kodu SQL mogñ byè nieco mylñce. Jak juĔ wspominaliĈmy wcze-
Ĉniej, wykonanie takiej kwerendy usuwa caäe rekordy, a nie tylko wartoĈci pola Nazwa stanu.
Zdecydowanie lepszym „skäadniowo” zapisem takiej kwerendy bödzie nastöpujñcy kod SQL:

DELETE [Klienci].*
FROM Klienci
WHERE ((([Klienci].[Nazwa stanu])="CA"));

RóĔnica polega na tym, Ĕe zamiast nazwy pojedynczego pola uĔyliĈmy gwiazdki, która symbo-
lizuje wszystkie pola tabeli. Jak widaè, czasami sposób, w jaki Access tworzy kod SQL kwerend,
nie jest najlepszñ reprezentacjñ zamierzonej akcji. OczywiĈcie kod generowany przez Accessa jest
poprawny i dziaäa, ale moĔe byè nieco mylñcy.

Omówienie

Kiedy usuwamy rekordy z tabeli, która jest powiñzana relacjami z innymi tabelami, musimy
wziñè pod uwagö kilka dodatkowych elementów. PoniewaĔ tabela nadrzödna jest poäñczona
z tabelñ podrzödnñ relacjñ jeden do wielu, usuniöcie rekordów z tabeli nadrzödnej spowodo-
waäoby naruszenie wiözów integralnoĈci i pozostawienie „osieroconych” rekordów w tabeli
podrzödnej.

Access posiada mechanizm pozwalajñcy na sprawne rozwiñzanie takiego dylematu, co nie zmie-
nia faktu, Ĕe zrozumienie istoty problemu jest niezmiernie waĔne. Aby zilustrowaè caäe zagad-
nienie, posäuĔymy siö przykäadem. Na rysunku 3.11 przedstawiono relacjö ustanowionñ pomiö-
dzy tabelami Klienci i Transakcje. Zwróèmy uwagö, Ĕe w oknie dialogowym Edytowanie relacji
zaznaczona  zostaäa  opcja  Wymuszaj  wiözy  integralnoĈci  (aby  wyĈwietliè  to  okno  dialogowe,
naleĔy dwukrotnie kliknñè lewym przyciskiem myszy liniö äñczñcñ obie tabele bñdĒ z menu
gäównego wybraè polecenie Relacje/Edytuj relacjö). Taka  relacja  oznacza,  Ĕe  rekordy  w  tabeli
Transakcje muszñ byè dopasowane do odpowiednich rekordów z tabeli Klienci, a dokäadniej,
Ĕe kaĔdy rekord w tabeli Transakcje musi posiadaè w polu ID klienta wartoĈè, która odpowiada
wartoĈci pola ID klienta jakiegoĈ rekordu w tabeli Klienci.

background image

3.3. Usuwanie danych

_

93

Rysunek 3.11. Przeglñdanie relacji pomiödzy dwiema tabelami

Rekordy w tabeli Klienci muszñ posiadaè unikatowe wartoĈci w polu ID klienta, stñd iloĈè rekor-
dów w tabeli Klienci jest taka sama, jak iloĈè unikatowych identyfikatorów klientów (iloĈè uni-
katowych  wartoĈci  pola  ID  klienta).  W  taki  wäaĈnie  sposób  tabela  Klienci  speänia  rolö  tabeli
nadrzödnej w relacji jeden do wielu.

Pole ID klienta w tabeli Transakcje nie musi posiadaè unikatowych wartoĈci. W praktyce sytu-
acja wyglñda tak, Ĕe niemal kaĔdy rekord z tabeli Klienci bödzie posiadaä wiele odpowiadajñcych
mu rekordów w tabeli podrzödnej Transakcje — dobrze prowadzony biznes powoduje, Ĕe stali,
lojalni klienci ciñgle wracajñ i skäadajñ nowe zlecenia.

I znów, jedynym wymaganiem dla rekordów z tabeli Transakcje jest to, Ĕe wartoĈè pola ID klienta
musi odpowiadaè wartoĈci tego pola w jednym z rekordów tabeli Klienci.

Teraz zaäóĔmy, Ĕe chcemy usunñè danego klienta z tabeli Klienci. PoniewaĔ pomiödzy tabelami
istniejñ wiözy integralnoĈci, ale kaskadowe usuwanie rekordów pokrewnych nie jest dozwolone
(opcja Kaskadowo usuþ rekordy pokrewne jest wyäñczona, jak to zostaäo zilustrowane na rysunku
3.11), to jeĔeli dany klient bödzie posiadaä powiñzane rekordy w tabeli podrzödnej, Access nie
pozwoli na proste usuniöcie klienta. Wiözy integralnoĈci pomiödzy tabelami nie pozwolñ na
utworzenie „osieroconych” rekordów. Klienci nie muszñ mieè Ĕadnych rekordów opisujñcych
transakcje, wiöc usuniöcie klientów bez transakcji jest moĔliwe, ale jeĔeli dla danego klienta
istniejñ w tabeli podrzödnej jakiekolwiek rekordy opisujñce jego transakcje, to usuniöcie takiego
klienta nie bödzie moĔliwe.

JeĔeli klient posada jakieĈ powiñzane z nim transakcje, to przed usuniöciem rekordu klienta
musimy usunñè wszystkie rekordy opisujñce jego transakcje. Usuwanie rekordów transakcji nie
podlega Ĕadnym ograniczeniom i w Ĕaden sposób nie moĔemy utworzyè „osieroconego” rekordu
klienta — „osierocone” rekordy mogñ siö teoretycznie pojawiè jedynie w tabeli podrzödnej.

background image

94

_

Rozdzia

ĥ 3. Kwerendy funkcjonalne

A zatem w jaki sposób usunñè wszystkie transakcje danego klienta? Kwerenda usuwajñca przed-
stawiona na rysunku 3.12 usuwa wszystkie rekordy transakcji dla klienta 

April Kramer

. W re-

kordzie opisujñcym tego klienta znajduje siö odpowiednie pole ID klienta, które jest wykorzy-
stywane przez kwerendö do identyfikacji usuwanych rekordów. Zwróèmy uwagö na fakt, Ĕe
w wierszu Usuwanie w pierwszych dwóch kolumnach umieszczono klauzule 

Where

, speäniajñce

rolö kryteriów wyszukiwania. Trzecia kolumna identyfikuje tabelö, z której bödñ usuwane odna-
lezione rekordy (Transakcje); w wierszu Usuwanie tej kolumny umieszczono klauzulö Skñd.

Rysunek 3.12. Usuwanie rekordów z jednej tabeli w oparciu o kryteria z innej tabeli

Kod SQL kwerendy przedstawionej na rysunku 3.12 wyglñda nastöpujñco:

DELETE Klienci.Imi

Ă, Klienci.Nazwisko, Transakcje.*

FROM Klienci INNER JOIN Transakcje ON
Klienci.[ID klienta] = Transakcje.[ID klienta]
WHERE (((Klienci.Imi

Ă)="April") AND

((Klienci.Nazwisko)="Kramer"));

Jest  to  nieco  mylñce,  poniewaĔ  po  säowie  kluczowym 

DELETE

  wystöpujñ  nazwy  pól  z  tabeli

Klienci (Imiö Nazwisko) — moĔna stñd wysnuè mylny wniosek, Ĕe usuwane bödñ rekordy z tabeli
Klienci. OczywiĈcie nie jest to prawdñ — usuwane sñ tylko rekordy transakcji z tabeli podrzödnej,
podczas gdy tabela klientów pozostaje nienaruszona. Rekord opisujñcy klienta zostaje usuniöty
przez kolejnñ kwerendö, przedstawionñ na rysunku 3.13.

Usuniöcie  w  ten  sposób  rekordu  klienta  April  Kramer  moĔe  byè  niebezpieczne,
poniewaĔ teoretycznie moĔe istnieè wiöcej niĔ jeden klient o takim imieniu i nazwisku.
Imienia i nazwiska klienta uĔyto w tej kwerendzie tylko na potrzeby lepszego zilustro-
wania zasady usuwania takich rekordów. W praktyce jedynym sposobem gwarantujñ-
cym, Ĕe usuniöty zostanie wäaĈciwy rekord klienta, jest posäuĔenie siö polem ID klienta.

Jak  widaè,  jeĔeli  kaskadowe  usuwanie  rekordów  pokrewnych  nie  jest  dozwolone  (na  przy-
käad kiedy w oknie Edytowanie relacji opcja Kaskadowo usuþ rekordy pokrewne zostaäa wyäñczona),
przed usuniöciem rekordu klienta musimy usunñè wszystkie odpowiadajñce mu rekordy z tabeli
podrzödnej. JeĔeli jednak ta opcja zostaäa wäñczona, to usuniöcie wybranych rekordów z tabeli
nadrzödnej spowoduje automatyczne usuniöcie wszystkich pokrewnych rekordów z tabeli pod-
rzödnej. W takiej sytuacji usuniöcie 

April Kramer

 z tabeli Klienci spowodowaäoby automatycz-

nie usuniöcie wszystkich zwiñzanych z niñ rekordów z tabeli Transakcje.

background image

3.4. Kwerendy tworz

éce tabele

_

95

Rysunek 3.13. Kwerenda usuwajñca z tabeli nadrzödnej rekord klienta

Takie rozwiñzanie potrafi zaoszczödziè masö czasu, ale nie ma nic za darmo. Kaskadowe usu-
wanie rekordów pokrewnych moĔe w prosty sposób spowodowaè niezamierzone usuniöcie
z tabel cennych informacji. JeĔeli chcemy skorzystaè z tej opcji, powinniĈmy upewniè siö, Ĕe
kopie zapasowe danych sñ tworzone odpowiednio czösto, w regularnych odstöpach czasu. Usu-
niöcie danych jest nieodwoäalne i jeĔeli nie posiadamy odpowiedniej kopii zapasowej, anulo-
wanie takiej operacji i przywrócenie poprzednich danych nie bödzie moĔliwe. JeĔeli nie posia-
damy odpowiedniego mechanizmu tworzenia kopii zapasowych, ryzyko zwiñzane z uĔyciem
moĔliwoĈci kaskadowego usuwania rekordów moĔe przewaĔyè nad wszystkimi zaletami päy-
nñcymi z zastosowania tego mechanizmu. Zanim zdecydujemy siö na jego zastosowanie, musimy
starannie rozwaĔyè wszystkie argumenty za i przeciw.

3.4. Kwerendy tworz

éce tabele

Opis problemu

W jaki sposób moĔna utworzyè tabelö przechowujñcñ rekordy bödñce rezultatem dziaäania
kwerendy?

Rozwi

ézanie

W pewnych sytuacjach bardzo uĔyteczna moĔe byè moĔliwoĈè umieszczenia rekordów zwra-
canych przez kwerendö bezpoĈrednio w nowej tabeli. Aby tego dokonaè, musimy skorzystaè
kwerendy tworzñcej tabelö (ang. make-table query).

W zasadzie moĔemy sobie teraz zadaè pytanie, po co mamy zadawaè sobie trud tworzenia nowej
tabeli, skoro tabele przechowujñce takie dane juĔ istniejñ? Oto kilka powodów:

Aby poäñczyè w jednej tabeli powiñzane ze sobñ dane nieposiadajñce struktury hierarchicznej.

Aby podzieliè dane z jednej wielkiej tabeli na kilka mniejszych tabel. Takiego podziaäu doko-
nujemy zazwyczaj w oparciu o wartoĈci jednego lub kilku pól kluczowych tabeli Ēródäowej.

background image

Czytaj dalej...

96

_

Rozdzia

ĥ 3. Kwerendy funkcjonalne

Rysunek 3.14 dobrze ilustruje pierwszñ sytuacjö. Mamy tutaj dwie tabele, które najwyraĒniej sñ
ze sobñ powiñzane — majñ wspólne pole ID pracownika, aczkolwiek nie istnieje tutaj relacja jeden
do wielu. W kaĔdej z tabel jednemu pracownikowi odpowiada tylko jeden rekord. Utrzymywa-
nie nazwisk pracowników w jednej tabeli, a informacji o dacie zatrudnienia i dziale w innej tabeli
byè moĔe ma jakieĈ uzasadnienie biznesowe, ale nie ma Ĕadnego sensu z punktu widzenia pro-
jektowania bazy danych. Poäñczenie danych z tych dwóch tabel w jednñ wydaje siö byè jak naj-
bardziej sensownym posuniöciem. Tabela bödñca rezultatem takiej operacji bödzie miaäa jedno
pole ID pracownika oraz trzy dodatkowe pola opisujñce dane pracownika.

Rysunek 3.14. Dwie tabele poäñczone relacjñ jeden do jednego

Aby utworzyè takñ tabelö, musimy umieĈciè dwie istniejñce tabele w widoku projektu kwe-
rendy, a w siatce projektu umieĈciè wszystkie pola tych tabel (ale tylko jedno pole ID pracownika).
Nastöpnie musimy poinformowaè Accessa, Ĕe tworzymy kwerendö tworzñcñ tabele. Aby tego
dokonaè, wybieramy z menu gäównego polecenie Kwerendy/Kwerenda tworzñca tabele (w wersji
Access 2007 uĔywamy odpowiedniego przycisku na WstñĔce). Kiedy wybierzemy z menu kwe-
rendö tworzñcñ tabele, na ekranie pojawi siö okno dialogowe Tworzenie tabeli, w którym moĔemy
wpisaè nazwö nowej tabeli lub wybraè z listy rozwijanej nazwö istniejñcej tabeli.

Na rysunku 3.15 przedstawiono projekt kwerendy, która äñczy rekordy z dwóch tabel i zapisuje
je w jednej, nowej tabeli o nazwie DaneOsobowePracowników.

Kod SQL kwerendy przedstawionej na rysunku 3.15 wyglñda nastöpujñco:

SELECT Pracownicy.[ID pracownika], Pracownicy.Pracownik,
DataZatrudnienia_Dzia

Ī.[Data zatrudnienia],

DataZatrudnienia_Dzia

Ī.[Nazwa dziaĪu] INTO DaneOsobowePracowników

FROM Pracownicy INNER JOIN DataZatrudnienia_Dzia

Ī ON

Pracownicy.[ID pracownika] = DataZatrudnienia_Dzia

Ī.[ID pracownika];

Zwróèmy uwagö, Ĕe kluczowym elementem takiej kwerendy jest polecenie 

SELECT <lista pól>

INTO <nazwa nowej tabeli>

, po którym nastöpujñ: klauzula 

FROM

 oraz ewentualne sprzöĔenia

i kryteria wyszukiwania.