Rozdział    6
                                               WYKORZYSTANIE
                                                  JĘZYKA SQL


6.1. Wprowadzenie
     SQL jest językiem wysokiego poziomu do manipulowania danymi o
niewielkiej liczbie instrukcji a o dużych możliwościach. Dzięki temu
programowanie systemów użytkowych baz danych może się odbywać w
bardzo zwarty sposób. Język SQL różni się w szczegółach, w zależności
od tego z jakiego pakietu narzędziowego korzystamy. Delphi umożliwia
wykorzystywanie praktycznie każdego systemu bazy danych. W sposób
bezpośredni można używać lokalnego języka SQL dla baz danych w
standardzie dBASE i Paradox oraz języka SQL dla baz danych tworzo-
nych w systemie Borland Local InterBase Server. Język SQL dla baz
danych utworzonych w standardzie dBASE lub Paradox jest nieco
ograniczoną wersją języka w porównaniu z wersją stosowaną dla baz
danych systemu Local InterBase. Między innymi z tego powodu w tej
książce omówimy język SQL dostępny w systemie Local InterBase.
Ponadto system Local InterBase umożliwia testowanie na jednym
komputerze aplikacji, które następnie mogą być uruchamiane w środo-
wisku klient/serwer. Architektura klient/serwer polega na tym, że
serwer przetwarza dane i wykonuje zapytania do bazy danych. Nato-
miast poszczególne stacje lokalne (klienci) zlecają serwerowi do wyko-
nania pewne operacje i otrzymują gotową odpowiedź. 
     Wszystkie przykłady zawarte w tym rozdziale wykorzystują bazy
danych utworzone w systemie Local InterBase (na ogół jest to baza
danych o nazwie alternatywnej Mistrz_i zawierająca tablice zaprojekto-
wane w rozdziale 2). Większość podanych przykładów można bez ża-
dnego problemu uruchomić na bazie danych utworzonej w systemie
dBASE, używając lokalną nieco ograniczoną wersję języka SQL (w tej
książce nie będziemy podawać tych ograniczeń, są one wyszczególnione
w dokumentacji). 
     System Local InterBase Server jest wyposażony w dwa podsystemy
o nazwach Windows ISQL oraz Server Manager. Podsystem Windows
ISQL służy do interakcyjnej pracy w języku SQL, a system Server
Manager jest wykorzystywany do administrowania bazami danych na
serwerze. 
     Podsystem Windows ISQL może być używany do testowania roz-
wiązań stosowanych następnie w programach bądź też do bezpośre-
dniego pobierania informacji z bazy danych. 
     Podczas pracy w systemie Windows ISQL jest automatycznie
otwierana transakcja (patrz rozdz. 6.6) i dlatego aby zapamiętać doko-
nane zmiany w bazie danych, należy w momencie kończenia pracy na
pytanie "Commit work for database ?" odpowiedzieć Tak.
     Jak się za chwilę przekonamy, przeniesienie zaprojektowanego
zapytania w języku SQL i przetestowanego w trybie interakcyjnym do
projektu w systemie Delphi jest szalenie proste. W związku z tym
język SQL będziemy omawiać w ten sposób, że dla pierwszych tworzo-
nych konstrukcji pokażemy, w jaki sposób przetestować je w trybie
interakcyjnym, a następnie jak je wykorzystać w projekcie. Natomiast
potem będziemy omawiać wyłącznie technikę tworzenia nowych kons-
trukcji języka SQL zakładając, że Czytelnik bez trudu je przetestuje w
podsystemie Windows ISQL bądź też zastosuje w projekcie. 
     Podstawową instrukcją języka SQL jest instrukcja SELECT.
Najprostsza jej postać jest następująca:
     SELECT p1,...pn
          FROM T
          WHERE W 
gdzie p1,...pn są nazwami pól, T jest nazwą tablicy, a W wyrażeniem
logicznym zawierającym między innymi nazwy pól.
     Instrukcja SELECT jest częściowym odpowiednikiem operacji
selekcji i projekcji omówionej w rozdziale 2. Nie jest to pełna odpowied-
niość, ponieważ wyrażenie występujące w tej instrukcji może być
bardziej złożone niż w operacji selekcji. Instrukcja SELECT zostanie
dokładnie omówiona w rozdziale 6.2 oraz 6.4.
     W języku SQL występuje również operacja połączenia zdefiniowana
w rozdziale 2, która zostanie omówiona w dalszej części pracy.
Składnia instrukcji
     Do opisu składni poszczególnych instrukcji zostanie wykorzystana
następująca symbolika. Instrukcje i słowa kluczowe będą zapisywane
dużymi literami. Nawiasy <> oznaczają informację wprowadzaną przez
programistę. Nawiasy kwadratowe [] zaznaczają opcjonalną część
instrukcji, tzn. część instrukcji umieszczona wewnątrz tych nawiasów
może wystąpić lub nie.  Trzy kropki ... służą do zaznaczenia, że w tym
miejscu można umieścić kilka składowych danej instrukcji. Uwaga: w
niniejszej książce w większości przypadków będzie podawana nieco
uproszczona składnia instrukcji. 
Przykład
Składnia instrukcji SELECT jest przedstawiona poniżej:
     SELECT <klauzula>
          FROM <klauzula>
          [WHERE <klauzula>]
          [GROUP BY <klauzula>]
          [HAVING <klauzula>]
          [ORDER BY <klauzula> ;
Tworzenie bazy danych
     W systemie Local InterBase baza danych jest przechowywana w
pliku o rozszerzeniu .dba. Oznacza to, że wszystkie tablice bazy oraz
niezbędne informacje pomocnicze takie, jak na przykład sposób zain-
deksowania są przechowywane w tym pliku. Do pliku tego nie ma
bezpośredniego dostępu i wszystkie operacje na bazie danych należy
wykonywać za pośrednictwem instrukcji języka SQL. 
     Przed omówieniem sposobu tworzenia bazy danych należy wspom-
nieć o konieczności przydzieleniu hasła użytkownikowi SYSDBA.
SYSDBA to administrator systemu mający wszelkie możliwe uprawnie-
nia do operacji na tablicach bazy danych. Gdyby to był użytkownik o
innej nazwie, należałoby mu nadać oddzielnie specjalne uprawnienia.
W związku z tym we wszystkich przykładach omówionych w tej książce
będziemy zakładać, że użytkownikiem jest administrator systemu o
nazwie SYSDBA. 
     Przydzielenie hasła użytkownikowi SYSDBA dokonuje się w nastę-
pujący sposób.
1. Uruchomić system Server Manager i wybrać opcję File/Server Login
(dla użytkownika SYSDBA pierwotnym hasłem jest "masterkey").
2. Wykonać opcję Tasks/User Security
3. Wybrać użytkownika o nazwie SYSDBA i nacisnąć przycisk Modify
User.
4. W wierszu Password podać hasło.
5. W wierszu Confirm Password podać to samo hasło.
6. Dwa razy w dwóch kolejnych oknach nacisnąć przycisk OK.
Uwaga: jeżeli hasłem podanym w punkcie 4 będzie na przykład mała
litera "a", to na pytanie o hasło we wszystkich następnych przykładach
należy podawać właśnie tę literę.
     Mając przydzielone hasło dla użytkownika SYSDBA, możemy już
przystąpić do omówienia sposobu tworzenia nowej bazy danych w
systemie Windows ISQL. Z menu File wybieramy podmenu Create
Database i w wierszu Database podajemy nazwę pliku (o rozszerzeniu
.dba), w którym będzie przechowywana baza danych wraz z pełną
ścieżką dostępu. Jako nazwę użytkownika podajemy SYSDBA, co
oznacza, że jest to administrator systemu mający wszelkie uprawnienia
do otwierania baz danych. W wierszu Password podajemy hasło nada-
ne wcześniej użytkownikowi SYSDBA. Podanie hasła będzie zawsze
konieczne przy otwieraniu tej bazy danych przez użytkownika SYS-
DBA. Tworzenie bazy danych c:\delph_ba\mistrz_i\mistrz.dba jest
zilustrowane na rys. 6.1. 

Formularz zamieszczony jest w książce

Rys. 6.1. Tworzenie bazy danych

    Po utworzeniu bazy danych jest bardzo wskazane nadanie jej
nazwy alternatywnej. Dokonuje się tego przy pomocy systemu BDE
Administrator w sposób omówiony w rozdziale 3. Dla przypomnienia
zilustrujmy przy pomocy rys. 6.2 nadanie nazwy alternatywnej
Mistrz_i dla bazy danych przechowywanej w pliku mistrz. dba, który
znajduje się w katalogu c:\delph_ba\mistrz_i.

Formularz zamieszczony jest w książce

Rys. 6.2. Nadawanie nazw alternatywnych
Tworzenie tablic
Nowe tablice dla utworzonej bazy danych można definiować na dwa
sposoby. Po pierwsze wykorzystując system Database Desktop i proje-
ktując strukturę tablicy w sposób podany w rozdziale 3. Przedstawia to
rys. 6.3, gdzie widać również, jakiego typu mogą być poszczególne pola.
Niestety po zaprojektowaniu struktury tablicy nie jest możliwa jej
późniejsza modyfikacja przy pomocy systemu Database Desktop.
Formularz zamieszczony jest w książce
Rys. 6.3. Tworzenie nowej tablicy
     Nową tablicę możemy również utworzyć przy pomocy instrukcji
języka SQL o następującej składni:
     CREATE TABLE <nazwa tablicy> 
          ( <nazwa kolumny> <typ danych>
          [, <nazwa kolumny> <typ danych> ... ]);
Powyższa instrukcja tworzy nową tablicę o zdefiniowanej nazwie i
zadanych kolumnach. Nazwa tablicy musi być unikalna w danej bazie
danych. Każda kolumna tablicy musi mieć jeden określony typ.
     Zatrzymamy się teraz przez chwilę na sposobach wykonywania
instrukcji języka SQL. Jak już wiemy, instrukcję taką można wykonać
w sposób interakcyjny w systemie Windows ISQL, co ilustruje rys. 6.4.
Ponadto każdą instrukcję języka SQL można wykonać w aplikacji
zaprojektowanej w systemie Delphi, wykorzystując komponent klasy
TQuery. Dokonuje się tego w następujący sposób. Umieszczamy na
formularzu komponent klasy TQuery i we własności SQL zapisujemy
odpowiednią instrukcję języka SQL. Uwaga: w przypadku gdy w
wyniku wykonania instrukcji nie jest wyprowadzana żadna informacja,
własność Active powinna być ustawiona na False. Wykonanie zaprojek-
towanej instrukcji języka SQL następuje w wyniku wykonania metody:
     Query1.ExecSQL;
Jak już raz podkreślaliśmy, w tym przypadku nie jest wyprowadzana
żadna informacja. Natomiast jeżeli w wyniku wykonania instrukcji
SQL wyprowadzamy pewną informację, to należy zastosować metodę

Open w następujący sposób:
     Query1.Open;
lub też ustawić własność Active na True. 
     Wykorzystaniem metody Open zajmiemy się nieco później, nato-
miast teraz proponujemy przeanalizowanie poniższych dwóch przykła-
dów, ilustrujących różne sposoby wykonania instrukcji języka SQL.
 
Formularz zamieszczony jest w książce
Rys. 6.4. Wykonanie instrukcji w systemie ISQL
Przykład
W celu utworzenia tablicy Test1 należy wykonać instrukcję:
     CREATE TABLE Test1 ( aaa CHAR(10), bbb CHAR(10) );
Powyższą instrukcję wykonujemy w oknie systemu Windows ISQL
widocznym na rys. 6.4. Tablica Test1 zostanie utworzona w bazie
danych, która została otwarta w momencie rozpoczynania pracy z
systemem Windows ISQL (do otworzenia bazy danych służy opcja File/
Connect to Database - należy podać pełną nazwę bazy danych wraz ze
ścieżką dostępu a nie nazwę alternatywną).
Przykład
W tym przykładzie instrukcję CREATE TABLE wykonamy w aplikacji
napisanej przy pomocy systemu Delphi. Na wstępie należy na formula-
rzu umieścić komponent klasy TQuery, co ilustruje rys. 6.5.

Formularz zamieszczony jest w książce

Rys. 6.5. Komponent Query1
Zwróćmy uwagę, że we własności DatabaseName podajemy nazwę
wykorzystywanej bazy danych. W naszym przypadku niech to będzie
baza o nazwie alternatywnej Mistrz_i (jest to baza danych, na której
jest oparta większość przykładów zamieszczonych w tym rozdziale). 
Następnie w oknie pojawiającym się po naciśnięciu klawisza myszki na
trzech kropkach umieszczonych w wierszu SQL okienka własności
wpisujemy odpowiednią instrukcję języka SQL, co ilustruje rys. 6.6.
Pozostaje nam jeszcze zaprojektowanie przycisku o nazwie na przykład
Utworz, po naciśnięciu którego będzie możliwe wykonanie zaprojekto-
wanej instrukcji języka SQL.

Formularz zamieszczony jest w książce

Rys. 6.6. Zaprojektowanie instrukcji języka SQL
Odpowiednia metoda powinna mieć postać:
procedure TForm1.UtworzClick(Sender: TObject);
begin
   Query1.ExecSQL;
end;
     Warto teraz sprawdzić działanie zaprojektowanej aplikacji. Po
naciśnięciu klawisza myszki na przycisku Utworz pojawia się okienko,
w którym podajemy hasło dostępu do bazy danych Mistrz_i. Natomiast
próba powtórnego naciśnięcia klawisza myszki na przycisku Utworz
zakończy się niepowodzeniem, ponieważ tablica Test1 została już
utworzona wcześniej.
     Warto jeszcze sprawdzić, czy tablica Test1 faktycznie powstała. W
tym celu należy uruchomić system Database Desktop i po otwarciu
bazy Mistrz_i obejrzeć strukturę tablicy Test1.
     Należy jeszcze raz podkreślić, że tablicę można utworzyć przy
pomocy systemu Database Desktop, co ilustruje rys. 6.3. Modyfikację
struktury już istniejącej tablicy można wykonać jedynie programowo
przy pomocy instrukcji 
ALTER TABLE <nazwa tablicy>
     ADD <nazwa kolumny> <typ danych>
     [,<nazwa kolumny> <typ danych> ...],
     DROP <nazwa kolumny> ;
Przykład
ALTER TABLE Ilosc
   ADD mistrz CHAR(15),
   DROP nr_mistrz;
     Do tablicy Ilosc zostanie dodana kolumna o nazwie mistrz, a
usunięta kolumna o nazwie nr_mistrz.
Uwaga: zakładamy, że Czytelnik po przeanalizowaniu poprzednich
przykładów bez problemu uruchomi tę instrukcję w systemie Windows
ISQL lub też wykona ją w projekcie napisanym z wykorzystaniem
systemu Delphi.
     Tablicę, która nie jest już potrzebna, można usunąć przy pomocy
instrukcji DROP TABLE:
     DROP TABLE <nazwa tablicy>;
Przykład
DROP TABLE Test1;
     Zostanie usunięta tablica Test1 z bazy danych, którą wcześniej
należy otworzyć. Przypomnijmy jeszcze raz, że jeżeli wykonujemy
instrukcję w systemie Windows ISQL, to jest to baza danych, którą
wybierzemy po wykonaniu opcji File/Connect to Database, a jeżeli
wykorzystujemy system Delphi, to baza danych powinna być określona
we własności DatabaseName (patrz rys. 6.5).
Operacje na tablicach
     Dane do tablicy można wprowadzać na wiele sposobów. Przede
wszystkim dokonuje się tego w aplikacjach w sposób, który zostanie
omówiony w następnych punktach. Można też do tego celu wykorzystać
system Database Desktop, chociaż ten sposób wprowadzania danych
stosuje się raczej w fazie projektowania aplikacji. Ostatnia możliwość
to użycie instrukcji języka SQL INSERT INTO o składni, której naj-
prostsza postać jest podana poniżej:
     INSERT INTO <nazwa tablicy>
          [(lista kolumn)]
          VALUES (<lista wartości>);
Lista kolumn nie musi występować, podane wartości są wtedy wprowa-
dzane do wszystkich kolumn w kolejności ich występowania w tablicy.
Przykład
Do wprowadzenia kolejnego wiersza do tablicy Ilosc wykorzystujemy
instrukcję:
INSERT INTO Ilosc
   VALUES ( 1,2,"deski",20 );
     W celu wprowadzenia danych do istniejącego wiersza tablicy
używamy instrukcję:
     INSERT INTO <nazwa tablicy>
          [(<lista kolumn>)]
          <instrukcja SELECT>;
Przykład
Wprowadzenie wierszy z tablicy Ilosc_1 do tablicy Ilosc spełniających
warunek material = 'deski' odbywa się przy pomocy instrukcji:
INSERT INTO Ilosc
     SELECT *
     FROM Ilosc_1
     WHERE material = "deski";
     Zastosowana w przykładzie instrukcja SELECT w połączeniu z
instrukcją INSERT powoduje dodanie do tablicy Ilosc wierszy tablicy
Ilosc_1 spełniających podany warunek (instrukcja SELECT jest omó-
wiona dokładnie w następnym rozdziale).
     Do zmiany zawartości jednego lub kilku wierszy tablicy służy ins-
trukcja:
     UPDATE  <nazwa tablicy>/ <nazwa perspektywy>
          SET <nazwa kolumny> = <wyrażenie>
          [,<nazwa kolumny> = <wyrażenie> ...]
          [ WHERE <warunek>];
Przykład
UPDATE Ilosc
   SET ilosc = 100
   WHERE nr_mag = 23;
     Powyższa instrukcja zmienia zawartość kolumny ilosc na 100 w
wierszu, w którym wartość kolumny nr_mag jest równa 23. 
     Usuwanie danych z tablic odbywa się za pomocą instrukcji DE-
LETE o składni: 
     DELETE FROM <nazwa tablicy>
          WHERE <warunek>;
Przykład
       DELETE FROM Ilosc
          WHERE material = "okna"; 
       
          Zostaną usunięte wszystkie wiersze tablicy, w których zawartość
     kolumny material ma wartość "okna". 
          
Przykład
     DELETE FROM Ilosc;
     
          Usunięte zostaną wszystkie wiersze tablicy Ilosc !!!
         
     Perspektywy
          Perspektywy są to tablice wirtualne tzn. takie, które fizycznie w
     pamięci nie istnieją i służą tylko do innej organizacji już istniejących
     tablic. Perspektywa może zawierać kombinacje wierszy i kolumn
     wybranych z jednej lub kilku tablic. Może być wykorzystywana do
     wybrania i wyprowadzenia żądanych informacji analogicznie jak dla
     tablic. Przy pomocy perspektywy można również wprowadzać i aktuali-     
     zować informację wtedy, gdy perspektywa powstała z kolumn poje-     
     dynczej tablicy. Perspektywę tworzy się przy pomocy instrukcji:
          CREATE VIEW <nazwa perspektywy> [(<lista kolumn>)]
               AS < podinstrukcja SELECT >
               [ WITH CHECK OPTION ]
     <lista kolumn> podaje nazwy kolumn, które mają wystąpić w tworzo-     
     nej perspektywie. Jeżeli opcja ta nie wystąpi, perspektywa będzie
     zawierała nazwy kolumn wyszczególnione w instrukcji SELECT.
     Podanie nazw kolumn jest konieczne w przypadku, gdy pewna kolum-
     
     na jest otrzymana w wyniku działania wyrażenia.
          Druga część instrukcji CREATE VIEW zawiera instrukcję SELECT 
     definiującą  wiersze i kolumny z wyróżnionej tablicy, które będą
     zawarte w perspektywie.  Opcja WITH CHECK OPTION jest wyko-     
     rzystywana wtedy, gdy chcemy, aby każdy wiersz umieszczony w
     perspektywie spełniał warunek wyszczególniony w opcji WHERE ins-     
     trukcji SELECT.
     
     Przykład
     CREATE VIEW Pl
        AS SELECT material, ilosc
        FROM Ilosc
        WHERE material = 'szyby';
     
          Zostanie utworzona perspektywa o nazwie Pl zawierająca kolumny
     material, ilosc z tablicy Ilosc i wiersze, dla których material = 'szyby'.  
     Zawartość perspektywy Pl można wyprowadzić przy pomocy instrukcji:
          SELECT *FROM Pl;
     
     Należy podkreślić, że przy każdej aktualizacji tablicy Ilosc zostanie
     również zaktualizowana perspektywa Pl. 
    
               Do usunięcia zbędnej perspektywy wykorzystuje się instrukcję
     DROP VIEW.
     
     Przykład
     DROP VIEW Mag;
     
          Zostanie usunięta perspektywa Mag. 
    
     Indeksowanie
          Podstawowym sposobem uporządkowania danych w tablicy w celu
     zapewnienia szybkiego dostępu do poszczególnych danych jest zainde-     
     ksowanie tablicy. Indeksowanie polega na zapamiętaniu wymaganej
     kolejności danych. Przy indeksowaniu pierwotne dane nie są zatem
     zamieniane miejscami, co umożliwia szybszy dostęp do żądanych
     danych. Tablice indeksowe są wykorzystywane przy wyprowadzaniu
     informacji za pomocą instrukcji SELECT. Jest wtedy automatycznie
     wybierany spośród zdefiniowanych indeksów ten, który jest najbardziej
     efektywny.
          Indeksowanie tablicy można wykonać w systemie Database Desk-     
     top w momencie projektowania struktury tablicy, co ilustruje rys. 6.7. 
     
 
     Formularz zamieszczony jest w książce
     Rys. 6.7. Zaprojektowanie zaindeksowania tablicy w systemie Database Desktop     
     
          Można również zaindeksować tablicę wykorzystując instrukcję
     CREATE INDEX o składni:
          CREATE [UNIQUE] [ASC/DESC] INDEX <nazwa indeksu>
               ON <nazwa tablicy> (<nazwa kolumny> 
               [,<nazwa kolumny> [ASC/DESC] ...]);
     Nazwy kolumn są tak zwanymi kluczami indeksowymi. Opcja UNIQUE oznacza, 
     że wyspecyfikowana kolumna indeksowa w każdym wierszu tablicy zawiera 
     unikalną wartość. Warunek ten będzie zachowany zarówno przy aktualizacji 
     wierszy tablicy jak i przy dołączaniu nowych wierszy do tablicy.
          Opcje ASC/ DESC (niemalejąco/nierosnąco) podają kolejność upo-     
     rządkowania danych. Z domniemania jest przyjmowana opcja ASC.
          Należy zwrócić uwagę na fakt, że opcja UNIQUE powinna być sto-     
     sowana z rozwagą, ponieważ wymaga przy wstawianiu lub aktualizacji
     danych sprawdzenia każdego wiersza, co znacznie zwalnia szybkość
     aktualizacji danych. 
     
     Przykład
     CREATE UNIQUE INDEX C_in ON Cena (material);
     
          W tablicy indeksowej C_in będzie podana kolejność uporządkowa-     
     nia wierszy tablicy Cena według kolejności alfabetycznej materiałów
     umieszczonych w kolumnie o nazwie material.
     
     Usunięcie indeksu następuje w wyniku wykonania instrukcji: 
          DROP INDEX <nazwa indeksu>;.
     
     6.2. Zapytania w języku SQL
     
     Instrukcja SELECT
          Instrukcją wykorzystywaną do wyprowadzania informacji umiesz-     
     czonych w tablicach języka SQL jest instrukcja SELECT o składni
     (zostały podane najczęściej stosowane opcje):
          SELECT <klauzula>
               FROM <klauzula>
               [WHERE <klauzula>]
               [GROUP BY <klauzula>]
               [HAVING <klauzula>]
               [ORDER BY <klauzula> 
          Obecnie omówimy wszystkie postacie instrukcji SELECT, poczyna-     
     jąc od najprostszej, która powoduje wyprowadzenie wyspecyfikowanych
     kolumn pojedynczej tablicy. Postać ta jest następująca:
          SELECT <kolumny> 
               FROM <tablica>;
     
     Przykład
     SELECT material,ilosc
        FROM Ilosc;
     
          Z tablicy Ilosc zostaną wyprowadzone zawartości kolumn, material
     oraz ilosc.
     
          Jak już wiemy, instrukcje języka SQL możemy wykonywać w oknie
     systemu Windows ISQL lub też w aplikacji zaprojektowanej z wykorzy-     
     staniem systemu Delphi. Omówimy teraz dokładnie ten drugi przypa-     
     dek, ponieważ różni się on od opisywanej wcześniej techniki wykony-     
     wania instrukcji SQL nie wyprowadzającej żądanej informacji. Chodzi
     bowiem o to, że instrukcja SELECT wyprowadza pewne wartości i w
     związku z tym należy wykonać metodę Open, a nie metodę ExecSQL.
     Ponadto dane wyprowadzamy przy pomocy komponentu klasy
     TDBGrid za pośrednictwem komponentu klasy TDataSource. Ilustruje
     to poniższy przykład.
     
     Przykład
     Pokażemy teraz jak wykonać instrukcję SELECT z poprzedniego
     przykładu w aplikacji napisanej z wykorzystaniem systemu Delphi
     (projekt Ilustr1.dpr zawarty w katalogu ROZ_6). Na wstępie na formu-     
     larzu umieszczamy cztery komponenty odpowiednio klasy TQuery,
     TDataSource, TDBNavigator oraz TDBGrid z tym, że trzy pierwsze
     mogą być umieszczone na panelu. Dla komponentu DataSource1
     własność DataSet ustawiamy na Query1, a dla komponentu DBNavigator1 
     oraz DBGrid1 własność DataSource ustalamy na DataSource1.
     Dla komponentu Query1 musimy zdefiniować trzy własności, a miano-     
     wicie DatabaseName jako Mistrz_i (alternatywna nazwa wykorzys-     
     tywanej baza danych), Active jako True (można też nie zmieniać usta-     
     wienia własności Active, ale wtedy należy wykonać metodę Query1.Op-     
     en najlepiej przy otwieraniu formularza). Natomiast w specjalnym
     oknie pojawiającym się po naciśnięciu klawisza myszki na dwóch
     kropkach umieszczonych w wierszu SQL wpisujemy instrukcję języka
     SQL. Rys. 6.8 pokazuje zaprojektowany formularz, gdzie aktywnym
     komponentem jest Query1, a na rys. 6.9 jest widoczne okno, w którym
     można zapisać instrukcję języka SQL.
     Formularz można obejrzeć w projekcie aplikacji
     Rys. 6.8. Zaprojektowany formularz z aktywnym komponentem Query1
     Formularz można obejrzeć w projekcie aplikacji
     Rys. 6.9. Okno do zapisywania instrukcji SQL
          Obecnie trzeba koniecznie  uruchomić  zaprojektowaną aplikację i
     sprawdzić jej zachowanie. Otóż jak widać, można oglądać wszystkie
     wiersze tablicy wynikowej, ale nie można przeprowadzać ich aktualiza-     
     cji. Nie można też dodawać ani usuwać rekordów. Aby było to możliwe,
     należy własność RequestLive ustawić na True. Wtedy wszystkie opera-     
     cje zmieniające zawartość tablicy wynikowej będą wykonalne.
     
          W powyższym przykładzie odpowiednie ustawienie własności
     RequestLive spowodowało, że tablica wynikowa mogła być edytowana.
     Ale uwaga, to nie jest zawsze możliwe dla dowolnej tablicy wynikowej.
     Nie będziemy w tej chwili dokładnie wyszczególniać wszystkich przy-     
     padków, dla których ustawienie własności RequestLive na True nie
     umożliwi edycji tablicy. A przypadków tych jest dużo, ponieważ w
     wyniku wykonania instrukcji SELECT bardzo często tablica wynikowa
     ma zupełnie inną strukturę niż tablica czy też tablice pierwotne. Warto
     tylko wiedzieć, że istnieje własność CanModify dostępna tylko z pozio-     
     mu programu sygnalizująca możliwość edycji tablicy wynikowej. Jeżeli
     własność ta ma wartość True, to edycja jest dostępna. A tak w ogóle, to
     do przeprowadzania edycji tablic znacznie wygodniejszy jest kompo-     
     nent klasy TTable i on głównie powinien być wykorzystywany do tego
     celu. Natomiast komponent klasy TQuery jest niezastąpiony do wypro-     
     wadzania różnych informacji z bazy danych.
          Warto jeszcze wiedzieć o innej możliwości określania instrukcji
     SQL w aplikacjach projektowanych w systemie Delphi. Otóż własność
     SQL komponentu klasy TQuery może być ustawiana nie tylko w spe-     
     cjalnym oknie widocznym na rys. 6.9, ale również w programach przy
     pomocy metody Add umożliwiającej dopisanie informacji do tekstu
     zapamiętanego we własności SQL. W tym celu należy wykonać nastę-     
     pujące instrukcje. 
     Query1.Close;     { zamknięcie komponentu }
     Query1.SQL.Clear; { wykasowanie poprzedniej instrukcji
                        języka SQL }
     Query1.SQL.Add('instrukcja języka SQL');  { wpisanie
                                               instrukcji }
     Query1.Open;      { uaktywnienie komponentu }
          
     Przykład
     Do aplikacji Ilustr1.dpr omówionej w poprzednim przykładzie należy
     dodać przycisk o nazwie Zmien. Metoda wykonywana po naciśnięciu
     klawisza myszki na tym przycisku ma postać.
     procedure TForm1.ZmienClick(Sender: TObject);
     begin
        Query1.Close;
        Query1.SQL.Clear;
        Query1.SQL.Add('SELECT nr_mistrz, mistrz FROM
        Wydzial');
        Query1.Open;
     end;
     
          Jak widać, podczas działania tej metody następuje wykonanie
     zupełnie nowej instrukcji języka SQL niż zdefiniowanej w trakcie
     projektowania aplikacji. 
    
          Jeżeli mają być wyprowadzane wszystkie kolumny tablicy, wów-     
     czas w instrukcji SELECT należy podać znak gwiazdki. Wtedy zawar-     
     tości kolumn będą wyprowadzane w kolejności umieszczenia w tablicy.
     
     Przykład
     SELECT *
        FROM Ilosc;
     
          Zostaną wyprowadzone wszystkie kolumny tablicy Ilosc: nr_mag,
     nr_mistrz, material i ilosc (jeżeli chcemy instrukcję SELECT wykonać
     w aplikacji to postępujemy analogicznie jak w poprzednim przykła-     
     dzie). 
    
          Dla wyprowadzenia tylko różnych wierszy tablicy należy zastoso-     
     wać opcję DISTINCT.
            
     Przykład
     SELECT DISTINCT *
        FROM Ilosc;
     
          Zostaną wyprowadzone wszystkie różne wiersze tablicy Ilosc.
    
          Podstawowa postać instrukcji SELECT jest następująca:
          SELECT <kolumny>
               FROM <tablice>
               WHERE <warunek>;
     Powyższa instrukcja umożliwia wyprowadzenie zawartości określonych
     kolumn zdefiniowanych tablic i tylko tych wierszy, które spełniają
     warunek podany w opcji WHERE.
     
     Przykład
     SELECT material, ilosc
        FROM Ilosc
        WHERE material = "szyby";
     
          Jeżeli zawartością tablicy Ilosc są wiersze widoczne na rys. 6.10 
     (wyprowadzone z aplikacji Mistrz.dpr omówionej później), to w wyniku
     wykonania podanej wyżej instrukcji SELECT zostaną wyselekcjonowane te 
     wiersze, dla których w kolumnie material jest umieszczona nazwa "szyby". 
     Ponadto zostaną wyprowadzone tylko zawartości kolumn material, ilosc, 
     co widać na rys. 6.11 (instrukcja SELECT została wykonana w systemie 
     Windows ISQL).
 
     Formularz można obejrzeć uruchamiając aaplikację
     Rys. 6.10. Tablica Ilosc
 
     Formularz można obejrzeć uruchamiając aplikację
     Rys. 6.11. Wynik wykonania instrukcji SELECT
          Warto zaznaczyć, że kolumny wyszczególnione w instrukcji SE-     
     LECT mogą pochodzić z różnych tablic. Przykłady ilustrujące taką
     sytuację są zamieszczone w dalszej części książki.
          Operatory, które mogą być wykorzystywane w opcji WHERE,
     zawiera poniższa tabela (porównywane wartości muszą być zgodnych
     typów): 
     
     dalszy ciąg rozdziału znajduje się w książce