SQL na
przykładach bazy danych InterBase firmy Inprise (Borland)
oraz bazy danych DB2 firmy IBM
Do nauki języka SQL potrzebny jest jego interpreter do obsługi bazy danych.
Do nauki języka SQL mogą być wykorzystane m.in. :
·
baza danych
InterBase firmy Inprise
(Borland) oraz
·
baza danych DB2 firmy IBM.
InterBase i IBM DB2 są to systemy relacyjnej bazy danych, w których została zaimplementowana pełna składnia języka SQL.
Ponadto, zarówno InterBase firmy Inprise
(Borland) jak i DB2 firmy IBM w wersji Personal Edition są dostępne za
darmo.
Są to w pełni profesjonalne i popularne systemy, które dodatkowo są łatwe w
obsłudze
i administrowaniu.
DB2 firmy IBM posiada więcej możliwości, ale jeśli chodzi o zakres interpretowanego języka SQL oba systemy są sobie równe.
Dla osób nie posiadających szybkiego łącza do Internetu, InterBase jest lepszym wyborem.
InterBase
SQL firmy Inprise (Borland)
jest systemem relacyjnych baz danych, pracującym w technologii klient-serwer,
w którym została zaimplementowana pełna składnia języka SQL.
Jest to w pełni profesjonalny i łatwy w obsłudze i administrowaniu system,
dostępny dla środowisk Microsoft Windows, Solaris i Linux.
Obecnie
sprzedawana jest wersja 7 serwera, która wymaga co najmniej 40MB miejsca na
dysku (nie licząc pojemności powstających baz).
Na komputerze klienta instaluje się jedynie bibliotekę DLL o rozmiarze 400 KB,
która zapewnia programom dostęp do serwera bazodanowego poprzez sieć
komputerową.
W 2000 roku firma Borland udostępniła kod źródłowy serwera InterBase 6.0 i później na jego podstawie powstał niezależny projekt bazy danych o nazwie Firebird.
IBM DB2 - relacyjny serwer danych z rodziny Information Management Software.
Baza IBM
DB2 v9.5 oferowana
jest w trzech komercyjnych edycjach:
Express, Workgroup, Enterprise
oraz bezpłatnej edycji DB2 Express-C.
Wszystkie edycje DB2 oparte są o ten sam kod i różnią się ograniczeniami
licencyjnym wynikającymi z zastosowanej platformy sprzętowej oraz ewentualnych
opcjonalnych komponentów.
edycje zawierają ten sam zestaw graficznych narzędzi administracyjnych, które
dostępne są standardowo także w języku polskim.
Bezpłatna edycja DB2 Express-C może być stosowana w komercyjnych rozwiązaniach
i nie ogranicza wielkości bazy danych.
Do każdego serwera bezpłatnej bazy można
wykupić wsparcie techniczne na okres jednego roku (DB2 Express-C FTL).
Wykupione wsparcie techniczne umożliwia dostęp do regularnie publikowanych
przez IBM uaktualnień kodu
oraz daje możliwość konfiguracji bazy w architekturze o wysokiej dostępności
W czasie
kiedy komputery nie były wykorzystywane tak powszechnie jak dzisiaj,
informacje były gromadzone na papierze.
Pracownik
firmy musiał ręcznie organizować dane.
Zapisywał je, wyszukiwał, aktualizował itd.
Dzisiaj, oprócz operacji, które musi wykonać ręcznie, pozostałe wykonuje za pomocą funkcji, które dostarcza relacyjny system bazy danych.
Relacyjny system bazy danych przechowuje wszystkie dane w tabelach.
Każda tabela
zawiera dane na konkretny temat,
np. dane o klientach, dane o pracownikach, towarach itp.
System
bazy danych zarządza
tymi danymi, pozwala m.in. na szybsze ich wyszukanie
i zorganizowanie
Za każdym
razem gdy potrzebujemy informacji z bazy danych,
musimy „zapytać" system bazy danych w języku, który on rozumie.
Tym językiem jest SQL - Structured Query Language
Do dzisiaj istnieją tzw. tradycyjne
bazy danych.
Są to bazy informacji, których nośnikiem jest po prostu papier. Wiele
instytucji w tym niestety policja oraz szpitale korzysta do dziś z takich baz.
Scenariusz wydobywania danych w takich instytucjach jest następujący:
§ osoba potrzebująca danych np. przełożony prosi drugą osobę o pewne dane;
§ pracownik po otrzymaniu polecenia szuka informacji wśród dokumentów, które zostały złożone albo w archiwum lub w po prostu w szafie;
§ pracownik po zebraniu pewnej ilości segregatorów z danego okresu przegląda je, a następnie przygotowuje zbiorczy dokument zawierający żądane informacje;
§ po wydobyciu danych i zorganizowaniu ich do odpowiedniej formy wysyła je do przełożonego.
Czas wykonania tych operacji jest różny i zależy od wielkości organizacji, jej struktury, ilości potrzebnych danych oraz od pracowitości osób je zbierających.
W systemie
relacyjnej bazy danych wszystkie powyższe operacje sprowadzają się do sformułowania
tego samego pytania o dane
ale w formie zrozumiałej dla komputera, a ściślej mówiąc, w formie zrozumiałej
dla systemu bazy danych.
Cała operacja wydobywania danych trwa w tym przypadku znacznie krócej. Jakość tych danych jest przy tym lepsza.
Mamy więcej pewności, że dane są prawdziwe, że ktoś się nie pomylił lub pominął pewną część danych przy zestawianiu żądanych informacji.
Język SQL jest wykorzystywany w
większości relacyjnych systemów baz danych. SQL
jest zaimplementowany m.in. w takich systemach baz danych, jak:
DB2, Oracie, Inter-Base, MySQL,
dBase, Paradox.
Składnia języka SQL dzieli się na trzy typy:
§ Język definiowania struktur danych - DDL (Data Definition Language);
§ Język do wybierania i manipulowania danymi - DML (Data Manipulation Language);
§ Język do zapewniania bezpieczeństwa dostępu do danych - DCL (Data Control Language).
Rys.2.5.
Język DDL jest używana przez administratorów systemu relacyjnej
bazy danych w celu utrzymania struktury bazy danych,
obiektów bazy danych takich jak m.in. tabele.
Język DCL
jest używany przez administratorów do zapewnienia bezpieczeństwa dostępu do
danych,
m.in. do nadawania uprawnień do danych.
Język DML jest używany przez wszystkich użytkowników, którzy mają
dostęp do bazy danych.
Za pomocą tego typu składni języka SQL użytkownicy mogą otrzymywać, zmieniać
dane, dodawać nowe itp.
Tabela składa
się z wierszy i kolumn. Wiersze w tabeli są przechowywane w dowolnym porządku.
Dla każdego wiersza każda z kolumn posiada jedno pole z wartością. Wszystkie
wartości w kolumnie są tego samego typu.
W różnych systemach relacyjnej bazy
danych jak np. DB2, Oracie, InterBase czy dBase lub Paradox,
każda tabela jest przechowywana w osobnym zbiorze na dysku twardym lub kilka
tabel w jednym zbiorze.
Sposób przechowywania danych z tabeli na dysku twardym jest tematem
drugorzędnym.
Ćwiczenia te
maja przede wszystkim na celu nauczenie języka SQL.
Teraz wystarczy tylko wiedzieć, że sposób przechowywania tabel zależy od
implementacji systemu relacyjnej bazy danych.
Nazwa tabeli
składa się z dwóch części. Pierwsza część to kwalifikator, a druga z kolei to
nazwa tabeli.
Kwalifikator i nazwa tabeli oddzielone są kropka. Każda tabela musi mieć
unikatową nazwę
w granicach kwalifikatora.
Taka
konstrukcja nazwy tabeli nie stosuje się we wszystkich relacyjnych bazach da nych.
Między innymi w opisywanym tutaj systemie InterBase.
W InterBase odwołanii do
tabeli następuje wprost, np.
SELECT
* FROM KLIENCI . .
.
w systemie DB2
SELECT
* FROM DB2ADMIN.KLIENCI
W różnych
systemach relacyjnej bazy danych inaczej nazywają się typy danych.
Jednak ich zakres i typ jest często identyczny.
Każdy system relacyjnej bazy danych posiada w swojej dokumentacji sekcję, która
opisuje typy danych używanych w tym systemie.
Poniżej znajdują się przykładowe typy danych wraz z ich opisem.
Tabela 2.1. numeryczne
typy danych
Typ danych |
Opis |
SMALLINT
|
liczby całkowite z przedziału –32768 do +32767 (czasami ten zakres jest mniejszy) |
INTEGER
|
liczby całkowite z przedziału –2147483648 do +2147483647 (lub mniejszy) |
DECIMAL
(m,n)
|
liczby rzeczywiste, gdzie m oznacza całkowitą liczbę cyfr, a n oznacza liczbę cyfr po przecinku |
Tabela 2.2. znakowae typy danych
Typ danych |
Opis |
CHAR
(n)
|
typ znakowy o stałej długości (max. 255 znaków) |
VARCHAR
(n)
|
typ znakowy o zmiennej długości |
Tabela
2.3.typy danych daty i czasu
Typ danych |
Opis |
DATE
|
typ daty (występują różne standardy zapisywania daty) |
TIME
|
typ czasu (występują różne standardy zapisywania czasu) |
Tworzenie tabeli polega na
definiowaniu jej kolumn.
Dla każdej kolumny
należy określić nazwę kolumny, typ danych i długość (w zależności od typu)
oraz to, czy jest dozwolone pozostawienie wartości pustej w kolumnie.
CREATE TABLE UZYTKOWNIK.PRACOWNICY (
ID_PRACOW CHAR(6)NOT NULL,
IMIE VARCHAR(18)NOT NULL,
NAZWISKO VARCHAR(24) NOT NULL,
STANOWISKO VARCHAR(12)NOT NULL,
DZIAL VARCHAR(12) NOT
NULL,
DATA_URODZ DATE,
TELEFON_DOM CHAR(12));
Wartość null jest to wartość nieokreślona, która może zostać użyta w każdym polu tabeli niezależnie od typu kolumny. Wartość null jest różna od zera lub spacji.
W tabeli na rysunku 2.8 osobom, które nie posiadają firmy, w kolumnach: FIRMA oraz NIP przypisano wartość mull.
Przy
konstruowaniu tabeli poleceniem create
table w poprzedniej sekcji określiliśmy dla pewnych kolumn parametr not null.
Oznacza to, że przy wstawianiu nowych wierszy musimy określić wartości
dla tych kolumn, nie mogą one być wartością null.
Definicja kolumny w poleceniu create table pozostawiona bez klauzuli not null określa,
że dozwolone jest wstawienie do tej kolumny wartości null. Istnieje jeszcze opcja o następującej składni:
NOT NULL WITH DEFAULT ( (wartość)]
gdzie
parametr wartość określa domyślną wartość dla kolumny. Wartość domyślna zostanie
nadana dla kolumny automatycznie,
gdy nie określimy jej wprost przy wstawianiu nowego wiersza do tabeli.
Możemy
udostępnić nasze dane innym użytkownikom, a ściślej mówiąc możemy udostępnić
tabele innemu użytkownikowi.
W tym celu stosuje się polecenie języka SOŁ grant.
Poniższy przykład nadaje uprawnienia użytkownikowi o nazwie UŻYTKOWNIK
do tabeli PRACOWNICY.
Od tej pory UŻYTKOWNIK może wybierać (wykonywać zapytania select) dane z naszej tabeli.
GRANT
SELECT ON PRACOWNICY TO UŻYTKOWNIK;
Prawa do tabeli można odebrać poleceniem revoke. Oto przykład:
REVOKE SELECT ON PRACOWNICY FROM UŻYTKOWNIK;
Powyższy
przykład użycia polecenia grant umożliwia
tylko wybieranie danych z tabeli.
Poniższy przykład umożliwia wybieranie, wstawianie i aktualizowanie danych w
tabeli.
GRANT SELECT, INSEKT, UPDATE ON PRACOWNICY TO UZYTKOWNIK;
Za pomocą widoków możemy ograniczyć
zakres danych dostępnych dla użytkownika.
Widok może ograniczać dane z jednej tabeli lub może to być kompozycja danych z
kilku tabel.
Dane w widoku mogą być ograniczone do kilku kolumn lub do pewnego zakresu
wierszy.
Widoki stosuje się w różnych celach:
§ w celu zabezpieczenia danych przed niepowołanym dostępem;
§ uproszczenia korzystania z danych dla końcowego użytkownika.
Przykładem
zwiększenia bezpieczeństwa może być widok, który nie obejmuje kolumny z danymi
o zarobkach.
Wiadomo, że nie wszyscy użytkownicy powinni mieć dostęp do takich danych.
1. Relacyjna baza danych jest kolekcją tabel.
2. Użytkownicy nie musza się martwić o to, jak dane są przechowywane w bazie danych oraz jak są wydobywane.
3. SQL jest językiem do komunikowania się z baza danych.
4. Język SQL jest używany do:
§ wydobywania danych (select);
§ manipulowania danymi (ihsert, update, delete);
§ definiowania, redefiniowania i usuwania obiektów wchodzących w skład
§ struktury bazy danych (create, alter, drop);
§ definiowania uprawnień do danych (grant, revoke).
5. Użytkownicy mogą mieć dostęp do danych poprzez widoki.
Polecenie select jest
używane do pobierania danych z bazy danych (z tabel lub widoków).
W tym rozdziale zapoznamy się ze składnią polecenia select.
Rozdział ten ma na celu nauczenie formułowania zapytań SQL do
wyświetlana wsstkich wierszy z tabeli,
wybierania określonych kolumn, używania warunków, używania stów kluczowych
BETWEEN, IN, LIKE oraz DISTINCT.
Tabela 3.1
select
opisuje nazwy kolumn, wyrażenia
arytmetyczne, funkcje
from
nazwy tabel
lub widoków
where
warunek
(wybieranie wierszy)
group by nazwy kolumn
having
warunek (grupowanie wybieranych wierszy)
order by nazwy kolumn lub pozycje
kolumn
Każde polecenie select musi
posiadać klauzule select oraz from, pozostałe klauzule są opcjonalne.
Inne klauzule wchodzące w skład polecenia select zostaną szczegółowo omówione później.
Poniższe polecenie select wyświetla
wszystkie kolumny i wiersze z tabeli PRACOWNICY.
select *
from
db2admin.pracownicy;
Wybieranie wszystkich kolumn i wierszy ma sens tylko w przypadku
małych tabel,
W praktyce buduje się zapytania, które znacznie ograniczają wynik zapytania.
Polecenie select, którego
użyjemy za chwilę, wyświetla kolumny IMIĘ, NAZWISKO i DZIAŁ z tabeli
PRACOWNICY.
SELECT IMIE, NAZWISKO, DZIAL FROM DB2ADMIN.PRACOWNICY;
Następujące polecenie select
wyświetla kolumny IMIĘ, NAZWISKO i DZIAŁ z tabeli PRACOWNICY i
jednocześnie porządkuje dane według nazwiska.
SELECT IMIE, NAZWISKO, DZIAL FROM
DB2ADMIN.PRACOWNICY
ORDER BY NAZWISKO ASC;
Wynik wykonania zapytania jest uporządkowany według kolumny
wskazanej w klauzuli ORDER BY.
Słowo kluczowe asc mówi
o tym, że sortowanie zostanie dokonane w porządku rosnącym.
Sortowanie rosnące jest domyślne więc słowo kluczowe asc nie musi być wyspecyfikowane.
Porządek malejący uzyskuje się przez zastosowanie słowa desc.
W zależności od implementacji bazy danych kolumna występująca w
klauzuli ORDER by musi być
częścią wyniku wykonania zapytania.
Możliwe jest wskazanie większej liczby kolumn w klauzuli order by.
Przykładowo może istnieć potrzeba wybrania danych w tabeli z
jednoczesnym sortowaniem według stanowiska,
na którym dana osoba pracuje, a następnie według nazwiska.
SELECT IMIĘ, NAZWISKO,
STANOWISKO, DZIAŁ
FROM DB2ADMIN.PRACOWNICY ...
ORDER BY STANOWISKO ASC, NAZWISKO ASC;
Istnieje inny sposób na wskazanie kolumn w klauzuli order by. Zamiast nazywać kolumny,
możemy je wskazać poprzez ich pozycje na liście select.
SELECT IMIE, NAZWISKO,
STANOWISKO, DZIAL FROM DB2ADMIN.PRACOWNICY
ORDER BY 3 ASC, 2 ASC;
Inne przykłady:
ORDER BY 3 ASC, NAZWISKO ASC
ORDER BY 3 ASC, 2 ASC, DZIAL ASC;
Dozwolona jest tylko jedna klauzula order by w zapytaniu select.
Klauzulę order by określa
się jako ostatnią w całym zapytaniu select.
Słowo kluczowe distinct zapewnia,
że wynik zwrócony z zapytania zawierać będzie tylko niepowtarzające się
wiersze.
Wszystkie powtarzające się wartości nie zostaną wyświetlone.
SELECT DISTINCT STANOWISKO FROM DB2ADMIN.PRACOWNICY;
Słowo kluczowe distinct musi
występować zaraz po słowie kluczowym select.
SELECT DISTINCT STANOWISKO, DZIAŁ FROM DB2ADMIN. PRACOWNICY;
Takie zapytanie wyświetli wszystkie stanowiska obejmowane w danych
działach.
Jeżeli w danym dziale pojawią się dwa takie same stanowiska, tylko jedno
zostanie wyświetlone.
Słowo distinct eliminuje
wiersze, które posiadają duplikaty we wszystkich kolumnach wyspecyfikowanych w
wyrażeniu select.
Tylko jedno słowo distinct może
zostać użyte w całym zapytaniu select.
Do wybrania określonych wierszy z tabeli używa się klauzuli where, która służy do określenia
kryterium wyboru wierszy.
W klauzuli WHERE specyflkujemy warunek, który musi
być spełniony dla szukanych wierszy.
SELECT IMIĘ, NAZWISKO,
STANOWISKO, DZIAL
PROM DB2ADMIN.PRACOWNICY
WHERE STANOWISKO = 'SPRZEDAWCA’;
W
przypadku kolumn typu znakowego, daty lub czasu, wartości dla których
sprawdzany jest warunek muszą być otoczone apostrofem.
Przy porównywaniu kolumn typu znakowego należy pamiętać, że rozróżniane są
wielkie i małe litery.
Dla kolumn typu numerycznego jak np.
INTEGER, SMALLINT, wartości do porównania nie są otaczane apostrofem.
SELECT NR_KLIENTA,
NR_SAMOCHODU, NR_PRACOW_WYP,
CENA_JEDN
FROM DB2ADMIN.WYPOZYCZENIA
WHERE CENA_JEDN
>= 100;
Operatory
logiczne używane w klauzuli WHERE
SELECT NR_KLIENTA, NR_SAMOCHODU, NR_PRACOW WYP, CENA_JEDN
FROM
DB2ADMIN. WYPOZYCZENIA
WHERE CENA_JEDN = 100 - równa
CENA_JEDN
<> 100 - nie równa
CENA_JEDN
> 100 - większa niż
CENA_JEDN
>= 100 - większa lub równa
CENA_JEDN
< 100 - mniejsza niż
CENA_JEDN
<= 100 - mniejsza lub równa
Kiedy w warunku używamy operatora and, aby wiersz został zawarty w wyniku,
oba warunki połączone operatorem and muszą
zostać spełnione, tzn. muszą zwrócić wartość prawdy (TRUE).
Warunek z operatorem or zwróci
wartość TRUE, gdy przynajmniej jedna ze stron zwróci wartość TRUE.
SELECT IMIE, NAZWISKO, STANOWISKO, DZIAL
FROM DB2ADMIN.PRACOWNICY
WHERE STANOWISKO = 'SPRZEDAWCA'
AND DZIAL = 'OBSŁUGA KLIENTA’;
Takie zapytanie SQL zwróci w wyniku wszystkich pracowników
pracujących na stanowisku sprzedawca w dziale obsługi klienta.
SELECT IMIE,
NAZWISKO, STANOWISKO, DZIAL
FROM DB2ADMIN.PRACOWNICY
WHERE STANOWISKO = 'SPRZEDAWCA'
OR DZIAL = 'TECHNICZNY';
Następne zapytanie zwróci wszystkich
pracowników pracujących na stanowisku sprzedawca oraz wszystkich pracowników
pracujących w dziale technicznym
niezależnie od tego, czy pracują na stanowisku sprzedawca.
Operatorów and i or możemy używać razem do budowy
bardziej złożonych warunków.
Następujące zapytanie zwróci wszystkich
pracowników pracujących na stanowisku kierownika
w dziale obsługi klienta oraz wszystkich pracowników z działu technicznego.
Wiersze zostaną uporządkowane wg działu a następnie wg nazwiska.
SELECT IMIE, NAZWISKO,
STANOWISKO, DZIAL
FROM DB2ADMIN.PRACOWNICY
WHERE STANOWISKO = 'KIEROWNIK'
AND
DZIAL = 'OBSŁUGA KLIENTA'
OR DZIAL = 'TECHNICZNY'
ORDER BY DZIAL, NAZWISKO;
W poprzednim przykładzie widoczna jest wyższość operatora and nad operatorem or.
Następne zapytanie posiada w klauzuli where
warunki otoczone nawiasami.
Nawiasy pozwalają określić kolejność sprawdzania warunków.
SELECT IMIE, NAZWISKO,
STANOWISKO, DZIAL
FROM DB2ADMIN.PRACOWNICY
WHERE STANOWISKO = 'KIEROWNIK’
AND (DZIAL = 'OBSŁUGA KLIENTA' OR
DZIAŁ = 'TECHNICZNY')
ORDER BY DZIAL, NAZWISKO;
Zapytanie wyświetli osoby pracujące tylko na stanowisku kierownika
w dziale obsługi klienta lub w dziale technicznym.
Predykat in pozwala
porównać wartość do wartości ze zbioru. Wartości typu znakowego, daty i czasu
muszą być otoczone apostrofem.
SELECT IMIE, NAZWISKO, STANOWISKO, DZIAL
FROM
DB2ADMIN.PRACOWNICY
WHERE STANOWISKO IN ('SPRZEDAWCA’,
'KIEROWNIK');
Wartości mogą być typu numerycznego, znakowego, typu daty lub czasu.
SELECT MARKA, TYP, ROK_PROD, POJ_SILNIKA
FROM DB2ADMIN.
SAMOCHODY
WHERE POJ_SILNIKA
IN (1400, 1600);
Predykat between pozwala sprawdzić, czy dana wartość zawiera się między dwoma wskazanymi wartościami.
SELECT MARKA,
TYP, ROK_PROD, KOLOR, POJ_SILNIKA
FROM DB2ADMIN.SAMOCHODY
WHERE POJ_SILNIKA
BETWEEN 1100 AND 1800;
Zapytanie zwróciło dane o samochodach, których pojemność silnika
zawiera się miedzy 1100 a 1800 cm sześciennych.
Klauzula:
WHERE
POJ_SILNIKA BETWEEN 1100 AND 1800;
jest równa następującemu zapisowi:
WHERE POJ_SILNIKA
>= 1100 AND POJ_SILNIKA <= 1800;
Wybieranie wierszy z tabeli, w których jedno z pól zawiera wartość
pustą null, polega na użyciu
predykatu null.
W przykładzie użycia predykatu null
wybieramy wszystkich klientów, którzy nie posiadają karty kredytowej.
Zwrócone zostaną wiersze z danymi o klientach, którzy w polu NR_ KARTY_KREDYT nie posiadaj ą żadnego wpisu.
SELECT IMIĘ, NAZWISKO, ULICA, MIASTO
PROM DB2ADMIN.KLIENCI
WHERE NR_KARTY_KREDYT
IS NULL;
Możliwe jest wybranie wszystkich klientów posiadających kartę
kredytową.
Wtedy w klauzuli where dla
sprawdzenia wartości w polu NR_KARTY_KREDYT używamy
również predykatu null, ale z
zaprzeczeniem.
SELECT IMIE,
NAZWISKO, NR_KARTY_KREDYT, MIASTO
FROM
DB2ADMIN.KLIENCI
WHERE
NR_KARTY_KREDYT IS NOT NULL;
Często istnieje konieczność wyszukania np. nazwisk klientów, które zaczynają się od konkretnej litery.
SELECT IMIE,
NAZWISKO, ULICA, MIASTO
FROM DB2ADMIN.KLIENCI
WHERE NAZWISKO LIKE 'K%';
Inne przykłady użycia predykatu like:
SELECT IMIE,
NAZWISKO, ULICA, MIASTO
FROM DB2ADMIN.KLIENCI
WHERE NAZWISKO LIKE '%SKI';
Zapytanie zwróci wiersze z danymi o klientach, których
nazwiska kończą się na „ski".
W następnym przykładzie wyszukamy klientów, którzy w swoim
nazwisku posiadają litery „K" oraz „A" w wymienionym porządku.
SELECT IMIE, NAZWISKO, ULICA, MIASTO
FROM DB2ADMIN.KLIENCI
WHERE NAZWISKO LIKE '%K%A%';
W zapytaniach z predykatem like można stosować zaprzeczenie NOT oraz operatory and i OR. Oto przykłady:
SELECT IMIE,
NAZWISKO, ULICA, MIASTO
FROM DB2ADMIN.KLIENCI ,
WHERE
NAZWISKO NOT LIKE 'K%';
Następujące zapytanie wyszuka wszystkich klientów, których
nazwiska nie zaczynają się na literę „K" oraz „D".
SELECT IMIE, NAZWISKO, ULICA, MIASTO
FROM DB2ADMIN.KLIENCI
WHERE
NAZWISKO NOT LIKE 'K%'
AND
NAZWISKO NOT LIKE 'D%' ;
Możliwe jest również wyszukanie np. klientów, których nazwiska
zawierają drugą literę „O".
Znak „_" zastępuje dowolny pojedynczy znak.
SELECT IMIE, NAZWISKO, ULICA, MIASTO
FROM DB2ADMIN.KLIENCI
WHERE NAZWISKO LIKE '_0%';
Oto drugi przykład, w którym pomijamy dwie pierwsze litery
nazwiska:
SELECT IMIE, NAZWISKO, ULICA, MIASTO
FROM DB2ADMIN.KLIENCI
WHERE NAZWISKO LIKE '_C%';
1. Do wybierania danych z tabeli służy polecenie select.
2. Można wybierać wszystkie i określone kolumny tabeli.
3. Można wybierać wszystkie i określone wiersze.
4. Można wybierać dane i jednocześnie je uporządkować.
5. W zapytaniu select można
użyć słów kluczowych:
§ distinct
- w celu
wyszukania nie powtarzających się wierszy;
§ like
- w celu
określenia wartości dla warunku;
§ IN - w celu wskazania
zbioru wartości dla warunku;
§ between - w celu wskazania zakresu wartości dla warunku.
Rozdział 4 . Wybieranie danych z wielu tabel.
W tym rozdziale zajmiemy się wyszukiwaniem danych z wielu tabel.
Do tej pory wszystkie zapytania wyszukujące koncentrowały się na jednej tabeli.
Poza tym nauczymy się używać skrótów w odwoływaniu się do tabel w zapytaniach
SQL. Poznamy również predykat join.
W naszej przykładowej bazie danych WYPAUT, dla każdego numeru
miejsca (miejsca pracy pracownika)
w tabeli PRACOWNICY istnieje jeden wiersz w tabeli MIEJSCA.
DB2 odczytuje numer miejsca pracy pracownika z tabeli PRACOWNICY,
a następnie przeszukuje tabelę MIEJSCA
w celu znalezienia odpowiadającego temu numerowi wiersza, który opisuje
dokładnie miejsce pracy tzn. adres, telefon itd.
W języku baz danych, jakim jest SQL, pytanie przedstawione na poprzednim
rysunku może wyglądać tak:
SELECT DB2ADMIN.PRACOWNICY.NAZWISKO,
DB2ADMIN.PRACOWNICY.STANOWISKO,
DB2ADMIN.PRACOWNICY.DZIAL,
DB2ADMIN.MIEJSCA.MIASTO,
DB2ADMIN.MIEJSCA.ULICA
FROM DB2ADMIN.PRACOWNICY,DB2ADMIN.MIEJSCA
WHERE
DB2ADMIN.PRACOWNICY.NR_MIEJSCA=DB2ADMIN.MIEJSCA.NR_MIEJSCA
ORDER BY DB2ADMIN.PRACOWNICY.NAZWISKO;
Wybieranie danych z wielu tabel nazywa się powszechnie złączeniem
(ang. join). W celu złączenia dwóch lub większej
ilości tabel:
§ w klauzuli select musimy wyspecyfikować kolumny,
które chcemy zawrzeć w zapytaniu;
§ w klauzuli from określamy nazwy złączanych tabel;
§ w klauzuli where określamy warunki złączenia.
Istnieją dwa typy składni zapytania złączającego.
Pierwszy typ został zaprezentowany już w poprzedniej sekcji. Oto zapytanie,
które zostało zbudowane przy użyciu tej składni:
SELECT DB2ADMIN.PRACOWNICY.NAZWISKO,
DB2ADMIN.PRACOWNICY.STANOWISKO,
DB2ADMIN.PRACOWNICY.DZIAL,
DB2ADMIN.MIEJSCA.MIASTO,
DB2ADMIN.MIĘJSCA.ULICA
FROM DB2ADMIN.PRACOWNICY,
DB2ADMIN.MIEJSCA
WHERE DB2ADMIN.PRACOWNICY.NR_MIEJSCA =
DB2ADMIN.MIEJSCA.NR_MIEJSCA
ORDER BY DB2ADMIN.PRACOWNICY.NAZWISKO;
Przy złączaniu dwóch tabel, do poprawnego wyświetlenia wyniku
klauzula where musi zawierać
jeden warunek.
Gdy złączamy trzy tabele, klauzula WHERE musi zawierać przynajmniej dwa
warunki.
Dwa pierwsze warunki w tym przykładzie
dotyczą złączenia tabel, trzeci dotyczy warunku wyboru wierszy.
Oto przykład:
SELECT DB2ADMIN. WYPOŻYCZENIA.NR_WYPOZYCZENIA,
DB2ADMIN.PRACOWNICY.NAZWISKO,
DB2ADMIN.PRACOWNICY.STANOWISKO,
DB2ADMIN.PRACOWNICY.DZIAL,
DB2ADMIN.MIEJSCA.MIASTO,
DB2ADMIN.MIEJSCA.ULICA
FROM DB2ADMIN.PRACOWNICY,
DB2ADMIN.MIEJSCA,
DB2ADMIN.WYPOZYCZENIA
WHERE DB2ADMIN.PRACOWNICY.NR_MIEJSCA =
DB2ADMIN.MIEJSCA.NR_MIEJSCA
AND DB2ADMIN.PRACOWNICY.NR_PRACOWNIKA =
DB2ADMIN.WYPOZYCZENIA.NR_PRACOW_WYP
AND DB2ADMIN.MIEJSCA.MIASTO = 'WARSZAWA'
ORDER BY DB2ADMIN.PRACOWNICY.NAZWISKO;
Inny typ złączenia polega na zastosowaniu konstrukcji join ... on.
SELECT DB2ADMIN.PRACOWNICY.NAZWISKO,
DB2ADMIN.PRACOWNICY.STANOWISKO,
DB2ADMIN.PRACOWNICY.DZIAL,
DB2ADMIN.MIEJSCA.MIASTO,
DB2ADMIN.MIEJSCA.ULICA
FROM DB2ADMIN.PRACOWNICY JOIN
DB2ADMIN.MIEJSCA ON
DB2ADMIN.PRACOWNICY.NR_MIEJSCA =
DB2ADMIN.MIEJSCA.NR_MIEJSCA
WHERE DB2ADMIN.PRACOWNICY.STANOWISKO =
'SPRZEDAWCA'
ORDER BY DB2ADMIN.PRACOWNICY.NAZWISKO;
Kiedy używamy słowa join w
klauzuli from, warunki złączenia
muszą być wyspecyfikowane po klauzuli on.
W klauzuli where można
określić dodatkowe warunki. Oto wynik wykonania powyższego zapytania:
Aliasy definiuje się w celu skrócenia nazwy tabeli. Jak
wiemy na nazwę tabeli składa się kwalifikator i nazwa tabeli.
Kwalifikator mówi o tym, kto jest właścicielem tabeli.
W naszym przykładzie użycia aliasów, alias P wskazuje
na tabelę DB2ADMIN.PRACOWNICY
natomiast alias M opisuje tabelę
DB2ADMIN.MIEJSCA.
SELECT
P.NAZWISKO, P.STANOWISKO, P.DZIAŁ , M.MIASTO, M.ULICA
FROM DB2ADMIN.PRACOWNICY P,
DB2ADMIN.MIEJSCA M
WHERE
P.NR_MIEJSCA
= M.NR_MIEJSCA AND P.STANOWISKO = 'SPRZEDAWCA'
ORDER BY P.NAZWISKO;
Wynik wykonania tego zapytania jest taki sam jak w ten w
poprzedniej sekcji.
Począwszy od tej sekcji w przykładach będziemy stosować aliasy
dla nazw tabel.
1. Dane mogą być wydobywane
z jednej lub wielu tabel.
2. W zapytaniu wybierającym
dane z przynajmniej dwóch tabel można użyć predykatu JOIN.
3. Jeżeli w zapytaniu, które
wybiera dane z przynajmniej dwóch tabel, nie zostanie wyspecyfikowany warunek
po słowie kluczowym where lub on, to zwrócony wynik będzie przedstawiał iloczyn
kartezjański.
4. W zapytaniach można użyć aliasów zamiast nazw tabel.
W tym rozdziale zajmiemy się używaniem funkcji skalarnych i
arytmetycznych.
Będziemy używać funkcji arytmetycznych do przeliczania wartości w kolumnach.
Poznamy podstawowe funkcje skalarne m.in. funkcje operujące na datach i czasie.
Pod koniec tego rozdziału poznamy sposób na wybieranie wartości przy użyciu
wyrażenia case.
W zapytaniu SQL możemy użyć następujących operatorów
arytmetycznych w celu obliczenia wartości:
+ dodawanie
- odejmowanie
* mnożenie
/ dzielenie
Operatorów tych możemy użyć do budowy bardziej rozbudowanych
wyrażeń matematycznych włącznie
z użyciem nawiasów w celu zaznaczenia kolejności wykonywania działań.
SELECT P.IMIĘ, P.NAZWISKO, P.PENSJA, P.DODATEK, P.PENSJA + P.DODATEK
FROM
DB2ADMIN.PRACOWNICY'P WHERE P.PENSJA > 1100
ORDER BY P,NAZWISKO;
Wynik zapytania zawiera obliczoną kolumnę, która jest sumą kolumn;
PENSJA I DODATEK.
Kolumna z wynikiem została domyślnie nazwana „5", ponieważ jest ona piąta
z kolei.
Nazwa taka została nadana w DB2 zainstalowanym pod kontrolą systemu Windows NT.
W innych systemach operacyjnych, DB2 może wy liczoną kolumnę nazywać inaczej.
Dla dwóch pracowników, którzy zajmują stanowisko kierowników nie
zostały obliczone wartości.
Nie posiadają oni żadnego dodatku. Ściślej mówiąc, w polu DODATEK wartość
dodatku dla tych osób wynosi moll.
Wartości NULL nie mogą brać udziału w obliczeniach. W dalszej części
tego rozdziału dowiemy się, jak obejść taki przypadek.
Kolumnę wynikową możemy nazwać. Poniżej znajduje się identyczne
zapytanie jak w poprzedniej sekcji.
Po słowie kluczowym as podana
jest nazwa dla nowej wyliczonej kolumny.
SELECT P.IMIE, P.NAZWISKO, P.PENSJA,
P.DODATEK,
P.PENSJA + P.DODATEK AS DO_WYPLATY
FROM DB2ADMIN.PRACOWNICY P
WHERE P. PENSJA > 1100
ORDER BX P.NAZWISKO;
W tym przykładzie tak samo jak w przykładzie z poprzedniej sekcji
do obliczeń nie mogła być wzięta pod uwagę wartość null.
Stąd puste pola widoczne na powyższym rysunku. Zostanie to rozwiązane w
następnej sekcji.
Nazwa tabeli wyliczonej może być otoczona cudzysłowem co pozwala
na użycie nazwy składającej się z kilku słów. Ilustruje to poniższy przykład.
SELECT P.IMIE, P.NAZWISKO, P.PENSJA,
P.DODATEK,
P.PENSJA + P.DODATEK AS "DO
WYPLATY"
FROM DB2ADMIN.PRACOWNICY P
WHERE P.PENSJA > 1100 ORDER BY
P.NAZWISKO;
Nowa nazwa kolumny wyliczonej nie może być użyta w klauzuli where.
W systemie DB2 może być natomiast użyta w order by.
SELECT P.IMIE, P.NAZWISKO, P.PENSJA,
P.DODATEK
P.PENSJA + P.DODATEK AS DO_WYPLATY
FROM D32ADMIN. PRACOWNICY P
WHERE P.PENSJA > 1100
ORDER BY DO_WYPLATY;
Jak widać w powyższym przykładzie, nazwa kolumny DO_WYPLATY w klauzuli order by nie może być poprzedzona aliasem
jak pozostałe kolumny.
W systemie InterBase, nowa nazwa kolumny
wyliczonej nie może być użyta w klauzuli order
by.
Zamiast nazwy możemy wskazać numer kolumny, względem której będziemy
porządkować dane.
Oto przykład tego samego polecenia dla systemu InterBase:
SELECT P.IMIE, P.NAZWISKO, P.PENSJA,
P.DODATEK,
P.PENSJA + P.DODATEK AS DO_WYPLATY
FROM PRACOWNICY P WHERE P.PENSJA >
1100
Funkcja coalesce została
zaimplementowana tylko w systemie DB2.
Funkcja coalesce jest funkcją
operującą na wartości null.
Zwraca pierwszy argument który
nie jest wartością null. Funkcja
ta jest równoważna funkcji value.
Funkcja yalue jest
synonimem funkcji coalesce. ,
Poniższy przykład użycia funkcji coalesce
rozwiązuje nasz problem z poprzedniej sekcji.
Działanie funkcji coalesce najpierw
w kolumnie DODATEK zamienia wszystkie wystąpienia wartości null
na wartość zera, a następnie robi
to samo przy obliczaniu wartości do wypłaty.
SELECT P.IMIE, P.NAZWISKO, P.PENSJA,
COALESCE ( P.DODATEK, O ) AS DODATEK,
P.PENSJA + COALESCE (P.DODATEK, 0) AS DO_WYPŁATY
FROM DB2ADMIN.PRACOWNICY P
WHERE P,PENSJA
> 1100 ORDER BY P.NAZWISKO;
W kolejnym przykładzie funkcja coalesce
została użyta w celu zastąpienia wszystkich-wystąpień wartości null
na ciąg „nie posiada". Wyświetleni zostali wszyscy klienci.
Dla tych, którzy nie posiadają karty kredytowej, w polu NRJCARTY
został wpisany ciąg „nie posiada".
SELECT K.IMIE, K.NAZWISKO,
COALESCE<K.NR_KARTY_KREDYT,
'Nie posiada') AS NR__KARTY
FROM DB2ADMIN.KLIENCI K;
Funkcja decimal została
zaimplementowana tylko w systemie DB2. Funkia DBCIMAL zwraca dziesiętną
reprezentację wartości numerycznej.
Pierwszy parametr zawiera wartość do reprezentacji, drugi parametr
określa ilość cyfr przed przecinkiem, trzeci parametr określa liczbę
miejsc po przecinku.
SELECT P.IMIE, P.NAZWISKO, P.PENSJA,
DECIMAL ( (P.PENSJA * 11.3)/100, 8,
2} AS KWOTA_PODWYZKI
FROM DB2ADMIN.PRACOWNICY P ORDER BY
P.NAZWISKO;
Przykład oblicza kwotę 11.3%
podwyżki.
Funkcja round została
zaimplementowana tylko w systemie DB2. Służy ona do zaokrąglania wyników,
Funkcja ta w pierwszym argumencie musi zawierać wartość do zaokrąglenia, w
drugim natomiast podaje się liczbę miejsc po przecinku, do jakiej ma zostać
zaokrąglona
wartość. Poniższy przykład zaokrągla wartości do liczb
całkowitych. Wartości dziesiętne poniżej 0,50 zostały zaokrąglone do zera,
natomiast powyżej 0,50 do jedności.
SELECT P.IMIE, P.NAZWISKO, P.PENSJA,
ROUND ( (P.PENSJA * 11.31/100, 0) AS KWOTA_PODWYZKI
FROM DB2ADMIN.PRACOWNICY P
ORDER BY P.NAZWISKO;
Kolumny typu daty lub czasu mogą być porównywane z innymi
wartościami reprezentującymi datę lub czas.
Wartości przedstawiające datę lub czas muszą być otoczone pojedynczym
cudzysłowem. W poniższym przykładzie zostaną wyświetlone dane
pracowników zatrudnionych w lub po dacie 1998-01-01.
SELECT P.IMIE, P.NAZWISKO, P.DZIAL,
P.STANOWISKO, P.DATA_ZATR
FROM DB2ADMIN. PRACOWNICY
P
WHERE P.DATA_ZATR
>= '1998-01-01'
ORDER BY P.NAZWISKO;
Kolejne zapytanie wybiera pracowników zatrudnionych co najmniej 2
lata.
Porównywana wartość 020000 przedstawia
02 rok, 00 miesięcy i 00 dni.
Funkcja current datę zwraca
bieżącą datę. Funkcja ta nie jest dostępna w systemie InterBase.
SELECT P.IMIE, P.NAZWISKO, P.DZIAL,
P.STANOWISKO, P.DATA__ZATR
FROM DB2ADMIN.PRACOWNICY P
WHERE
CURRENT DATE - P.DATA_ZATR >= 020000
ORDER BY P.NAZWISKO;
Oprócz funkcji corrent
datę, która zwraca bieżącą datę, mamy do wykorzystania funkcję
zwracającą
bieżący czas current time oraz
funkcję current timestamp zwracającą
dokładny bieżący czas.
Obie pozostałe funkcje również nie są dostępne w systemie InterBase.
Funkcja year pozwala
odczytać rok z pełnego formatu daty.
Funkcja year oraz wszystkie
pozostałe w tej sekcji nie zostały niestety zaimplementowane w InterBase.
Kolejny przykład jest identyczny do tego z poprzedniej sekcji z tym wyjątkiem,
że dodatkowa kolumna przedstawia
ilość przepracowanych lat przez pracownika, który pracuje dłużej niż dwa lata.
SELECT P.IMIE,
P.NAZWISKO, P.DZIAL, P.STANOWISKO, P.DATA_ZATR,
YEAR
(CURRENT DATĘ -
P.DATA_ZATR) AS ILOSC_LAT
FROM
DB2ADMIN.PRACOWNICY
P
WHERE
CURRENT DATE -
P.DATA_ZATR >=
020000
ORDER BY P.NAZWISKO;
Poza funkcją year mamy
do dyspozycji funkcje mdnth oraz day, które odpowiednio wydobywają z
daty miesiąc i dzień. Oto przykład:
SELECT P. IMIĘ, P. NAZWISKO, P.DATA_ZATR
YEAR(P.DATA_ZATR)
AS ROK,
MONTH(P.DATA_ZATR)
AS MIESIAC,
DAY(P.DATA_ZATR)
AS DZIEN
FROM DB2ADMIN.PRACOWNICY P;
W naszej przykładowej bazie danych znajduje się tabela
WYPOŻYCZENIA, która m.in. przechowuje dane
o dacie wypożyczenia samochodu i o dacie jego oddania.
Następny przykład będzie obliczał ilość dni, przez które samochód był
wypożyczony.
SELECT K.NAZWISKO, W.NR_WYPOZYCZENIA,
W.DATA_WYP,
W.DATA_ODD,
DAYS(W.DATA_ODD)-
DAYS(W.DATA_WYP) + l AS ILOSC_DNI
FROM DB2ADMIN.KLIENCI K,
DB2ADMIN.WYPOŻYCZENIA W
WHERE
K.NR_KLIENTA = W.NR_KLIEHTA AND W.DATA_ODD IS NOT NULL;
Ciąg DAYS(W.DATA_ODD) - DAYS (W. DAT_WYP) + l AS ILOSC_DNI
występujący w zapytaniu odejmuje
od daty oddania datę wypożyczenia samochodu i dodaje jeden.
Dodanie jednego dnia ma na celu zaznaczenie sytuacji, gdy klient oddał samochód
w dniu wypożyczenia.
W takim przypadku różnica tych dat równa jest zero.
W pozostałych przypadkach również dodawana musi być liczba jeden, aby zawrzeć w
wyniku pierwszy dzień wypożyczenia.
Funkcja days odczytuje z daty
ilość dni od daty l stycznia 0001 roku plus jeden.
Następny przykład użycia funkcji days
polega na odjęciu od istniejących dat dwóch dni.
Możemy również posłużyć się funkcją years
oraz months, które
odpowiednio oznaczają lata i miesiące.
SELECT K. NAZWISKO, W. NR_WYPOZYCZENIA,
W.DATA_WYP, W.DATA_ODD
W.DATA_WYP - 2 DAYS, W. DATA_ODD - 2 DAYS
FROM DB2ADMIN.KLIENCI K,
DB2ADMIN.WYPOŻYCZENIA W
WHERE K.NR_KLIENTA
= W. NR_KLIENTA
AND
W.DATA_ODD IS NOT NULL
AND K.MIASTO = 'WARSZAWA';
W razie potrzeby wybrania tyko pewnej części łańcucha musimy
zastosować funkcję substr.
Na poniższym rysunku funkcja substr
wybiera ciąg o długości sześciu znaków począwszy od trzeciego znaku.
SELECT
SUBSTR(K.NAZWISKO, 3, 4), K.NAZWISKO
FROM DB2ADMIN.KLIENCI K;
W InterBase funkcję substr należy „uaktywnić".
Polega to na zadeklarowaniu funkcji, która zostanie pobrana z zewnętrznej
biblioteki dołączanej dynamicznie DLL.
Aby funkcja ,.'." substr była
aktywna w InterBase, wykonaj poniższe polecenie w Interactive SQL.
DECLARE EXTERNAL FUNCTION SUBSTR
CSTRING(80),
SMALLINT, SMALLINT
RETURNS
CSTRING(SO) FREE_IT
ENTRY_POINT
'IB_UDF_Substr' MODULE_NAME 'ib_udf.dll';
Po wykonaniu powyższego polecenia, możemy przejść do opcji IBConsole, aby zobaczyć tę funkcję, klikając w panelu po
lewej stronie w ikonę External Function.
Inaczej niż w DB2, w InterBase funkcja substr wybiera ciąg począwszy od
pozycji podanej w drugim argumencie a skończywszy na trzecim argumencie. Zatem
polecenie:
SELECT SUBSTR(K.NAZWISKO, 3, 4),
K.NAZWISKO
FROM KLIENCI K;
zwróci następujące wyniki:
Funkcja concat pozwala
łączyć ciągi znaków w jeden łańcuch wynikowy. Funkcja ta jest dostępna tylko w
DB2.
Poniższy przykład zapytania wyświetli listę klientów wraz z adresem
zamieszkania. Taka lista może posłużyć jako źródło do korespondencji seryjnej.
SELECT K.IMIE CONCAT ' ' CONCAT
K.NAZWISKO AS KLIENT,
'ul. ' CONCAT K.DLICA CONCAT
' ' CONCAT K. NUMER AS ULICA,
K. KOD CONCAT ' ' CONCAT K. MIASTO
AS MIASTO
FROM DB2ADMIN.KLIENCI K
ORDER BY K.NAZWISKO;
Zamiast funkcji concat
można użyć znaków | |:
SELECT K.IMIĘ | |
' ' | | K.NAZWISKO AS KLIENT, ...
Wyrażenie case pozwala
na wybranie pewnej wartości w zależności od wartości w innej kolumnie.
Wyrażenie case dostępne jest
tylko w systemie DB2.
W przykładzie poniżej sprawdzamy, czy klient pochodzi z Warszawy; jeżeli tak,
to w kolumnie wpisywana jest wartość
„Klient oddziału macierzystego", w przeciwnym razie jest to „Klient z
przedstawicielstwa".
SELECT K.IMIE, K.NAZWISKO, K.MIASTO,
CASE K.MIASTO
WHEN
'WARSZAWA' THEN 'Klient oddziału macierzystego'
ELSE 'Klient z przedstawicielstwa'
END
FROM DB2ADMIN.KLIENCI K ORDER BY
K.NAZWISKO;
1.
Funkcje
arytmetyczne mogą być używane w klauzuli select
orazw HERE.
2. Kolumny wyliczone mogą
być nazwane przez zastosowanie klauzuli as.
3. Funkcje skalarne mogą być
używane do zmiany reprezentacji danych - funkcje: DECIMAL,
SUBSTR, CONCAT.
4. Funkcje skalarne mogą być
użyte do wydobycia lat, miesięcy oraz dni z różnych formatów daty.
5. Wyrażenie CASE pozwala na wybór wartości dla kolumny w zależności od zdefiniowanego warunku.
W tym rozdziale poznamy funkcje operujące na kolumnach, które mogą
być użyte w celu
wydobycia wyników z jednego lub większej ilości wierszy Poznamy również zasady
grupowania wierszy
Do funkcji
kolumnowych zalicza się ftmkcje sum, avg, min, max oraz count
Funkcje te są używane w klauzulach select
lub having
sum - funkcja służąca do obliczenia sumy wartości w
określonych kolumnach,
avg - oblicza średnią wartości \v
kolumnie,
min - znajduje minimalną
wartość,
max - znajduje maksymalną wartość,
count - śluzy do zliczania wystąpień pewnej wartości w
wierszach
Poniższy przykład wyświetli całkowitą sumę wszystkich pensji
pracowników, średnią pensję, minimalną i maksymalna pensję oraz ilość
pracowników
SELECT
SUM(P.PENSJA) AS PENSJA,
AVG(P.PENSJA)
AS SREDNIA,
MIN (P.PENSJA)
AS PENSJA_MIN,
MAX(P.PENSJA)
AS PENSJA_MAX,
COUNT(*) AS
ILOSC FROM DB2ADMIN PRACOWNICY P,
W poprzednim przykładzie funkcja count
została użyta do zliczenia wszystkich wierszy w tabeli (count(*)),
może być ona użyta również do zliczenia wierszy zawierających
powtarzającą się wartość w kolumnie. W tym przykładzie zliczamy liczbę działów
i stanowisk w firmie.
SELECT
COUNT(DISTINCT P.DZIAL) AS ILOSC_DZIALOW,
COUNT(DISTINCT
P.STANOWISKO) AS ILOSC_STANOWISK
FROM DB2ADMIN.PRACOWNICY P;
Stosowanie funkcji kolumnowych można przeprowadzić również na
pewnym podzbiorze wierszy,
SELECT
SUM(P.PENSJA) AS PENSJA,
AVG(P.PENSJA)
AS SREDNIA,
MIN(P.PENSJA)
AS PENSJA_MIN,
MAX(P.PENSJA)
AS PENSJA_MAX,
COUNT(*)
AS ILOSC FROM DB2ADMIN.PRACOWNICY P
WHERE
P.DZIAL = 'OBSLUGA KLIENTA’;
Klauzula group by grupuje
wiersze o tej samej wartości wyszczególnionych kolumn.
Funkcje agregujące SQL (ayg, max, min,
sum oraz count) w klauzuli
select operują na każdej grupie
osobno.
Następujący przykład zapytania pogrupuje wiersze według
stanowiska.
SELECT P.STANOWISKO, SUM (P.PENSJA) AS
PENSJA,
AYG(P.PENSJA) AS SREDNIA,
MIN(P.PENSJA) AS PENSJA_MIN,
MAX(P.PENSJA) AS PENSJA_MAX,
COUNT(*) AS ILOSC
FROM DB2ADMIN. PRACOWNICY P
GROUP BY P.STANOWISKO
ORDER BY P.STANOWISKO;
Klauzula haying używana
jest w połączeniu z klauzulą group by w
celu ograniczenia wyświetlanych grup.
Warunek szukania musi zawierać funkcję agregującą. Po zgrupowaniu wierszy przez
klauzulę group by, klauzula haying wyświetla tylko te wiersze
spośród zgrupowanych, które spełniają warunki wyszczególnione w klauzuli haying.
Klauzula haying może
być użyta tylko wówczas, gdy w zapytaniu znajduje się klauzula group BY.
Następny przykład zapytania wyświetla wszystkich pracowników,
którzy wypożyczyli samochody na łączną jednostkową wartość powyżej 400 zł.
SELECT P.NAZWISKO, SUM (W.CENA_JEDN)
FROM DB2ADMIN.PRACOWNICY P,
DB2ADMIN.WYPOZYCZENIA W
WHERE P.NR_PRACOWNIKA
= W.NR_PRACOW_WYP
GROUP BY P.NAZWISKO;
HAVING SUM(W.CENA_JEDN)
> 400
ORDER BY P.NAZWISKO;
1. Funkcje kolumnowe mogą
być użyte tylko w klauzulach select i
having.
2. Klauzula select może zawierać tylko funkcje kolumnowe
oraz kolumny wskazane w klauzuli order
by.
3. Klauzula having może zawierać dowolne funkcje
kolumnowe operujące na dowolnych kolumnach tabeli.
Te kolumny nie musza być wyspecyfikowane w klauzuli SELECT.
W tym rozdziale zapoznamy się z klauzulą union, która pozwala na łączenie dwóch lub więcej wyników
wykonania zapytania select.
Poznamy składnię wyrażenia union, zasady dla listy w klauzuli select oraz różnice między klauzulą union i union all.
Klauzula union łączy
dwa lub więcej polecenia select w
jedną tabelę wynikową.
Klauzula select musi zwracać tę
samą liczbę kolumn.
Kolumny pokrywające się mu-szą mieć tę samą szerokość
i typ danych. Nazwy tych kolumn mogą być różne.
Klauzula UNION łączy dwa zestawy wyników w jeden i jednocześnie
usuwa duplikaty.
Poniższy rysunek ilustruje zastosowanie
klauzuli union.
Jak widać, powtarzające się wiersze na szarym tle zostały umieszczone
tylko raz w końcowym wyniku zapytania z klauzulą union.
W kolejnym przykładzie są zwracane dane o imieniu i nazwisku
wszystkich klientów i pracowników, których nazwiska kończą się na „ski".
Tylko jedna osoba o imieniu i nazwisku Jan Kowalski występuje jednocześnie w
tabeli klientów i pracowników.
SELECT IMIE, NAZWISKO
FROM DB2ADMIN.KLIENCI
WHERE
NAZWISKO LIKE '%SKI'
UNION
SELECT IMIE, NAZWISKO
FROM DB2ADMIN.
PRACOWNICY
WHERE NAZWISKO LIKE '%SKI';
Za każdym razem zapytania łączące wyniki z klauzulą union wyświetlają wyniki posortowane
rosnąco.
Jeżeli chcemy zawrzeć klauzulę ORDER BY, która posortuje nam wynik malejąco,
musi ona być umieszczona na końcu zapytania.
SELECT IMIE,
NAZWISKO
FROM DB2ADMIN.KLIENCI
WHERE
NA2WISKO LIKE '%SKI'
UNION
SELECT IMIE, NAZWISKO
FROM DB2ADMIN.PRACOWNICY
WHERE NAZWISKO LIKE '%SKI'
ORDER BY NAZWISKO DESC;
W systemie InterBase powyższe zapytanie należy zmodyfikować poprzez zastąpienie ostatniej klauzuli order by następującą:
ORDER BY 2
DESC;
InterBase nie pozwala w zapytaniach łączących wyniki na specyfikowanie nazwy kolumny w klauzuli order by.
Różnica pomiędzy klauzulą union
a union ALL polega na tym,
że wynik łączenia zapytań klauzulą union
all zawiera powtarzające się wiersze.
Klauzula union all dziafa szybciej niż union.
Tak więc, gdy łączymy kilka wyników zapytania, i gdy jesteśmy pewni, że
łączone wyniki
nie zawierają duplikatów, możemy używać klauzuli union all.
1. Wyniki zapytania select z tą samą liczbą kolumn będących
tego samego typu danych
mogą być łączone poprzez użycie klauzuli union.
2. Klauzula union sortuje dane wynikowe i usuwa
duplikaty.
3. Klauzula union all działa szybciej niż union.
4. Użyj klauzuli union all gdy jesteś pewien, że łączone wyniki nie zawierają duplikatów.
Rozdział ten opisuje używanie podzapytań.
Znajdują się tutaj informacje, jak konstruować podzapytania,
jak używać podzapytań
w klauzuli where oraz w klauzuli haying oraz jak budować podzapytania ze słowami kluczowymi in, all, any lub some.
Przypuśćmy, że musimy znaleźć pracowników, którzy otrzymują
wynagrodzenie na kwotę większą niż wynosi średnia.
Musimy najpierw sprawdzić, jaka jest średnia dla każdego pracownika.
SELECT AVG(P.PENSJA)
FROM DB2ADMIN.PRACOWNICY
P;
Wynik wynosi: 1530,00
Teraz szukamy pracowników, którzy zarabiają poniżej tej średniej:
SELECT P.IMIE,
P.NAZWISKO, P.DZIAL, P.STANOWISKO
FROM DB2ADMIN.PRACOWNICY P WHERE
P.PENSJA > 1530;
Wykonaliśmy zadanie. Znaleźliśmy pracowników, którzy zarabiają
powyżej średniej.
Ale dokonaliśmy tego w dwóch krokach za pomocą dwóch zapytań.
Teraz otrzymamy ten sam wynik, ale przy użyciu podzapytania.
SELECT P,IMIE,
P.NAZWISKO, P.DZIAL, P.STANOWISKO
FROM DB2ADMIN.PRACOWNICY P
WHERE P.PENSJA > (SELECT
AVG(P.PENSJA)
FROM DB2ADMIN.PRACOWNICY P);
Słowo kluczowe in pozwala
na zidentyfikowanie wszystkich elementów w zbiorze A które nie występują w
zbiorze B.
Zapytanie wyświetla listę samochodów, których do tej pory nie
wypożyczył żaden klient.
Zapytanie wybiera te samochody, które nie znajdują się w tabeli WYPOŻYCZENIA,
czyli te, które nie były do tej pory przedmiotem wypożyczenia.
SELECT S.NR_SAMOCHODO,
S.MARKA, S,TYP
FROM D32ADMIN.SAMOCHODY S
WHERE S.NR_SAMOCHODU
NOT
IN
(SELECT
W.NR_SAMOCHODU
FROM DB2ADMIN.WYPOZYCZENIA W);
Przykładowe
podzapytanie ze słowem any będzie wykonane w dwóch krokach.
Jako pierwsze jest wykonywane podzapytanie, które
znajduje średnią pensję w każdym dziale.
W drugim kroku, każda pensja pracownika porównywana jest z listą średnich
pensji. Wyświetleni zostaną pracownicy, których pensja jest wyższa od
wszystkich średnich pensji obliczonych w podzapytaniu.
Zapytanie z rysunku 8.5 jest wykonywane w dwóch krokach. Jako
pierwsze jest wykonywane podzapytanie, które znajduje
średnią pensję w każdym dziale. W drugim kroku, każda pensja pracownika
porównywana jest z listą średnich pensji. Ostatecznie wyświetleni zostaną
wszyscy pracownicy, których pensja jest wyższa od najmniejszej średniej pensji
obliczonej w podzapytaniu.
Musimy znaleźć działy, w których średnia pensja pracowników jest
wyższa od średniej pensji w firmie.
Do średnich pensji nie będą brani pod uwagę kierownicy działów.
Gdybyśmy musieli wykonać to zadanie „ręcznie", to
musielibyśmy przejść przez trzy kroki.
W pierwszym kroku musielibyśmy znaleźć średnią pensję w firmie, nie biorąc pod
uwagę kierowników.
SELECT AVG(P.PENSJA)
FROM DB2ADMIN.PRACOWNICY P
WHERE P.STANOWISKO <> 'KIEROWNIK’;
W drugim kroku obliczylibyśmy średnie pensje pracowników w
poszczególnych działach, nie biorąc przy tym pod uwagę kierowników.
SELECT P.DZIAL, AVG(P.PENSJA) AS SREDNIA_PENSJA
FROM DB2ADMIN.PRACOWNICY P
WHERE P.STANOWISKO <> 'KIEROWNIK'
GROUP BY P.DZIAL
ORDER BY SREDNIA_PENSJA;
Jeżeli używasz InterBase, zamień ostatni
wiersz powyższego polecenia na:
ORDER BY 2;
W trzecim kroku musielibyśmy porównać wartości średnich pensji
poszczególnych działów ze średnią pensją w firmie.
Ostatecznie wykonujemy to zadanie za pomocą pojedynczego zapytania
z podzapytaniem w klauzuli having.
SELECT P.DZIAL, AVG(P.PENSJA) AS SREDNIA_PENSJA
FROM DB2ADMIN.PRACOWNICY P
WHERE P.STANOWISKO <> 'KIEROWNIK’
GROUP
BY P.DZIAL
HAVING
AVG(P.PENSJA) > (SELECT AVG(P.PENSJA)
FROM DB2ADMIN.PRACOWNICY P
WHERE P.STANOWISKO <> 'KIEROWNIK')
ORDER BY SREDNIA_PENSJA;
1. Podzapytania muszą być otoczone
nawiasami.
2. Podzapytania nie mogą zawierać klauzuli union, union ALL lub order by.
W tym rozdziale nauczymy się tworzyć tabele i widoki. Poznamy
składnię języka SQL niezbędną do ich tworzenia.
Nauczymy się również wstawiać wiersze do tabeli, zmieniać dane w tabeli,
usuwać wiersze oraz usuwać tabele.
Na rysunku 9.1 znajdziesz wypełnioną danymi tabelę KLIENCIJTEST,
na której będziemy ćwiczyć zagadnienia poruszane w tym rozdziale.
Następujące wyrażenie create
table tworzy tabelę KLIENCI_TEST.
CREATE
TABLE DB2ADMIN.KLIENCI_TEST (
NR_KLIENTA
CHAR(8) NOT NULL,
IMIE
VARCHAR(20) NOT NULL,
NAZWISKO
VARCHAR(20) NOT NULL,
NR_KARTY_KREDYT
CHAR(20) ,
ULICA
VARCHAR(24) NOT NULL,
NUMER
CHAR(8) NOT NULL,
MIASTO
VARCHAR(24) NOT NUIi,
KOD
CHAR(6) NOT NULL,
NRJTELEFONU
CHAR
(16),
PRIMARY KEY (NR_KLIENTA)
)
;
Definiując tabelę musimy określić jej nazwę np. KLIENCI_TEST. Następnie określić kolumny dla tej tabeli.
Każda kolumna musi posiadać: unikatową nazwę w obrębie tabeli oraz typ danych,
jakie będą przechowywane w kolumnie.
Dodatkowo przy definiowaniu kolumn określić można, czy dozwolone jest
pozostawienie jej pustej;
jeżeli nie, dodajemy klauzulę not null do
definicji kolumny.
Np. kolumna NR_KARTY_ KREDYT nie jest wymagana -
podczas wstawiania nowego wiersza
- pole w tej kolumnie możemy pozostawić puste.
Może dziś (prawie) każdy posiada kartę płatniczą, ale nie każdy posiada kartę
kredytową.
Dodatkowo nie każdy klient ma życzenie płacić kartą kredytową.
Słowo kluczowe primary key określa
klucz główny dla tabeli.
Klucz główny oraz klucz obcy zostanie opisany w następnym rozdziale.
Tabelę możemy przebudować, dodając nową kolumnę lub ją usuwając,
możemy zmienić typ danych kolumny,
jak również zmienić inne cechy tabeli oraz kolumn w niej zawartych.
Do zmiany struktury tabeli służy wyrażenie SQL alter table.
Kolejne polecenie alter
table doda dwie kolumny: FIRMA oraz NIP do tabeli KLIENCI_TEST.
ALTER
TABLE DB2ADMIN.KLIENCI_TEST
ADD
FIRMA VARCHAR(40)
ADD NIP CHAR(12) ;
W InterBase kolejne wiersze ze słowem add w powyższym poleceniu należy
oddzielić
przecinkiem. Aby zapobiec błędom, musimy wykonać polecenie alter table.
Następne przykłady będą operować również na tych kolumnach.
Dane zawarte w widoku nie sąjej
fizycznymi danymi a danymi należącymi do tabeli lub kilku tabel z których widok
czerpie dane.
Widoki przede wszystkim są tworzone w celu ograniczenia dostępu do danych w
tabelach bazy danych. Do tworzenia widoków służy polecenie create view.
Poniższy przykład tworzy widok zawierający dane klientów, którzy
posiadają firmę.
CREATE
VIEW DB2ADMIN.KLIENCI_FIRMY AS
SELECT K.IMIE, K.NAZWISKO, K.FIRMA,
K.NIP, K.MIASTO
FROM
DB2ADMIN.KLIENCI K
WHERE
K.FIRMA IS NOT NULL;
Teraz możemy wybierać dane z widoku tak, jak do tej pory
wybieraliśmy dane z tabeli.
SELECT
*
FROM
DB2ADMIN.KLIENCI_FIRMY;
.
Następny przykład tworzy widok, który ogranicza dane pracowników
do wszystkich danych oprócz informacji na temat dodatku i pensji.
CREATE VIEW
DB2ADMIN.V__PRACOWNICY AS
SELECT P.NR_PRACOWNIKA,
P.IMIE, P.NAZWISKO,
P.DATA_ZATR,
P.DZIAL, P.STANOWISKO,
P.NR_MIEJSCA, P.NRJTELEFONU
FROM DB2ADMIN.PRACOWNICY P;
Aby dodać jeden lub więcej rekordów do istniejącej tabeli, należy
posłużyć się wyrażeniem SQL insert.
Aby dodać rekord do tabeli KLIENCI_TEST
zdefiniowanej w sekcji „Tworzenie tabel", napisz i wykonaj poniższe
wyrażenie SQL.
Upewnij się, że tabela KLIENCIJTEST posiada kolumny FIRMA oraz NIP, które
dodaliśmy do struktury tabeli poleceniem alter
table.
INSERT INTO DB2ADMIN.KLIENCI_TEST
VALUES ( '00000031',
'MARIUSZ', 'DOLATA', NULL, 'KOCHANOWSKIEGO’, '3',
'WROCŁAW', '37-300', '167-763-234',
'KWIATY', '2224-444-224');
Dodaj jeszcze kilka rekordów:
INSERT INTO DB2ADMIN.KLIENCI_TEST
YALUES ('00000032', 'TOMASZ', 'DOMAGAŁA’
, 'HX 145345678', 'RÓŻANA', '4/9', 'WARSZAWA’, '01-900',
'46-744-431', NULL, NULL);
INSERT INTO DB2ADMIN.KLIENCI_TEST
VALUES ('00000033', 'PAWEŁ',
'MALCZYKOWSKI' , 'HF 14565661', 'SŁONECZNA', '9', 'WARSZAWA1,
'01-900', '16-742-114', NULL, NULL);
INSERT INTO DB2ADMIN.KLIENCI_TEST
VALUES ('00000034', 'PIOTR', 'MUSZYŃSKI'
, 'DD 72325221',
'SZYBOWCOWA', '22A’,
'WARSZAWA', '01-200', '44-342-116',
'WULKANIZACJA', '4356-098-876');
INSERT INTO DB2ADMIN.KLIENCI_TEST
VALUES ('00000035', 'ANNA',
'MIKOLAJCZYK’ ,NULL , 'JAŁOWCOWA', '24',
'WROCŁAW', '37-200', '144-188-415',
'FRYZJERSTWO', '2343-112-345');
Powyższe wyrażenia dodały nowe wiersze do tabeli KLIENCI_TEST.
Każde z tych wyrażeń wypełnia
wartościami wszystkie kolumny tabeli.
Aby wstawić dane tylko do wybranych kolumn, należy je określić, a następnie
podać wartości:
INSEKT INTO DB2ADMIN. KLIENCI_TEST {NR_KLIENTA, IMIE,
NAZWISKO, ULICA, NUMER, MIASTO, KOD)
VALUES ('00000036’,
'MAGDALENA', 'BRZOZA' , 'ALEJE LIPOWE', '4/3', _ 'ŚWIDNICA, '58-100');
Powyższe polecenie insekt dodało
nowy wiersz do tabeli KLIENCI_TEST.
Wypełnione zostały wszystkie kolumny oprócz kolumny NR_KARTY_KREDYT
i kolumny TELEFON.
Wartości dla tych kolumn nie są wymagane więc wstawienie nowego wiersza
przebiegło bez błędu.
Istnieje możliwość dodania wielu wierszy za jednym razem.
Wstawienie kilku rekordów w jednym poleceniu polega na użyciu klauzuli select. Oto przykład:
INSERT INTO DB2ADMIN.KLIENCI_TEST (NR_KLIENTA, IMIE, NAZWISKO, ULICA, NUMER, MIASTO, KOD)
SELECT NR_KLIENTA,
IMIE, NAZWISKO, ULICA, NUMER, MIASTO, KOD
FROM
DB2ADMIN.KLIENCI
WHERE
FIRMA IS NULL;
Aby usunąć rekordy z tabeli, użyj polecenia delete FROM np.
DELETE
FROM DB2ADMIN.KLIENCI_TEST WHERE FIRMA IS NOT NULL;
Polecenie delete from bez
klauzuli where usuwa wszystkie
rekordy z tabeli, np.
DELETE
FROM DB2ADMIN.KLIENCI_TEST;
Polecenie update zmienia
wartości we wskazanych kolumnach tabeli dla jednego lub większej ilości
wierszy.
Poniższe polecenie update zwiększa
kwotę dodatku pracownika zatrudnionego na stanowisku sprzedawcy o 50 zł.
UPDATE DB2ADMIN.PRACOWNICY
SET DODATEK = DODATEK + 50
WHERE STANOWISKO = 'SPRZEDAWCA';
Teraz możemy sprawdzić, czy wartości dodatku dla sprzedawców
zostały zmienione:
SELECT *
FROM DB2ADMIN.PRACOWNICY
WHERE STANOWISKO = 'SPRZEDAWCA’;
Jeżeli zmieniamy wartości więcej niż jednej kolumny, muszą one być
oddzielone przecinkiem.
Poniższe polecenie zwiększa dodatek dla kierowników o 30 zł oraz zwiększa
pensje o 10%.
UPDATE DB2ADMIN.PRACOWNICY
SET DODATEK = DODATEK + 30,
PENSJA = PENSJA + (PENSJA *10) /100
WHERE STANOWISKO = 'KIEROWNIK';
Tabela KLIENCI_TEST nie będzie nam już
więcej potrzebna. Aby usunąć tabelę, musimy użyć polecenia drop table:
DROP TABLE KLIENCI TEST;
Polecenie usuwające tabelę usuwa jednocześnie wszystkie dane zawarte w tabeli oraz usuwa wszystkie widoki które czerpią dane z usuwanej tabeli.
1. Usunięcie tabeli powoduje
usunięcie danych i widoków związanych z usuwaną tabelą.
2. Możemy określić wiersze,
które mają zostać usunięte lub zmienione poprzez zamieszczenie odpowiedniego
warunku w klauzuli where.
3. Opuszczenie klauzuli where w pleceniach update lub delete powoduje, że wszystkie wiersze zostaną zmienione lub usunięte.
W tym rozdziale dowiemy się istotnych informacji o ograniczeniach,
integralności danych tabeli oraz o integralności referencyjnej.
Wszystkie te zagadnienia składają się na bezpieczeństwo i jakość danych
gromadzonych w bazie danych.
Możesz zdefiniować ograniczenie sprawdzające poprawność
wpisywanych danych do tabeli
poprzez określenie warunku sprawdzającego check.
Poniższy przykład ilustruje wyrażenie zmieniające strukturę tabeli
PRACOWNICY
poprzez dodanie ograniczenia zapobiegającego wpisaniu kwoty dodatku większej od
kwoty pensji.
ALTER TABLE DB2ADMIN.PRACOWNICY ADD
CHECK (PENSJA > DODATEK);
Jeżeli wpiszesz teraz wyrażenie dodające wiersz do tabeli
pracownicy, który będzie zawierał
w kolumnie DODATEK wartość większą niż w kolumnie PENSJA np.
INSERT INTO DB2ADMIN.PRACOWNICY
VALUES ('0011', 'JOLANTA',
'NOWAKOWSKA1, '1999-05-01', 'OBSLUGA
KLIENTA’, 'SPRZEDAWCA', 1100, 1200, '000001' , '433-451-154' ) ;
Baza DB2 wygeneruje komunikat o błędzie, który mówi o naruszeniu
ograniczenia sprawdzającego check:
DB21034E
The command was processed as an SQL statement
because
it was not a valid Comnand Linę
Processor command.
During
SQL processing it returned:
SQL0545N
The reąuested operation is not allowed because a rów
does
not satisfy the check constraint
"DB2ADMIN.PRACOWNICY.SQLQ10121215529810". SQLSTATE=23513
Każda tabela bazy danych powinna zawierać klucz główny.
Klucz główny tabeli to kolumna lub grupa kolumn, która w sposób jednoznaczny
identyfikuje wiersz w tabeli.
Na przykład, dla tabeli zawierającej dane o pracownikach kluczem głównym może
być, kolumna o nazwie NR_PRACOWNIKA,
która jednoznacznie określa danego
pracownika. Kluczem głównym może być numer telefonu
w tabeli przechowującej dane abonentów operatora telefonicznego.
Jak już wspomniałem, klucz główny może
składać się z wielu kolumn.
Przykładem takiego klucza głównego może
być kolumna NUMER oraz ROK w tabeli przechowującej dane o wystawionych
fakturach,
gdzie kolumna NUMER określa numer faktury a kolumna ROK określa rok
wystawienia.
Wartości z tych kolumn wzięte razem są różne w każdym wierszu.
Jak już wspomniałem, dla tabeli PRACOWNICY kluczem głównym może
być kolumna
NR_PRACOWN1KA. Ustalenie klucza głównego (primary
key) podczas tworzenia tabeli:
CREATE TABLE DB2ADMIN. PRACOWNICY (
NR_PRACOWNIKA
CHAR(4)NOT NULL,
IMIE
VARCHAR(20) NOT NULL,
NAZWISKO
VARCHAR(20) NOT NULL,
DATA_ZATR
DATE NOT
NULL,
DZIAL
VARCHAR(20) NOT NULL,
STANOWISKO
VARCHAR(20) NOT
NULL,
PENSJA
DECIMAL(8,2),
DODATEK
DECIMAL(8,2)
NR_MIEJSCA
CHAR(6) NOT NULL,
NRJTELEFONU
CHAR(16)
PRIMARY KEY (NR_PRACOWNIKA));
zapobiegnie wstawieniu dwóch identycznych wierszy.
W przypadku gdy dodamy drugi wiersz z danymi pracownika o numerze już
istniejącym w tabeli, DB2
wyświetli błąd z informacją o naruszeniu integralności danych.
Klucz obcy to jedna lub więcej kolumn tabeli odwołujących się do
kolumny lub kolumn klucza głównego w innej tabeli.
Klucze obce są wykorzystywane do
utrzymywania integralności referencyjnej w bazie danych.
Tworząc klucz obcy, definiujemy związek między tabelą klucza głównego i tabelą
klucza obcego.
Związek taki powstaje podczas złączania kolumn takich samych typów danych z
każdej tabeli.
Złączanie tabel przez odpowiednie
kolumny chroni dane z tabeli klucza obcego przed „osieroceniem",
jakie mogłoby nastąpić w wyniku usunięcia odpowiadających im danych z tabeli
klucza głównego.
Definiowanie kluczy obcych jest po
prostu sposobem łączenia danych przechowywanych w różnych tabelach bazy danych.
Na przykład, w tabeli PRACOWNICY widocznej na poniższym zdjęciu
kluczem obcym jest kolumna NR_MIEJSCA.
Ta kolumna czerpie wartości z tabeli MIEJSCA z kolumny NR_MIEJSCA
(klucz główny w tabeli MIEJSCA).
Gdy odczytamy numer miejsca z tabeli PRACOWNICY, możemy się odwołać do tabeli
MIEJSCA
i odczytać z niej pełny adres miejsca pracy pracownika. Rysunek 10.1 ilustruje
związek tabeli klucza obcego z tabelą klucza głównego.
Rysunek 10.1 można odczytać następująco: tabela klucza obcego
PRACOWNICY jest złączona z tabelą klucza głównego MIEJSCA
poprzez kolumny NR_M1EJSCA. Związek klucza obcego chroni wiersze z tabeli
PRACOWNICY
przed osieroceniem na wypadek usunięcia jakiegokolwiek wiersza z tabeli
MIEJSCA.
Aby zapewnić taką ochronę, musimy zdefiniować klucze obce we
wszystkich tabelach, które odwołują się do innych tabel.
Taki związek występuje m.in. w naszych przykładowych tabelach PRACOWNICY oraz
MIEJSCA.
ALTER
TABLE DB2ADMIN.PRACOWNICY
ADD
POREIGN KEY (NR_MIEJSCA)
REFERENCES MIEJSCA (NR MIEJSCA) ON
DELETE RESTRICT;
Polecenie to ustanawia klucz obcy w tabeli PRACOWNICY w kolumnie
NR_ MIEJSCA.
Czytając dalej to polecenie dowiadujemy się że kolumna ta odwołuje się do
kolumny NR_MIEJSCA w tabeli MIEJSCA.
Słowa kluczowe on delete restrict mówią,
że niemożliwe jest usunięcie wiersza z tabeli MIEJSCA,
gdy istnieje wiersz do niego się odwołujący w tabeli PRACOWNICY. Dla systemu InterBase
zamiast słowa restrict jest
honorowane słowo no action.
W tabeli 10.1 znajdują się opisy wszystkich możliwych akcji, jakie
zostaną zainicjowane w chwili usuwania wiersza w tabeli zależnej:
Tabela 10.1.
Akcja |
Opis
|
RESTRIC |
Ograniczone usuwanie, które mówi, że dopóki istnieją w tabeli PRACOWNICY wiersze odwołujące do usuwanego adresu |
lub dla InterBase |
|
NO ACTION |
nie można go usunąć. Aby usunąć dane o adresie z tabeli MIEJSCA, najpierw należy usunąć wszystkich pracowników pracujących w miejscu o którym informacje chcemy usunąć |
CASCADE |
kaskadowe usuwanie, mówi, że gdy usuwamy wiersze z tabeli MIEJSCA, to są jednocześnie usuwane wszystkie wiersze z danymi o pracownikach, którzy pracują w usuwanym miejscu |
SET NULL |
Wstaw wartość NULL, mówi, że jeśli usuwamy dane o miejscach, to w tabeli PRACOWNICY w kolumnie NR_MIEJSCA zostanie wstawiona wartość NULL |
1. Możesz zdefiniować
ograniczenie sprawdzające poprawność wpisywanych danych do tabeli
poprzez określenie warunku sprawdzającego check.
2. Integralność danych w
tabeli zachowuje się dzięki kluczom głównym.
3. Klucze obce służą do
utrzymywania integralności referencyjnej.
Podczas budowy zapytań przy bieżącej pracy z bazą danych będziemy
korzystać z zakładki lnteractive.
Aby wykonać zapytanie, musimy się upewnić, że jesteśmy podłączeni do bazy
danych, na której chcemy pracować.
Są dwa sposoby na podłączenie się do bazy danych. Jeden z nich to wpisanie
polecenia SQL:
CONNECT
TO WYPAUT USER db2admin USING db2admin;
w oknie Command na zakładce lnteractive. Po naciśnięciu kombinacji klawiszy Ctrl+Enter powyższe polecenie
zostanie wykonane i zostaniemy podłączeni do bazy danych. Zostanie to
zakomunikowane w oknie poniżej okna Command
następującym komunikatem:
--------------------
Command Entered --------------------
CONNECT
TO WYPAUT USER db2admin USING ******** •
---------------------------------------------
Database
Connection Information
Database
server = DB2/NT 7.1.0
SQL
authorization ID = DB2ADMIN
Local
database alias = WYPAUT
Oprócz tego komunikatu, w polu Database connection zobaczymy wpis informujący o aktualnym
połączeniu.
Można to zobaczyć na zdjęciu (JAKUB - DB2 - WYPAUT).
Drugi sposób podłączenia się do bazy danych polega na wybraniu z
okna Select Database
(rysunek 12.3) konkretnej bazy danych.
Okno Select Database
wywołuje się przez naciśnięcie myszką klawisza z trzema kropkami znajdującego
się po prawej stronie pola Database connection.
Teraz gdy jesteśmy podłączeni do bazy WYPAUT, możemy wydawać inne polecenia lub zapytania SQL w oknie Command.
Przed tym, jak zaczniemy pracować z ćwiczeniami musimy, po
stworzeniu bazy danych, utworzyć tabele i wypełnić je danymi.
Możemy to wykonać poprzez okno Com-mand na zakładce lnteractive lub poprzez wykonanie skryptów uprzednio
stworzonych.
Wpisywanie wszystkich poleceń tworzących tabele oraz poleceń wstawiających dane
jest zbyt czasochłonne.
Polecam wykonanie skryptów, które zostały zamieszczone na serwerze ftp
wydawnictwa.
Aby wykonać skrypt, musimy go otworzyć i uruchomić. Wybieramy w tym celu menu Script j Import... Pojawi się okno widoczne na rysunku
12.4.
W tym oknie musimy najpierw wybrać komputer, na którym znajdują
się skrypty poprzez rozwinięcie listy System name
i wybranie konkretnego systemu. Następnie przechodzimy do katalogu ze skryptami
i pojedynczo je otwieramy.
Zawartość skryptu zostanie wyświetlona w oknie Script
na zakładce Script. Zobacz poniższe zdjęcie okna Command Center.
Aby wykonać skrypt naciskamy kombinację klawiszy Ctrl+Enter lub wybieramy myszką przycisk Execute
znajdujący się pod menu głównym z lewej strony okna. Zobaczymy serię
komunikatów u dołu okna mówiącym o tym,
że wykonanie poszczególnych poleceń SQL w skrypcie zostało zakończone
pomyślnie, np.
24', '00000014', '000004',
'0005', NULL, '000001', NULL, '2000-01-24', NULL, 200, 100);
INSERT INTO DB2ADMIN.WYPOZYCZENIA
VALUES ('00000025', '00000010',
'000004', '0009', NULL, '000002', NULL, '2000-02-09', NULL, 200,
100);
1. Przykładowa baza WYPAUT
składa się z pięciu tabel: KLIENCI, PRACOWNICY, MIEJSCA, WYPOZYCZENIA i
SAMOCHODY.
2. Wszystkie te tabele są ze
sobą powiązane relacjami.
3. Skrypty
zamieszczone w tym rozdziale są dostępne
również na serwerze:
ftp://ftp.helion.com.pl/przyklady/cwsql.zip.