Bazy danych 4. Przykłady SQL podstawy P. F. Góra http://th-www.if.uj.edu.pl/zfs/gora/ 2011/12
Przykład I Przedsiębiorca tworzy bazę danych pracowników na potrzeby wypłacania im wynagrodzeń i przekazywania zaliczek do Urzędu Skarbowego. Zachodza następujace zależności funkcyjne: PracId Stanowisko Stanowisko Stawka PracId StażPracy StażPracy Stawka Wynagrodzenie PracId Gmina Gmina UrzadSkarbowy (1a) (1b) (1c) (1d) (1e) (1f) Copyright c 2010-11 P. F. Góra 4 2
1. Udowodnić, że PracId Wynagrodzenie PracId Stanowisko Stanowisko Stawka = PracId Stawka (2a) PracId Stawka PracId StażPracy = PracId StażPracy Stawka (2b) PracId StażPracy Stawka StażPracy Stawka Wynagrodzenie = PracId Wynagrodzenie (2c) 2. Spróbujmy zaprojektować taka oto tabelę: Pracownik (PracId, StażPracy, Stanowisko, Stawka, Gmina) (3) Tabela (??) nie jest w 3PN, gdyż zawiera relację przechodnia (do atrybutu nie będacego częścia klucza). Ponieważ stawka przyporzadkowana jest stanowisku, nie zaś konkretnemu pracownikowi, wpisywanie stawek jak w (??) prowadzi do redundancji i anomalii modyfikacji. Copyright c 2010-11 P. F. Góra 4 3
3. Następujacy projekt jest w 3PN, a nawet w PNBC Pracownicy (PracId, StażPracy, Stanowisko, Gmina) Stanowiska (Stanowisko, Stawka) Płace ( StażPracy, Stawka, Wynagrodzenie ) Urzędy (Gmina, UrzadSkarbowy) (4a) (4b) (4c) (4d) 4. W opraciu o projekt (??), w języku algebry relacji sformułować zapytanie o wynagrodzenie konkretnego pracownika ρ T1 ( πstanowisko,stażpracy,wynagrodzenie (Stanowiska Płace) π PracId,Wynagrodzenie (T 1 Pracownicy) Sa inne możliwe ścieżki wykonania tego zapytania. ) (5a) (5b) Copyright c 2010-11 P. F. Góra 4 4
Przykład II Kancelaria adwokacka prowadzi bazę czynności adwokackich. Każda czynność wykonana jest przez pracownika na jakimś stanowisku; ze stanowiskiem zwia- zana jest stawka. Każda czynność wykonana jest na rzecz pewnego klienta. Cena, jaka płaci klient, zależy od czasu trwania czynności adwokackiej i stawki, jaka pobiera pracownik kancelarii. Zależności funkcyjne: PracId Stanowisko Stanowisko Stawka Czynność Pracownik KlientId Czas Czas Stawka Koszt KlientId NazwaKlienta (6a) (6b) (6c) (6d) (6e) Copyright c 2010-11 P. F. Góra 4 5
Tabele: Czynności ( Czynność, PracId, KlientId, Czas ) Pracownicy (PracId, Stanowisko) Stanowiska (Stanowisko, Stawka) Opłaty (Czas, Stawka, Koszt) Kilenci (KlientId, NazwaKlienta) (7a) (7b) (7c) (7d) (7e) Mimo iż po zdefiniowaniu osobnych tabel Pracownicy i Stanowiska tabel jest więcej, łacznie przechowujemy mniej informacji. Copyright c 2010-11 P. F. Góra 4 6
Przykład III Tworzymy bazę opisujac a zaliczenia, jakie studenci uzyskiwali ze swoich projektów. Jeden student może podchodzić do tego samego projektu wiele razy (może poprawiać ocenę). Jednego dnia jeden student może starać się tylko o jedno zaliczenie. NrZaliczenia NrIndeksu NrProjektu Data Ocena NrIndeksu Data NrZaliczenia (8a) (8b) Wydaje się, że projekt Zaliczenia (NrZaliczenia, NrIndeksu, Data, NrProjektu, Ocena) (9) nie jest poprawny, gdyż nie uwzględnia drugiej z zależności (??). Copyright c 2010-11 P. F. Góra 4 7
Projekt Zaliczenia (NrZaliczenia, NrIndeksu, Data, NrProjektu, Ocena) (10) nie jest poprawny, gdyż zawiera zależności przechodnie: NrIndeksu Data NrZaliczenia NrProjektu Ocena, a zatem nie jest w 3PN (ustaliliśmy, że NrZaliczenia nie może być kluczem!). Copyright c 2010-11 P. F. Góra 4 8
Rozbijmy pierwsza z zależności funkcyjnych (??)na dwie części: NrZaliczenia NrProjektu Ocena NrZaliczenia NrIndeksu Data NrIndeksu Data NrZaliczenia (11a) (11b) (11c) Zależności (??), (??) sa swoimi odwrotnościami, a zatem jedna z nich można wyeliminować. Projekt KtoKiedy (NrIndeksu, Data, NrZaliczenia) CoZaCo (NrZaliczenia, NrProjektu, Ocena) (12a) (12b) jest w PNBC. Ta analiza pokazuje, że projekt (??) tak naprawdę jest poprawny. Copyright c 2010-11 P. F. Góra 4 9
Przykład IV Fabryka w magazynie przechowuje części różnego typu (śrubki i nakrętki). Każda część ma swój unikalny identyfikator. W magazynie każdy pojemnik ( regał ) zawiera identyczne części. Mamy relacje funkcyjne NrRegału IdCzęści Ilość (13a) Śrubki: IdCzęści Długość Średnica TypŁba (13b) Nakrętki: IdCzęści Średnica (13c) Projekty odpowiednich tabel sa (pozornie) oczywiste. Copyright c 2010-11 P. F. Góra 4 10
Niektóre zapytania bardzo wykonać jest bardzo łatwo, na przykład wskaż regały, w których znajduja się śrubki o długości 3/4": π NrRegału ( πidczęści ( σdługość=3/4" Śrubki ) Regały ) (14) Inne zapytania sa bardziej problematyczne na przykład jaki typ łba maja śrubki przechowywane na regale 58 (( π TypŁba σnrregału=58 Regały ) Śrubki ) (15) To zapytanie powinno zadziałać dobrze: Jeśli części przechowywane na regale 58 sa śrubkami, wszystko jest OK. Jeśli części przechowywane na regale 58 nie sa śrubkami (tylko nakrętkami), złaczenie w (??) da zbiór pusty, a więc także OK pod warunkiem, że nie przypiszemy tego samego IdCzęści śrubkom i nakrętkom, a takiego więzu w naszym projekcie nie ma. Copyright c 2010-11 P. F. Góra 4 11
Problem można częściowo rozwiazać modyfikujac tabelę Regały: NrRegału IdCzęści RodzajCzęści Ilość (16) Wówczas możliwe jest sprawdzenie na których regałach znajduja się śrubki ) (σ Regały RodzajCzęści= Śrubki (17) ρ RegałyŚrubek i dalej π TypŁba (( σnrregału=58 RegałyŚrubek ) Śrubki ) (18) Jeśli na regale 58 nie ma śrubek, dostaniemy zbiór pusty. Copyright c 2010-11 P. F. Góra 4 12
W relacyjnym modelu danych nie ma rekordów z wariantami, zanych z niektórych języków programowania. Prawdziwym rozwiazaniem byłoby przekonanie zleceniodawcy, że stosowanie jednolitej numeracji do różnego rodzaju części nie jest rozsadne. Jeżeli nie da się zleceniodawcy do tego przekonać a zleceniodawca może mieć uzasadnione powody aby protestować najlepszym rozwiazaniem jest zsumowanie zależności (??), (??), które maja ten sam poprzednik: NrRegału IdCzęści Ilość IdCzęści Długość Średnica TypŁba (19a) (19b) Atrybut Średnica występuje w następnikach dwa razy, więc po zsumowaniu pojawia się tylko raz. Teraz należy rozumieć, że jeżeli atrybuty Długość, TypŁba przyjmuja wartość null, mamy do czynienia z nakrętka, w przeciwnym zaś razie ze śrubka. Copyright c 2010-11 P. F. Góra 4 13
Zgodnie z zasadami sztuki, funkcja określajaca czy dana część jest śrubka, czy nakrętka, powinna być wbudowana w bazę danych (jako tak zwana procedura składowana). Podobnie w bazie powinien znaleźć się więz domenowy (check) stwierdzajacy, że atrybuty Długość, TypŁba musza być jednocześnie null lub not null. Atrybut Średnica powinien być zawsze not null. Copyright c 2010-11 P. F. Góra 4 14
Przykład V (kolejowy) Tworzymy bazę danych zawierajac a (uproszczony) rozkład jazdy pociagów oraz informacje o sprzedanych biletach. Po pierwsze, Z każdym pociagiem stowarzyszona jest lista stacji, na których się on zatrzymuje. Z każda stacja stowarzyszony jest zbiór pociagów, na których się on zatrzymuje. Dla każdej stacji należy podać godziny przyjazdu i odjazdu każdego pocia- gu, który się na niej zatrzymuje. Copyright c 2010-11 P. F. Góra 4 15
Pierwszy i ostatni punkt odpowiadaja następujacym zależnościom funkcyjnym: NrPociagu Stacja NrKolejny NrPociagu Stacja Przyjazd Odjazd (20a) (20b) co prowadzi do następujacej struktury tabeli Przystanki ( NrPociagu, Stacja, NrKolejny, Przyjazd, Odjazd ) (21) Powstaje jednak pewna watpliwość: A co się stanie jeśli jakiś pociag nie przejeżdża przez dana stację? Czy przypoadkiem zależności funkcyjne (??) nie wymagaja wyspecyfikowania wszystkich możliwych par NrPociagu-Stacja? Oczywiście nie: Zależność funkcyjna ma postać implikacji: jeżeli podamy atrybuty poprzednika, to ustalamy jednoznacznie wartości atrybutów następnika. A jeżeli nie, to nie. Copyright c 2010-11 P. F. Góra 4 16
Rola zapytań A co z określeniem zbioru pociagów, które zatrzymuja się na danej stacji? Nie trzeba w tym celu konstruować osobnej tabeli (relacji) można to osiagn ać poprzez odpowiednie zapytanie: ( π NrPociagu σstacja= Koluszki (Przystanki) ) (22) Nie wszystkie informacje przechowuje się w postaci osobnych tabel użyteczność baz danych polega (między innymi) na tym, że wiele rzeczy da się zrealizować poprzez zapytania. Copyright c 2010-11 P. F. Góra 4 17
Zadanie Posługujac się schematem tabeli Przystanki (??), znaleźć wszystkie pociagi, które przejeżdżaja przez stację X oraz przez stację Y. [ ( πnrpociagu σstacja= X (Przystanki) )] [ ( π NrPociagu σstacja= Y (Przystanki) )] (23) Tabela Przystanki występuje w powyższym zapytaniu dwa razy, po obu stronach złaczenia. Jest to przykład tak zwanego samozłaczenia (self-join). Copyright c 2010-11 P. F. Góra 4 18
Zadanie Posługujac się schematem tabeli Przystanki (??), znaleźć wszystkie pociagi, które najpierw przejeżdżaja przez stację X, później przez stację Y. [ ρ StacjaX(NrPociagu,NrX) πnrpoci ( )] agu,nrkolejny σstacja= X (Przystanki) [ ( ρ StacjaY(NrPociagu,NrY) πnrpociagu,nrkolejny σstacja= Y (Przystanki) ( π NrPociagu σnrx<nry (StacjaX StacjaY) ) )] (24a) (24b) (24c) Zapytanie (??) oczywiście także zawiera samozłaczenie, tyle że w formie niejawnej. Pytanie: Po jakim atrybucie realizowane jest złaczenie w (??)? Po atrybucie NrPociagu, bo to jest powtarzajacy się atrybut w tabelach StacjaX, StacjaY. Copyright c 2010-11 P. F. Góra 4 19
Structured Query Language Używane standardy: SQL92 SQL99 SQL:2003 Żaden dostawca nie jest w pełni zgodny ze standardem prawie wszyscy wprowadzaja rozszerzenia, prawie nikt nie spełnia wszystkich wymogów. W dużych systemach komercyjnych odejście od wymogów nie jest wielkie Copyright c 2010-11 P. F. Góra 4 20
Programowanie deklaratywne SQL a ściślej, podzbiór SQL obejmujacy zapytania SELECT jest językiem deklaratywnym: określa logikę programowania, bez określenia control flow. Innymi słowy, zapytanie SQL mówi co chcemy osiagn ać, bez określenia jak chcemy to zrobić. Przeciwieństwem deklaratywnego paradygmatu programowania jest programowanie imperatywne. Copyright c 2010-11 P. F. Góra 4 21
Połaczenie się z serwerem Przed rozpoczęciem pracy, nalezy wywołać proces kliencki, który połaczy się z serwerem. W MySQL może to wygladać na przykład tak: C:\>mysql -upawel -p Enter password: ************* Po zakończeniu pracy trzeba się pożegnać: mysql> QUIT; Bye Znacznie częściej połaczenie z serwerem nawiazuje się za pomoca jakiejś aplikacji, nie zaś bezpośrednio z shella. Copyright c 2010-11 P. F. Góra 4 22
Utworzenie bazy danych mysql> CREATE DATABASE MoiStudenci CHARACTER SET cp1250; Query OK, 1 row affected (0.06 sec) mysql> USE MoiStudenci; Database changed mysql> Po wywołaniu klienta, trzeba wejść do wybranej bazy za pomoca instrukcji USE nie tylko po jej utworzeniu, ale zawsze. Copyright c 2010-11 P. F. Góra 4 23
To, jakie bazy znajduja się na serwerze, możemy zobaczyć za pomoca instrukcji SHOW DATABASES. mysql> SHOW DATABASES; +--------------------+ Database +--------------------+ information_schema kaskady moistudenci mysql test +--------------------+ 5 rows in set (0.00 sec) Copyright c 2010-11 P. F. Góra 4 24
Utworzenie tabeli mysql> CREATE TABLE Studenci -> (NrStudenta SMALLINT UNSIGNED NOT NULL -> AUTO_INCREMENT PRIMARY KEY); Query OK, 0 rows affected (0.14 sec) Jeśli okaże się to konieczne, po utworzeniu można zmienić definicję tabeli. mysql> ALTER TABLE Studenci -> ADD COLUMN (Nazwisko VARCHAR(20) NOT NULL); Query OK, 1 row affected (0.17 sec) Records: 1 Duplicates: 0 Warnings: 0 Copyright c 2010-11 P. F. Góra 4 25
Składnia polecenia CREATE TABLE CREATE TABLE NazwaTabeli ( NazwaKolumny 1 TypKolumny 1 NULL NOT NULL..., NazwaKolumny 2 TypKolumny 2 NULL NOT NULL...,... ) PRIMARY KEY (NazwaKolumny p,nazwakolumny q,... ) ; Inne opcje poznamy później. Copyright c 2010-11 P. F. Góra 4 26
Typy danych (atrybutów) TINYINT DATE TINYBLOB SMALLINT TIME BLOB MEDIUMINT TIMESTAMP MEDIUMBLOB INT DATETIME LONGBLOB INTEGER CHAR TINYTEXT BIGINT VARCHAR TEXT REAL BOOLEAN LONGTEXT DOUBLE ENUM FLOAT SET DECIMAL NUMERIC Copyright c 2010-11 P. F. Góra 4 27
Instrukcja DESCRIBE podaje definicję tabeli. mysql> DESCRIBE Studenci; +------------+----------------------+------+-----+---------+----------------+ Field Type Null Key Default Extra +------------+----------------------+------+-----+---------+----------------+ NrStudenta smallint(5) unsigned NO PRI NULL auto_increment Nazwisko varchar(20) NO +------------+----------------------+------+-----+---------+----------------+ 2 rows in set (0.01 sec) Niepotrzebna tabelę usuwamy za pomoca instrukcji DROP TABLE. mysql> DROP TABLE Studenci; Query OK, 0 rows affected (0.02 sec) Lepiej ja utworzyć od poczatku dobrze niż dodawać kolumna po kolumnie... Copyright c 2010-11 P. F. Góra 4 28
mysql> CREATE TABLE Studenci -> (NrStudenta SMALLINT UNSIGNED NOT NUll -> AUTO_INCREMENT PRIMARY KEY, -> Imie VARCHAR(20), -> Nazwisko VARCHAR(20) NOT NULL, -> Uwagi VARCHAR(30), -> Grupa CHAR(2) NOT NULL)); Query OK, 0 rows affected (0.06 sec) mysql> DESCRIBE Studenci; +------------+----------------------+------+-----+---------+----------------+ Field Type Null Key Default Extra +------------+----------------------+------+-----+---------+----------------+ NrStudenta smallint(5) unsigned NO PRI NULL auto_increment Imie varchar(20) YES NULL Nazwisko varchar(20) NO Uwagi varchar(30) YES NULL Grupa char(2) NO +------------+----------------------+------+-----+---------+----------------+ 5 rows in set (0.00 sec) Copyright c 2010-11 P. F. Góra 4 29
Wstawianie wartości do tabeli mysql> SET CHARACTER SET cp1250; Query OK, 0 rows affected (0.00 sec) Gdybyśmy tego nie zrobili, MySQL używałby takiego zestawu znaków, jaki obowiazywał domyślnie w momencie połaczenia z serwerem. Kwestie określania zestawu znaków to osobliwość MySQLa mysql> INSERT INTO Studenci VALUES -> (1, Milena, Zahorska, wt, uzupełniające ); Query OK, 1 row affected (0.02 sec) Copyright c 2010-11 P. F. Góra 4 30
Co teraz jest w tabeli? mysql> SELECT * FROM Studenci; +------------+--------+----------+---------------+-------+ NrStudenta Imie Nazwisko Uwagi Grupa +------------+--------+----------+---------------+-------+ 1 Milena Zahorska uzupełniające wt +------------+--------+----------+---------------+-------+ 1 row in set (0.00 sec) Copyright c 2010-11 P. F. Góra 4 31
Składnia zapytania SELECT; SELECT [DISTINCT] lista select FROM tabela lub zapytanie WHERE warunek logiczny GROUP BY wyrażenie grupujace HAVING warunek wyszukiwania po grupowaniu ORDER BY wyrażenie porzadkuj ace [ASC DESC] ; W zapytaniu SELECT wszystkie klauzule musza występować w powyższej kolejności. Niektóre klauzule można opuścić, ale to, co jest, musi być w tej kolejności. Copyright c 2010-11 P. F. Góra 4 32
Dodajmy więcej danych mysql> INSERT INTO Studenci VALUES -> (2, Sylwester, Tomiec, uzupełniające, wt ), -> (3, Michał, Gajewczyk,, wt ); Query OK, 2 rows affected (0.02 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM Studenci; +------------+-----------+-----------+---------------+-------+ NrStudenta Imie Nazwisko Uwagi Grupa +------------+-----------+-----------+---------------+-------+ 1 Milena Zahorska uzupełniające wt 2 Sylwester Tomiec uzupełniające wt 3 Michał Gajewczyk wt +------------+-----------+-----------+---------------+-------+ 3 rows in set (0.00 sec) Copyright c 2010-11 P. F. Góra 4 33
Wykorzystanie opcji AUTOINCREMENT mysql> INSERT INTO Studenci (Imie,Nazwisko,Grupa) VALUES -> ( Rafał, Świderski, wt ), -> ( Maciej, Matowicki, wf ), -> ( Janko, Muzykant, nd ); Query OK, 3 rows affected (0.02 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM Studenci; +------------+-----------+-----------+---------------+-------+ NrStudenta Imie Nazwisko Uwagi Grupa +------------+-----------+-----------+---------------+-------+ 1 Milena Zahorska uzupełniające wt 2 Sylwester Tomiec uzupełniające wt 3 Michał Gajewczyk wt 4 Rafał Świderski NULL wt 5 Maciej Matowicki NULL wf 6 Janko Muzykant NULL nd +------------+-----------+-----------+---------------+-------+ 6 rows in set (0.00 sec) Copyright c 2010-11 P. F. Góra 4 34
Zapytanie UPDATE mysql> UPDATE Studenci -> SET Uwagi=NULL -> WHERE NrStudenta=3; Query OK, 1 row affected (0.02 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> UPDATE Studenci -> SET Grupa= wt WHERE Grupa= wf ; Query OK, 1 row affected (0.03 sec) Rows matched: 1 Changed: 1 Warnings: 0 Copyright c 2010-11 P. F. Góra 4 35
mysql> SELECT * FROM Studenci; +------------+-----------+-----------+---------------+-------+ NrStudenta Imie Nazwisko Uwagi Grupa +------------+-----------+-----------+---------------+-------+ 1 Milena Zahorska uzupełniające wt 2 Sylwester Tomiec uzupełniające wt 3 Michał Gajewczyk NULL wt 4 Rafał Świderski NULL wt 5 Maciej Matowicki NULL wt 6 Janko Muzykant NULL nd +------------+-----------+-----------+---------------+-------+ 6 rows in set (0.00 sec) Copyright c 2010-11 P. F. Góra 4 36
Zapytanie DELETE Usuwanie wierszy spełniajacych podane kryterium: mysql> DELETE FROM Studenci -> WHERE Imie= Janko ; Query OK, 1 row affected (0.03 sec) Dodajmy coś jeszcze: mysql> INSERT INTO Studenci (Imie,Nazwisko,Grupa) VALUES -> ( Michał, Czubek, pt ),( Marcin, Pyra, pt ), -> ( Marcin, Baranowski, pt ); Query OK, 3 rows affected (0.02 sec) Records: 3 Duplicates: 0 Warnings: 0 Copyright c 2010-11 P. F. Góra 4 37
mysql> SELECT * FROM Studenci; +------------+-----------+------------+---------------+-------+ NrStudenta Imie Nazwisko Uwagi Grupa +------------+-----------+------------+---------------+-------+ 1 Milena Zahorska uzupełniające wt 2 Sylwester Tomiec uzupełniające wt 3 Michał Gajewczyk NULL wt 4 Rafał Świderski NULL wt 5 Maciej Matowicki NULL wt 7 Michał Czubek NULL pt 8 Marcin Pyra NULL pt 9 Marcin Baranowski NULL pt +------------+-----------+------------+---------------+-------+ 8 rows in set (0.01 sec) Brakuje numeru 6 AUTOINCREMENT zapamiętał, że on tam był. AUTOINCREMENT zawsze startuje od high water mark. Copyright c 2010-11 P. F. Góra 4 38
Jawnie wyspecyfikowana lista select mysql> SELECT Imie, Nazwisko FROM Studenci; +-----------+------------+ Imie Nazwisko +-----------+------------+ Milena Zahorska Sylwester Tomiec Michał Gajewczyk Rafał Świderski Maciej Matowicki Michał Czubek Marcin Pyra Marcin Baranowski +-----------+------------+ 8 rows in set (0.01 sec) Gwiazdka w zapytaniu SELECT (SELECT * FROM...) oznacza wszystkie kolumny. Copyright c 2010-11 P. F. Góra 4 39
Problem duplikatów mysql> SELECT Imie -> FROM Studenci; +-----------+ Imie +-----------+ Milena Sylwester Michał Rafał Maciej Michał Marcin Marcin +-----------+ 8 rows in set (0.00 sec) mysql> SELECT DISTINCT Imie -> FROM Studenci; +-----------+ Imie +-----------+ Milena Sylwester Michał Rafał Maciej Marcin +-----------+ 6 rows in set (0.00 sec) Copyright c 2010-11 P. F. Góra 4 40
Operator LIKE mysql> SELECT Imie, Nazwisko -> FROM Studenci -> WHERE Imie LIKE Mi% ; +--------+-----------+ Imie Nazwisko +--------+-----------+ Milena Zahorska Michał Gajewczyk Michał Czubek +--------+-----------+ 3 rows in set (0.00 sec) mysql> SELECT Imie, Nazwisko -> FROM Studenci -> WHERE Imie LIKE %ł ; +--------+-----------+ Imie Nazwisko +--------+-----------+ Michał Gajewczyk Rafał Świderski Michał Czubek +--------+-----------+ 3 rows in set (0.00 sec) Copyright c 2010-11 P. F. Góra 4 41
Wykorzystanie ORDER BY mysql> SELECT Imie, Nazwisko -> FROM Studenci -> WHERE Grupa= wt -> ORDER BY Nazwisko ASC; +-----------+-----------+ Imie Nazwisko +-----------+-----------+ Michał Gajewczyk Maciej Matowicki Sylwester Tomiec Milena Zahorska Rafał Świderski +-----------+-----------+ 5 rows in set (0.02 sec) Problemy z poprawnym sortowaniem polskich znaków diakrytycznych Copyright c 2010-11 P. F. Góra 4 42
MySQL i programowanie wsadowe C:\wyklady\bazy> mysql < nazwa pliku C:\wyklady\bazy> mysql -hhostname -uusername -p < nazwa pliku Plik musi być dostępny dla klienta. Pliki wsadowe można też wołać z wnętrza klienta: mysql> source nazwa pliku; Uwaga: Jeśli któreś polecenie w pliku wsadowym spowoduje bład, dalsze polecenia nie sa wykonywane. Copyright c 2010-11 P. F. Góra 4 43
Tworzenie tabeli wraz z kopiowaniem danych mysql> USE moistudenci; Database changed mysql> DESCRIBE Studenci; +------------+----------------------+------+-----+---------+----------------+ Field Type Null Key Default Extra +------------+----------------------+------+-----+---------+----------------+ NrStudenta smallint(5) unsigned NO PRI auto_increment Imie varchar(20) NO Nazwisko varchar(20) NO Uwagi varchar(30) YES Grupa char(2) YES +------------+----------------------+------+-----+---------+----------------+ 5 rows in set (0.21 sec) Copyright c 2010-11 P. F. Góra 4 44
mysql> CREATE TABLE Studenci2 -> (NrStudenta INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, -> Imie VARCHAR(20) NOT NULL, Nazwisko VARCHAR(20) NOT NULL, -> Uwagi VARCHAR(30), Grupa CHAR(2)) -> -- TU kończy się definicja tabeli! -> SELECT * FROM STUDENCI; Query OK, 9 rows affected (1.08 sec) Records: 9 Duplicates: 0 Warnings: 0 mysql> DESCRIBE Studenci2; +------------+------------------+------+-----+---------+----------------+ Field Type Null Key Default Extra +------------+------------------+------+-----+---------+----------------+ NrStudenta int(10) unsigned NO PRI auto_increment Imie varchar(20) NO Nazwisko varchar(20) NO Uwagi varchar(30) YES Grupa char(2) YES +------------+------------------+------+-----+---------+----------------+ 5 rows in set (0.01 sec) Copyright c 2010-11 P. F. Góra 4 45
mysql> SELECT * FROM Studenci2; +------------+----------+--------------+-------+-------+ NrStudenta Imie Nazwisko Uwagi Grupa +------------+----------+--------------+-------+-------+ 1 Mariusz Lewandowski xxxx xy 2 Jakub Stefanowski xy 3 Marek Giebułtowski xy 4 Barbara Jeziorek xy 6 Wojciech Wąchal xy 72 Jakub Janoszek xy 73 Maciej Gowin xy 74 Tadeusz Drozda xy 75 Marek Kolejny xy +------------+----------+--------------+-------+-------+ 9 rows in set (0.03 sec) Copyright c 2010-11 P. F. Góra 4 46
Zmienne tymczasowe SQL pozwala na definiowanie zmiennych tymczasowych nazwa zmiennej tymczasowej zawsze zaczyna się od @. Zmienna istnieje dopóty, dopóki nie zostanie zakończone połaczenie z serwerem. Procesy klienckie nie widza zmiennych zdefiniowanych przez inne procesy. mysql> SET @a=5; Query OK, 0 rows affected (0.01 sec) mysql> SELECT @a-2; +------+ @a-2 +------+ 3 +------+ 1 row in set (0.00 sec) Copyright c 2010-11 P. F. Góra 4 47
Zmiennej można przypisać wartość, która jest wynikiem zapytania: mysql> SET @b=(select NrStudenta FROM Studenci2 WHERE Imie= Tadeusz ); Query OK, 0 rows affected (0.89 sec) mysql> SELECT @b, @a+@b; +------+-------+ @b @a+@b +------+-------+ 74 79 +------+-------+ 1 row in set (0.00 sec) Copyright c 2010-11 P. F. Góra 4 48
Aliasy W zapytaniu SELECT możemy nadawać kolumnom inne nazwy niż te, które występuja w definicji tabeli. Nosza one nazwę aliasów. mysql> SELECT NrStudenta AS ToJestNumer, Imie FROM Studenci2; +-------------+----------+ ToJestNumer Imie +-------------+----------+ 1 Mariusz 2 Jakub 3 Marek 4 Barbara 6 Wojciech 72 Jakub 73 Maciej 74 Tadeusz 75 Marek 65536 X +-------------+----------+ 10 rows in set (0.00 sec) Copyright c 2010-11 P. F. Góra 4 49
Niekiedy wygodnie jest użyć aliasu w dalszej części zapytania, ale nie można go użyć w kaluzuli WHERE mysql> SELECT NrStudenta AS ToJestNumer, Imie FROM Studenci2 -> WHERE ToJestNumer > 10; ERROR 1054 (42S22): Unknown column ToJestNumer in where clause Można natomiast użyć aliasu w klauzuli HAVING: mysql> SELECT NrStudenta AS ToJestNumer, Imie as Pierwsze imię FROM Studenci2 -> HAVING ToJestNumer > 10; +-------------+---------------+ ToJestNumer Pierwsze imię +-------------+---------------+ 72 Jakub 73 Maciej 74 Tadeusz 75 Marek 65536 X +-------------+---------------+ 5 rows in set (0.00 sec) Copyright c 2010-11 P. F. Góra 4 50
Jest to szczególnie przydatne, gdy w warunku występuje wartość obliczana na podstawie więcej niż jednej kolumny: mysql> SELECT CONCAT(Imie,,Nazwisko) AS Imie_Nazwisko FROM Studenci2 -> HAVING Imie_Nazwisko LIKE "%r%z%"; +---------------------+ Imie_Nazwisko +---------------------+ Mariusz Lewandowski Barbara Jeziorek Tadeusz Drozda +---------------------+ 3 rows in set (0.00 sec) Copyright c 2010-11 P. F. Góra 4 51