wprowadzenie -...
TRANSCRIPT
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
1
Na podstawie: webmaster.helion.pl
oraz: ihelp.ovh.org
Wprowadzenie
Funkcje tekstowe
Funkcje liczbowe
Funkcje daty i czasu
Funkcje konwersji
Funkcje serwera MySQL
Tak jak we wszystkich innych językach programowania, w języku SQL funkcje stanowią potężne
narzędzie w pracy programisty — zamiast samodzielnie pisać skomplikowane programy, wystarczy
wywołać odpowiednią funkcję. W tym odcinku nauczysz się wywoływać funkcje systemowe i poznasz
niektóre funkcje serwera MySQL.
Wprowadzenie
Wbudowane funkcje serwerów baz danych można podzielić na trzy kategorie:
1. Funkcje skalarne — zwracają pojedynczą wartość obliczoną na podstawie zera lub większej
liczby prostych argumentów.
2. Funkcje grupujące — zwracają pojedynczą wartość dla zbioru argumentów wywołania.
3. Funkcje typu RowSet — zwracające dane w postaci tabelarycznej, do których odwołujemy
się tak jak do tabel.
Na podstawie typu parametrów wywołania funkcje skalarne można podzielić na:
1. Funkcje tekstowe operujące na ciągach znaków.
2. Funkcje liczbowe operujące na liczbach.
3. Funkcje daty i czasu operujące na danych typu data i godzina.
4. Funkcje konwersji służące do zmiany typu danych.
5. Na specjalne wyróżnienie zasługują funkcje kryptologiczne, które pozwalają zaszyfrować,
odszyfrować i podpisać wiadomość oraz sprawdzić jej autentyczność.
W języku SQL funkcje można zagnieżdżać do dowolnego poziomu. Funkcje najbardziej wewnętrzne
obliczane są w pierwszej kolejności, a na podstawie ich wyników obliczane są funkcje zewnętrzne.
Funkcje tekstowe
Argumentem funkcji tekstowych są ciągi znaków (dane typów char, varchar lub text). Typ danych
zwracanych przez funkcje tekstowe jest podstawą do ich dalszego podziału: wyróżniamy funkcje
tekstowe zwracające wartość znakową i funkcje tekstowe zwracające liczbę.
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
2
Funkcje tekstowe zwracające tekst
CONCAT()
Funkcja łączy (konkatenuje) przekazane jako parametr i oddzielone przecinkami ciągi znaków.
Używaliśmy już tej funkcji, a w następnych listingach użyjemy jej jeszcze kilka razy.
CONCAT_WS()
Funkcja łączy (konkatenuje) przekazane jako parametr i oddzielone przecinkami ciągi znaków,
rozdzielając je przekazanym jako pierwszy parametr ciągiem znaków.
LOWER()
Wynikiem działania funkcji LOWER() jest ciąg znaków podany jako argument, ale składający się
wyłącznie z małych liter. Za pomocą tej funkcji wszystkie wielkie litery argumentu zostaną
zamienione na małe. Aby na przykład wyświetlić nazwiska wszystkich współpracowników za pomocą
małych liter, napiszemy (listing 12.1):
Listing 12.1. Funkcji skalarnych można używać m.in. w klauzulach SELECT, WHERE i ORDER BY
SELECT title, LOWER(title)
FROM customer
WHERE customer_id<3;
+-------+--------------+
| title | lower(title) |
+-------+--------------+
| Miss | miss |
| Mr | mr |
+-------+--------------+
UPPER()
Wynikiem działania funkcji UPPER() jest ciąg znaków podany jako argument, ale składający się
wyłącznie z wielkich liter. Za pomocą tej funkcji wszystkie małe litery argumentu zostaną zamienione
na wielkie. Aby na przykład uszeregować nazwy wszystkich towarów alfabetycznie według ich nazw,
bez względu na wielkość użytych w nazwie liter, napiszemy (listing 12.2):
Listing 12.2. Poszczególne klauzule instrukcji są od siebie niezależne — dane mogą być na przykład
sortowane według wyrażenia niewymienionego w klauzuli SELECT
SELECT *
FROM item
ORDER BY UPPER(description);
+---------+-----------------+------------+------------+
| item_id | description | cost_price | sell_price |
+---------+-----------------+------------+------------+
| 10 | Carrier Bag | 0.01 | 0.00 |
| 7 | Fan Large | 13.36 | 19.95 |
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
3
| 6 | Fan Small | 9.23 | 15.75 |
| 3 | Linux CD | 1.99 | 2.49 |
| 5 | Picture Frame | 7.54 | 9.95 |
| 9 | Roman Coin | 2.34 | 2.45 |
| 2 | Rubik Cube | 7.45 | 11.49 |
| 11 | Speakers | 19.73 | 25.32 |
| 12 | SQL Server 2005 | NULL | NULL |
| 4 | Tissues | 2.11 | 3.99 |
| 8 | Toothbrush | 0.75 | 1.45 |
| 1 | Wood Puzzle | 15.23 | 21.95 |
+---------+-----------------+------------+------------+
LEFT()
Za pomocą funkcji LEFT() z podanego jako argument ciągu znaków zostanie wycięta określona
liczba znaków, począwszy od lewej strony. Aby odczytać inicjały klientów, wykonamy instrukcję
pokazaną na listingu 12.3.
Listing 12.3. Przykład zagnieżdżania funkcji — najpierw odczytywane są pierwsza litera imienia i
nazwiska, a następnie są one łączone w jeden ciąg
SELECT CONCAT(LEFT(fname,1), LEFT(lname,1))
FROM customer;
+--------------------------------------+
| CONCAT(LEFT(fname,1), LEFT(lname,1)) |
+--------------------------------------+
| JS |
| AS |
| AM |
| AM |
| SC |
| NM |
| RS |
| AS |
| CH |
| MH |
| DJ |
| RN |
| LH |
| BN |
| DH |
| NULL |
+--------------------------------------+
RIGHT()
Za pomocą funkcji RIGHT() z podanego jako argument ciągu znaków zostanie wycięta określona
liczba znaków, począwszy od prawej strony (listing 12.4).
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
4
Listing 12.4. Wyświetlamy dane wyłącznie tych osób, których imiona kończą się na litery rd
SELECT title, lname, fname
FROM customer
WHERE RIGHT(fname,2) = 'rd';
+-------+--------+---------+
| title | lname | fname |
+-------+--------+---------+
| Mr | Stones | Richard |
| Mr | Neill | Richard |
+-------+--------+---------+
TRIM(), LTRIM() i RTRIM()
Funkcja LTRIM() z podanego ciągu znaków usuwa wiodące spacje, funkcja RTIM() usuwa kończące
(wolne) spacje, a funkcja TRIM() — zarówno wiodące, jak i wolne spacje (listing 12.5).
Listing 12.5. Przed zapisaniem danych do bazy z reguły warto usunąć z nich przypadkowo dodane
spacje
SELECT ltrim(' barba dos ';
+---------------------------+
| ltrim(' barba dos ') |
+---------------------------+
| barba dos |
+---------------------------+
SELECT rtrim(' barba dos ');
+---------------------------+
| rtrim(' barba dos ') |
+---------------------------+
| barba dos |
+---------------------------+
SELECT trim(' barba dos ');
+--------------------------+
| trim(' barba dos ') |
+--------------------------+
| barba dos |
+--------------------------+
REPLACE()
Za pomocą funkcji REPLACE() w ciągu znaków podanym jako pierwszy parametr zostanie wyszukany
ciąg podany jako jej drugi parametr, a następnie w miejsce znalezionego ciągu będzie podstawiony
ciąg podany jako trzeci parametr wywołania. Jeżeli trzeci parametr nie zostanie podany, z ciągu
podstawowego będzie wycięty wyszukany ciąg znaków (listing 12.6).
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
5
Listing 12.6. Funkcja REPLACE jest niezastąpiona na przykład przy przygotowywaniu kolejnej wersji
tego samego zestawienia
SELECT REPLACE('Kierownik niech nam żyje', ' żyje' , 'zgnije');
+---------------------------------------------------------+
| REPLACE('Kierownik niech nam żyje', ' żyje' , 'zgnije') |
+---------------------------------------------------------+
| Kierownik niech nam zgnije |
+---------------------------------------------------------+
SUBSTRING()
W wyniku działania funkcji SUBSTRING() zostanie zwrócona określona liczba znaków z łańcucha
tekstowego, począwszy od podanej pozycji. Jeżeli nie podamy liczby zwracanych znaków, zwrócone
będą wszystkie znaki występujące po pozycji określonej przez drugi parametr. Podanie ujemnej
wartości drugiego parametru spowoduje, że znaki będą liczone od prawej do lewej (listing 12.7).
Listing 12.7. Siedem liter, począwszy od piątej, z nazw produktów
SELECT SUBSTRING(description,5,7)
FROM item;
+----------------------------+
| SUBSTRING(description,5,7) |
+----------------------------+
| Puzzle |
| k Cube |
| x CD |
| ues |
| ure Fra |
| Small |
| Large |
| hbrush |
| n Coin |
| ier Bag |
| kers |
| Server |
+----------------------------+
SPACE()
Działanie funkcji SPACE() powoduje zwrócenie liczby spacji określonej jako parametr (listing 12.8).
Listing 12.8. Zamiast ręcznie dodawać spacje, możemy użyć do tego funkcji SPACE()
SELECT CONCAT(fname, SPACE(3), lname)
FROM customer;
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
6
+--------------------------------+
| CONCAT(fname, SPACE(3), lname) |
+--------------------------------+
| Jenny Stones |
| Andrew Stones |
| Alex Matthew |
| Adrian Matthew |
| Simon Cozens |
| Neil Matthew |
| Richard Stones |
| Ann Stones |
| Christine Hickman |
| Mike Howard |
| Dave Jones |
| Richard Neill |
| Laura Hendy |
| Bill Neill |
| David Hudson |
| NULL |
+--------------------------------+
REVERSE()
Funkcja REVERSE() zwraca ciąg znaków będący palindromem argumentu wywołania, czyli ciągiem
znaków o odwróconej kolejności liter (listing 12.9).
Listing 12.9. Zapytanie zwracające imiona będące palindromami
SELECT fname
from customer
WHERE REVERSE(fname) = fname;
+-------+
| fname |
+-------+
| Anna |
+-------+
Funkcje tekstowe zwracające liczby
LENGTH()
Funkcja LENGTH() jako wynik zwraca długość ciągu znaków podanego jako parametr jej wywołania.
Jeżeli wywołamy funkcję LENGTH() z wartością Null, funkcja zwróci wartość Null. Za pomocą
poniższej instrukcji wyświetlimy tylko te opisy towarów, które mają długie (dłuższe niż 10-znakowe)
nazwy (listing 12.10).
Listing 12.10. Funkcja LENGTH() użyta do selekcji wierszy
SELECT description, LENGTH(description)
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
7
FROM item
WHERE LENGTH(description)>10;
+-----------------+---------------------+
| description | LENGTH(description) |
+-----------------+---------------------+
| Wood Puzzle | 11 |
| Picture Frame | 13 |
| Carrier Bag | 11 |
| SQL Server 2005 | 15 |
+-----------------+---------------------+
INSTR()
W wyniku działania funkcji INSTR() będzie zwrócona pozycja, na której w ciągu znaków podanym
jako pierwszy parametr został znaleziony ciąg znaków podany jako drugi parametr. Jeżeli szukany ciąg
znaków nie będzie znaleziony, funkcja zwróci 0 (listing 12.11).
Listing 12.11. Wykorzystanie funkcji INSTR() do wybrania produktów, które w nazwie mają literę
a
SELECT description
FROM item
WHERE INSTR(description, 'a')>0;
+---------------+
| description |
+---------------+
| Picture Frame |
| Fan Small |
| Fan Large |
| Roman Coin |
| Carrier Bag |
| Speakers |
+---------------+
Funkcje liczbowe
Funkcje liczbowe pozwalają wykonywać dodatkowe (oprócz dodawania, odejmowania czy mnożenia)
operacje matematyczne oraz formatować liczby.
ROUND()
Działanie funkcji ROUND() polega na zaokrągleniu liczby do określonej liczby cyfr po przecinku.
Pierwszy parametr jest liczbą do zaokrąglenia, drugi wskazuje, do ilu pozycji chcemy ją zaokrąglić.
Ujemna wartość powoduje zaokrąglenie liczby z lewej strony przecinka; 0 spowoduje zaokrąglenie do
najbliższej liczby całkowitej. Jeżeli drugi parametr nie jest podany, serwer baz danych przyjmuje
domyślnie jego wartość jako równą 0 (listing 12.12).
Listing 12.12. Przykład użycia funkcji ROUND()
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
8
SELECT Round(3.1415926535897,4);
+--------------------------+
| Round(3.1415926535897,4) |
+--------------------------+
| 3.1416 |
+--------------------------+
SELECT Round(3.1415926535897,0);
+--------------------------+
| Round(3.1415926535897,0) |
+--------------------------+
| 3 |
+--------------------------+
SELECT Round(3.1415926535897);
+------------------------+
| Round(3.1415926535897) |
+------------------------+
| 3 |
+------------------------+
TRUNCATE()
Funkcja TRUNCATE() powoduje obcięcie liczby do określonej liczby cyfr po przecinku. Pierwszy
parametr jest liczbą do obcięcia, drugi wskazuje, do ilu pozycji chcemy liczbę skrócić. Ujemna wartość
powoduje dodanie określonej liczby zer z lewej strony przecinka. Jeżeli drugi parametr nie jest
podany, MySQL przyjmuje domyślnie jego wartość jako równą 0 (listing 12.13).
Listing 12.13. Obcięcie miejsc po przecinku i zaokrąglenie do iluś miejsc po przecinku to dwie
operacje
SELECT Truncate(3.1415926535897,4);
+-----------------------------+
| Truncate(3.1415926535897,4) |
+-----------------------------+
| 3.1415 |
+-----------------------------+
ABS()
Wynikiem działania funkcji ABS() jest wartość bezwzględna liczby (liczba bez znaku). Jako parametr
podaje się liczbę, której wartość bezwzględną należy obliczyć (listing 12.14).
Listing 12.14. Funkcja ABS() użyta do sprawdzenia, czy dana liczba jest dodatnia
SELECT *
FROM item
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
9
WHERE sell_price != ABS(sell_price);
Empty set
CEILING(), FLOOR()
Za pomocą funkcji CEILING() zwrócona zostanie najmniejsza liczba całkowita równa liczbie podanej
jako argument funkcji lub większa. Funkcja FLOOR() zwraca największą liczbę całkowitą równą
liczbie podanej jako argument funkcji lub mniejszą (listing 12.15).
Listing 12.15. Zwróć uwagę na wynik wywołania funkcji z argumentem Null
SELECT sell_price, CEILING(sell_price), FLOOR(sell_price)
FROM item;
+------------+---------------------+-------------------+
| sell_price | CEILING(sell_price) | FLOOR(sell_price) |
+------------+---------------------+-------------------+
| 21.95 | 22 | 21 |
| 11.49 | 12 | 11 |
| 2.49 | 3 | 2 |
| 3.99 | 4 | 3 |
| 9.95 | 10 | 9 |
| 15.75 | 16 | 15 |
| 19.95 | 20 | 19 |
| 1.45 | 2 | 1 |
| 2.45 | 3 | 2 |
| 0.00 | 0 | 0 |
| 25.32 | 26 | 25 |
| NULL | NULL | NULL |
+------------+---------------------+-------------------+
POWER(), POW()
Funkcja POWER() sprawia, że liczba podana jako pierwszy parametr zostanie podniesiona do potęgi
podanej jako drugi parametr. Wartości drugiego parametru mogą być mniejsze niż zero (listing
12.16).
Listing 12.16. Często tę samą funkcję możemy wywołać za pomocą kilku nazw
SELECT POWER(10,2), POW(2,10);
+-------------+-----------+
| POWER(10,2) | POW(2,10) |
+-------------+-----------+
| 100 | 1024 |
+-------------+-----------+
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
10
SQRT()
W wyniku działania funkcji SQRT() zwrócony będzie pierwiastek kwadratowy z liczby podanej jako
parametr wywołania (listing 12.17).
Listing 12.17. Przykład użycia funkcji SQRT()
SELECT SQRT(10), SQRT(16);
+--------------------+----------+
| SQRT(10) | SQRT(16) |
+--------------------+----------+
| 3.1622776601683795 | 4 |
+--------------------+----------+
MOD()
Funkcja MOD() zwraca jako wynik wartość reszty po podzieleniu liczby podanej jako pierwszy
parametr przez dzielnik podany jako drugi parametr wywołania funkcji. Jeżeli wartość drugiego
parametru wynosi 0, zwracana jest liczba podana jako pierwszy parametr (listing 12.18).
Listing 12.18. Zapytanie zwracające dane towarów o parzystych identyfikatorach
SELECT *
FROM item
WHERE MOD(item_id,2)=0;
+---------+-----------------+------------+------------+
| item_id | description | cost_price | sell_price |
+---------+-----------------+------------+------------+
| 2 | Rubik Cube | 7.45 | 11.49 |
| 4 | Tissues | 2.11 | 3.99 |
| 6 | Fan Small | 9.23 | 15.75 |
| 8 | Toothbrush | 0.75 | 1.45 |
| 10 | Carrier Bag | 0.01 | 0.00 |
| 12 | SQL Server 2005 | NULL | NULL |
+---------+-----------------+------------+------------+
Funkcje trygonometryczne — SIN(), COS(), TAN() i COT()
W wyniku działania funkcji SIN() (sinus), COS() (cosinus), TAN() (tangens) i COT() (cotangens)
zwrócona zostanie wartość odpowiednich funkcji trygonometrycznych — dla parametru będącego
kątem w radianach będzie obliczony odpowiednio: sinus, cosinus, tangens lub cotangens. Aby
przeliczyć kąty z radianów na stopnie, należy posłużyć się wzorem: stopnie · PI()/180 = radiany
(listing 12.19).
Listing 12.19. Przykład użycia funkcji trygonometrycznych
SELECT SIN(200), COS(200), COT(200);
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
11
+-------------------+------------------+-------------------+
| SIN(200) | COS(200) | COT(200) |
+-------------------+------------------+-------------------+
| -0.87329729721399 | 0.48718767500701 | -0.55787150213477 |
+-------------------+------------------+-------------------+
RAND()
Funkcja RAND() zwraca pseudolosową liczbę z przedziału od 0 do 1. Serwer MySQL oblicza tę
wartość dla każdego wiersza wyniku (listing 12.20), co pozwala użyć funkcji RAND() do losowego
wybierania danych z tabeli (listing 12.21).
Listing 12.20. MySQL w przeciwieństwie do niektórych serwerów baz danych wylicza wartości
funkcji RAND() dla każdego wiersza wyniku
SELECT RAND(), description
FROM item;
+------------------+-----------------+
| RAND() | description |
+------------------+-----------------+
| 0.93018501059169 | Wood Puzzle |
| 0.14203970892545 | Rubik Cube |
| 0.9196435435858 | Linux CD |
| 0.17209862188632 | Tissues |
| 0.10156250940781 | Picture Frame |
| 0.99151671211376 | Fan Small |
| 0.65289606307903 | Fan Large |
| 0.2899302097875 | Toothbrush |
| 0.49096289043404 | Roman Coin |
| 0.58502385354137 | Carrier Bag |
| 0.45223062713838 | Speakers |
| 0.50608160580143 | SQL Server 2005 |
+------------------+-----------------+
Listing 12.21. Każde wywołanie tej instrukcji zwróci informację o innym, losowo wybranym
towarze
SELECT *
FROM item
ORDER BY RAND()
LIMIT 1;
+---------+-------------+------------+------------+
| item_id | description | cost_price | sell_price |
+---------+-------------+------------+------------+
| 9 | Roman Coin | 2.34 | 2.45 |
+---------+-------------+------------+------------+
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
12
SIGN()
Funkcja SIGN() zwraca 1, jeżeli argumentem jej wywołania była liczba większa od 0, lub 0, jeżeli
argumentem jej wywołania było 0, albo –1, jeżeli została wywołana dla liczby mniejszej od zera. W
listingu 12.22 użyto jej do wyróżniania informacji o tym, czy cena sprzedaży towaru była wyższa od
ceny jego zakupu.
Listing 12.22. Funkcja SIGN() wywołana dla wyniku odjęcia wartości dwóch kolumn
SELECT description,SIGN(sell_price-cost_price)
FROM test.item;
+-----------------+-----------------------------+
| description | SIGN(sell_price-cost_price) |
+-----------------+-----------------------------+
| Wood Puzzle | 1 |
| Rubik Cube | 1 |
| Linux CD | 1 |
| Tissues | 1 |
| Picture Frame | 1 |
| Fan Small | 1 |
| Fan Large | 1 |
| Toothbrush | 1 |
| Roman Coin | 1 |
| Carrier Bag | -1 |
| Speakers | 1 |
| SQL Server 2005 | NULL |
+-----------------+-----------------------------+
FORMAT()
Funkcja FORMAT() zwraca przekazaną jako pierwszy argument wywołania liczbę z określoną przez
drugi parametr liczbą miejsc po przecinku (listing 12.23).
Listing 12.23. Formatowanie liczb polega na określaniu miejsc po przecinku
SELECT cost_price, FORMAT(cost_price,1), FORMAT(cost_price,3)
FROM test.item i;
+------------+----------------------+----------------------+
| cost_price | FORMAT(cost_price,1) | FORMAT(cost_price,3) |
+------------+----------------------+----------------------+
| 15.23 | 15.2 | 15.230 |
| 7.45 | 7.5 | 7.450 |
| 1.99 | 2.0 | 1.990 |
| 2.11 | 2.1 | 2.110 |
| 7.54 | 7.5 | 7.540 |
| 9.23 | 9.2 | 9.230 |
| 13.36 | 13.4 | 13.360 |
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
13
| 0.75 | 0.8 | 0.750 |
| 2.34 | 2.3 | 2.340 |
| 0.01 | 0.0 | 0.010 |
| 19.73 | 19.7 | 19.730 |
| NULL | NULL | NULL |
+------------+----------------------+----------------------+
Funkcje daty i czasu
Kolejna często używana grupa funkcji to funkcje operujące na argumentach będących zapisem daty
lub czasu. W prawie każdej bazie danych część przechowywanych w niej informacji musi mieć jakiś
znacznik czasu — atrybut pozwalający na sprawdzenie, kiedy rekord został dodany lub
zmodyfikowany. Informacje takie jak dane o poszczególnych transakcjach finansowych stają się
bezwartościowe po wyeliminowaniu dat tych operacji. Dlatego MySQL posiada predefiniowane
funkcje pozwalające wykonywać podstawowe operacje na danych tego typu.
CURDATE(), CURTIME()
Wynikiem działania funkcji CURDATE() jest bieżąca data, a funkcji CURTIME() — bieżący czas.
Częstym zastosowaniem funkcji jest automatyczne wstawianie informacji o czasie utworzenia lub
zmodyfikowania danych (listing 12.24).
Listing 12.24. Odczytanie bieżącej daty i czasu systemowego
SELECT CURDATE(),CURTIME();
+------------+-----------+
| CURDATE() | CURTIME() |
+------------+-----------+
| 2016-04-06 | 09:33:10 |
+------------+-----------+
NOW()
Funkcja NOW() zwraca zarówno datę, jak i czas systemowy (listing 12.25).
Listing 12.25. Przykład wywołania funkcji NOW(). Należy zwrócić uwagę, że nawet jeżeli funkcja
wywoływana jest bez parametrów, trzeba użyć nawiasów
SELECT NOW();
+---------------------+
| NOW() |
+---------------------+
| 2016-04-06 09:37:08 |
+---------------------+
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
14
DAYOFMONTH(), DAYOFWEEK(), DAYOFYEAR()
Funkcje DAYOFMONTH(), DAYOFWEEK(), DAYOFYEAR() zwracają numer dnia odpowiednio:
miesiąca (liczba z zakresu od 1 do 31), tygodnia (liczba z zakresu od 1 do 7, gdzie 1 oznacza niedzielę
— pierwszy dzień tygodnia, a 7 sobotę — siódmy dzień tygodnia) i roku (liczba z zakresu od 1 do 365)
(listing 12.26).
Listing 12.26. Lista zamówień złożonych w piątek
SELECT *
FROM orderinfo
WHERE DAYOFWEEK(date_placed) = 6;
+--------------+-------------+-------------+--------------+----------+
| orderinfo_id | customer_id | date_placed | date_shipped | shipping |
+--------------+-------------+-------------+--------------+----------+
| 2 | 8 | 2000-06-23 | 2000-06-23 | 0.00 |
| 5 | 8 | 2000-07-21 | 2000-07-24 | 0.00 |
+--------------+-------------+-------------+--------------+----------+
DAY(), MONTH(), YEAR()
Funkcje DAY(), MONTH(), YEAR() zwracają odpowiednio dzień, miesiąc i rok z daty przekazanej
jako parametr wywołania (listing 12.27).
Listing 12.27. Informacja o dacie zamówień rozbita na dni, miesiące i lata
SELECT date_placed, DAY(date_placed), MONTH (date_placed),
YEAR(date_placed)
FROM orderinfo;
+-------------+------------------+---------------------+-------------------+
| date_placed | DAY(date_placed) | MONTH (date_placed) | YEAR(date_placed) |
+-------------+------------------+---------------------+-------------------+
| 2000-03-13 | 13 | 3 | 2000 |
| 2000-06-23 | 23 | 6 | 2000 |
| 2000-09-02 | 2 | 9 | 2000 |
| 2000-09-03 | 3 | 9 | 2000 |
| 2000-07-21 | 21 | 7 | 2000 |
+-------------+------------------+---------------------+-------------------+
HOUR(), MINUTE(), SECOND()
Funkcje HOUR(), MINUTE(), SECOND() zwracają odpowiednio godziny, minuty i sekundy z czasu
przekazanego jako parametr wywołania (listing 12.28).
Listing 12.28. Informacja o bieżącym czasie rozbita na godziny, minuty i sekundy
SELECT HOUR(CURTIME()), MINUTE(CURTIME()), SECOND(CURTIME());
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
15
+-----------------+-------------------+-------------------+
| HOUR(CURTIME()) | MINUTE(CURTIME()) | SECOND(CURTIME()) |
+-----------------+-------------------+-------------------+
| 12 | 50 | 9 |
+-----------------+-------------------+-------------------+
DAYNAME(), MONTHNAME()
Funkcje DAYNAME(), MONTHNAME() zwracają nazwę dnia tygodnia i miesiąca daty będącej
argumentem wywołania (listing 12.29).
Listing 12.29. Opisowo przedstawione dni tygodnia i nazwy miesięcy
SELECT date_placed, DAYNAME(date_placed), MONTHNAME(date_placed)
FROM orderinfo;
+-------------+----------------------+------------------------+
| date_placed | DAYNAME(date_placed) | MONTHNAME(date_placed) |
+-------------+----------------------+------------------------+
| 2000-03-13 | Monday | March |
| 2000-06-23 | Friday | June |
| 2000-09-02 | Saturday | September |
| 2000-09-03 | Sunday | September |
| 2000-07-21 | Friday | July |
+-------------+----------------------+------------------------+
DATE_ADD()
Działanie funkcji DATE_ADD() powoduje obliczenie wyniku zmiany daty (podanej jako pierwszy
parametr) o ilość jednostek czasu określoną przez drugi parametr (listing 12.30).
Listing 12.30. Terminy zrealizowania zamówień zostały przesunięte o trzy dni
SELECT date_shipped, DATE_ADD(date_shipped, INTERVAL 3 DAY)
FROM orderinfo;
+--------------+----------------------------------------+
| date_shipped | DATE_ADD(date_shipped, INTERVAL 3 DAY) |
+--------------+----------------------------------------+
| 2000-03-17 | 2000-03-20 |
| 2000-06-23 | 2000-06-26 |
| 2000-09-12 | 2000-09-15 |
| 2000-09-10 | 2000-09-13 |
| 2000-07-24 | 2000-07-27 |
+--------------+----------------------------------------+
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
16
DATEDIFF()
Wynikiem działania funkcji DATEDIFF() jest liczba dni, które dzielą daty podane jako parametry
funkcji. Aby sprawdzić, ile dni upłynęło pomiędzy złożeniem i zrealizowaniem zamówienia, napiszemy
(listing 12.31):
Listing 12.31. Aliasy zdefiniowane w klauzuli SELECT nie mogą być użyte w innych klauzulach.
Zamiast tego musimy powtórzyć całe wyrażenie
SELECT orderinfo_id, DATEDIFF(date_shipped, date_placed) AS 'czas
realizacji'
FROM orderinfo
ORDER BY DATEDIFF(date_shipped, date_placed);
+--------------+-----------------+
| orderinfo_id | czas realizacji |
+--------------+-----------------+
| 2 | 0 |
| 5 | 3 |
| 1 | 4 |
| 4 | 7 |
| 3 | 10 |
+--------------+-----------------+
DATE_FORMAT(), TIME_FORMAT()
Funkcja DATE_FORMAT() pozwala formatować dane daty i czasu, funkcja TIME_FORMAT() pozwala
formatować wyłącznie informacje o czasie. Pierwszym parametrem obu funkcji jest data lub czas,
drugim — symbol docelowego formatu (tabela 12.1).
Tabela 12.1. Najczęściej stosowane formaty daty i czasu
Format Opis
%a Skrócona nazwa dnia tygodnia
%b Skrócona nazwa miesiąca
%c Jedno- lub dwucyfrowy numer miesiąca
%D Kolejny dzień miesiąca z angielskim przedrostkiem
%d Jedno- lub dwucyfrowy numer dnia miesiąca
%e Dwucyfrowy numer dnia miesiąca
%f Liczba milisekund
%H Godziny w notacji 24-godzinnej
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
17
%h Godziny w notacji 12-godzinnej
%i Minuty
%j Dzień roku
%M Nazwa miesiąca
%m Dwucyfrowy numer miesiąca
%p Symbol AM (łac. ante meridiem) lub PM (łac. post meridiem)
%r Czas w formacie hh:mm:ss uzupełniony o symbol AM lub PM
%S Sekundy
%T Czas w formacie hh:mm:ss
%U Tydzień (pierwszym dniem tygodnia jest niedziela)
%u Tydzień (pierwszym dniem tygodnia jest poniedziałek)
%W Nazwa dnia tygodnia
%w Dzień tygodnia
%Y Czterocyfrowy rok
%y Dwucyfrowy rok
Listing 12.32. pokazuje zastosowanie obu funkcji do formatowania danych daty i czasu.
Listing 12.32. Daty zrealizowania zamówień w oryginalnym i polskim formacie uzupełnione o
informacje o bieżącym czasie
SELECT date_shipped, DATE_FORMAT(date_shipped, '%D%M, %Y'),
time_format(curtime(),'%T')
FROM orderinfo;
+--------------+---------------------------------------+-----------------------------+
| date_shipped | DATE_FORMAT(date_shipped, '%D%M, %Y') | time_format(curtime(),'%T') |
+--------------+---------------------------------------+-----------------------------+
| 2000-03-17 | 17thMarch, 2000 | 13:13:01 |
| 2000-06-23 | 23rdJune, 2000 | 13:13:01 |
| 2000-09-12 | 12thSeptember, 2000 | 13:13:01 |
| 2000-09-10 | 10thSeptember, 2000 | 13:13:01 |
| 2000-07-24 | 24thJuly, 2000 | 13:13:01 |
+--------------+---------------------------------------+-----------------------------+
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
18
Funkcje konwersji
Piąta wersja serwera MySQL umożliwia definiowanie kolumn lub deklarowanie zmiennych różnych
typów:
1. Dane tekstowe (typy char, varchar, text) — mogą zawierać tekst lub kombinacje
tekstu i liczb, na przykład adres; mogą zawierać również liczby, na których nie są
przeprowadzane obliczenia, takie jak numery telefonów, numery katalogowe i kody
pocztowe.
2. Dane binarne (typy binary, varbinary, BLOB) — mogą zawierać dowolne dane. Mogą
to być zarówno długie teksty, jak i grafika czy pliki multimedialne.
3. Dane liczbowe (typy tinyint, smallint, mediumint, int, bigint, decimal,
float, double) — zawierają dane liczbowe, na których są przeprowadzane obliczenia,
przy czym dwa ostatnie typy są zmiennoprzecinkowe, czyli takie dane przechowywane są z
określoną dokładnością.
4. Daty (typy datetime, date, timestamp, time i year) — przechowują dane
dotyczące daty i czasu.
5. Dane logiczne (typy bool, boolean) — w MySQL-u są to synonimy typu tinyint, przy
czym 0 oznacza fałsz, a 1 — prawdę.
Prędzej czy później każdy administrator i programista baz danych będzie zmuszony porównać dane
różnych typów. Wynik porównania np. imienia Anna z liczbą 712 czy datą 2001-1-1 jest trudny do
przewidzenia. Aby takie porównanie było możliwe, trzeba najpierw przekonwertować porównywane
dane.
ASCII()
W wyniku działania funkcji ASCII() będzie zwrócony kod ASCII znaku podanego jako parametr
wywołania. Jeżeli jako parametr podamy ciąg znaków, za pomocą tej funkcji zostanie obliczony i
zwrócony kod ASCII pierwszego znaku w ciągu (listing 12.33).
Listing 12.33. Konwersja znaków na liczby
SELECT ASCII(lname), lname
FROM customer;
+--------------+---------+
| ASCII(lname) | lname |
+--------------+---------+
| 83 | Stones |
| 83 | Stones |
| 77 | Matthew |
| 77 | Matthew |
| 67 | Cozens |
| 77 | Matthew |
| 83 | Stones |
| 83 | Stones |
| 72 | Hickman |
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
19
| 72 | Howard |
| 74 | Jones |
| 78 | Neill |
| 72 | Hendy |
| 78 | Neill |
| 72 | Hudson |
| 87 | Wolski |
+--------------+---------+
CHR()
Działanie funkcji CHR() jest przeciwieństwem działania funkcji ASCII() — zamiast zamiany tekstu
na liczbę przeprowadza konwersję liczby na odpowiadające jej znaki kodu ASCII (listing 12.34).
Listing 12.34. Funkcję CHR() często stosuje się w celu „oszukania” prostych zabezpieczeń przed
iniekcją kodu
SELECT CHAR(77,121,83,81,'76');
+-------------------------+
| CHAR(77,121,83,81,'76') |
+-------------------------+
| MySQL |
+-------------------------+
BIN()
Funkcja BIN() zwraca binarną reprezentację podanej liczby dziesiętnej (listing 12.35).
Listing 12.35. Zmiana podstawy liczb
SELECT item_id, BIN(item_id)
FROM item;
+---------+--------------+
| item_id | BIN(item_id) |
+---------+--------------+
| 1 | 1 |
| 2 | 10 |
| 3 | 11 |
| 4 | 100 |
| 5 | 101 |
| 6 | 110 |
| 7 | 111 |
| 8 | 1000 |
| 9 | 1001 |
| 10 | 1010 |
| 11 | 1011 |
| 12 | 1100 |
+---------+--------------+
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
20
CAST()
Funkcja CAST() pozwala przekonwertować (rzutować) dane przekazane jako pierwszy parametr
wywołania na typ podany jako drugi parametr funkcji (listing 12.36).
Listing 12.36. CAST() jest najbardziej uniwersalną funkcją konwersji
SELECT CAST('2001-1-1' AS date);
+--------------------------+
| CAST('2001-1-1' AS date) |
+--------------------------+
| 2001-01-01 |
+--------------------------+
Funkcje serwera MySQL
Kilka funkcji kryptograficznych dostępnych w serwerze MySQL.
ENCODE(), DECODE()
Funkcja ENCODE() zwraca szyfrogram podanego ciągu znaków. Do szyfrowania używane jest hasło
podane jako drugi parametr wywołania (listing 12.37). Funkcja DECODE() deszyfruje zaszyfrowane
funkcją ENCODE() szyfrogramy.
Listing 12.37. Poufne dane lepiej przechowywać w bazie w postaci zaszyfrowanej
SELECT ENCODE('Pin do karty VISA GOLD to 3478','h@ssL0');
+---------------------------------------------------+
| ENCODE('Pin do karty VISA GOLD to 3478','h@ssL0') |
+---------------------------------------------------+
| ☻ćň5)KÂW▬┘őu |
+---------------------------------------------------+
SHA1()
Funkcja SHA1() wylicza sygnaturę podanego ciągu znaków (listing 12.38).
Listing 12.38. W niektórych przypadkach trzeba móc potwierdzić autentyczność danych. Najlepiej
wykorzystać do tego funkcję mieszania
SELECT SHA1(sell_price)
FROM item;
+------------------------------------------+
| SHA1(sell_price) |
+------------------------------------------+
| d593b090a756bf12bb1b40e50d03db971d90865a |
| 366091419860e27172808dce4b1be574bb51c5fe |
| 03f82d768c8366b01cc7366f3c2628e0ec9a8021 |
E.14 – Bazy Danych – cz. 12 – SQL – Wybrane funkcje serwera MySQL
21
| 70d403dc3c9428c27b2da0056c4702e424c928b1 |
| 8818c759d88e34a1184655ed00ae1a44121aabd5 |
| 3194b173d1f5e493d10d8fe69cdbb6a9ae218c0e |
| 866de6c5b3f877858098c63bd9f5fb67b3616736 |
| 2792cf2449e7d1a4a46d0b78eb2caeb99e78a396 |
| 953e85433144f4cec72744beca1c8eeb898df5d8 |
| 22cf82b68b95049bffb91128349ccc312a460b10 |
| 139fb724c5c37892cb113d2866672b67e9a90ff9 |
| NULL |
+------------------------------------------+
PASSWORD()
Hasła użytkowników muszą być chronione, a to oznacza, że nigdy nie należy zapisywać ich w bazie w
jawnej postaci. Prawie zawsze hasło wykorzystywane jest jedynie do potwierdzenia tożsamości
użytkownika, a do tego celu serwer baz danych nie musi odszyfrować hasła, czyli hasła powinny być
zapisane nieodwracalnie zaszyfrowane. Wiemy już, że tak działają funkcje mieszania — hasła do
serwera MySQL też są tak przechowywane, z tym że do ich wyliczenia i późniejszego porównania
wykorzystywana jest funkcja PASSWORD() (listing 12.39).
Listing 12.39. Do sprawdzania tożsamości należy używać sygnatur haseł, nie samych haseł
SELECT fname, lname
FROM customer
WHERE PASSWORD (fname) = '*773326F7387809AEE1566F9BEDE2DEE006776333';
+-----------------+
| fname | lname |
+-----------------+
| Alex | Matthew |
+-----------------+
SELECT PASSWORD ('Jenny');
+-------------------------------------------+
| PASSWORD ('Jenny') |
+-------------------------------------------+
| *B2D8022EC63D192D46A9C6E8F651C37B4BC163A6 |
+-------------------------------------------+
SELECT fname, lname
FROM customer
WHERE PASSWORD (fname) = '*B2D8022EC63D192D46A9C6E8F651C37B4BC163A6';
+----------------+
| fname | lname |
+----------------+
| Jenny | Stones |
+----------------+