Bazy Danych W06 Wojciech St. Mościbrodzki wojmos@wojmos.com
Wybrane funkcje wbudowane
Najważniejsze funkcje operujące na łańcuchach ASCII() Konwersja znaku na kod (odwrotnie: ORD()) mysql> SELECT ASCII('2'); -> 50 mysql> SELECT ASCII(2); mysql> SELECT ASCII('dx'); -> 100 BIN() Konwersja liczby zapisanej jako tekst na system binarny mysql> SELECT BIN(12); -> '1100' BIN_LENGTH() zwraca długość łancucha (w bitach!) mysql> SELECT BIT_LENGTH('text'); -> 32
Najważniejsze funkcje operujące na łańcuchach CHAR() – konwersja argumentów (int) na sklejony łańcuch mysql> SELECT CHAR(77,121,83,81,'76'); -> 'MySQL' mysql> SELECT CHAR(77,77.3,'77.3'); -> 'MMM' CHAR(int USING str) – konwersja z użyciem zestawu znaków mysql> SELECT CHARSET(CHAR(0x65)), CHARSET(CHAR(0x65 USING utf8)); +---------------------+--------------------------------+ | CHARSET(CHAR(0x65)) | CHARSET(CHAR(0x65 USING utf8)) | | latin1 | utf8 | CHAR_LENGTH() – długość łańcucha mysql> SELECT CHAR_LENGTH('ABC'); -> 3
Najważniejsze funkcje operujące na łańcuchach CONCAT() – skleja łańcuchy mysql> SELECT CONCAT('My', 'S', 'QL'); -> 'MySQL' mysql> SELECT CONCAT('My', NULL, 'QL'); -> NULL mysql> SELECT CONCAT(14.3); -> '14.3' CONCAT() – wersja skrócona: mysql> SELECT 'My' 'S' 'QL'; -> 'MySQL' CONCAT_WS() – wersja z separatorem: mysql> SELECT CONCAT_WS(',','First name','Second name','Last Name'); -> 'First name,Second name,Last Name' mysql> SELECT CONCAT_WS(',','First name',NULL,'Last Name'); -> 'First name,Last Name'
Najważniejsze funkcje operujące na łańcuchach ELT(int, str, str, …) – podaje n-ty element z listy mysql> SELECT ELT(1, 'ej', 'Heja', 'hej', 'foo'); -> 'ej' mysql> SELECT ELT(4, 'ej', 'Heja', 'hej', 'foo'); -> 'foo' FIND(str, str1, str2…) – podaje pozycję str w liście str1, str2… mysql> SELECT FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo'); -> 2 mysql> SELECT FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo'); -> 0 FORMAT(X, D) – formatuje x do D miejsc dziesiętnych (z sep.) mysql> SELECT FORMAT(12332.123456, 4); -> '12,332.1235' mysql> SELECT FORMAT(12332.1,4); -> '12,332.1000' mysql> SELECT FORMAT(12332.2,0); -> '12,332'
Najważniejsze funkcje operujące na łańcuchach HEX(int) – konwersja na system szesnastkowy mysql> SELECT HEX(255), CONV(HEX(255),16,10); -> 'FF', 255 HEX(str) – konwersja STRINGU na reprezentację szesnastkową ysql> SELECT 0x616263, HEX('abc'), UNHEX(HEX('abc')); -> 'abc', 616263, 'abc' INSERT() – wstawianie do łańcucha mysql> SELECT INSERT('Quadratic', 3, 4, 'What'); -> 'QuWhattic' mysql> SELECT INSERT('Quadratic', -1, 4, 'What'); -> 'Quadratic' mysql> SELECT INSERT('Quadratic', 3, 100, 'What'); -> 'QuWhat' INSTR() – wyszukiwanie w łańcuchu mysql> SELECT INSTR('foobarbar', 'bar'); -> 4
Najważniejsze funkcje operujące na łańcuchach LEFT() – wycinanie lewej części łańcucha mysql> SELECT LEFT('foobarbar', 5); -> 'fooba' LENGTH() – podaje długość łańcucha w bajtach (multibajty!) mysql> SELECT LENGTH('text'); -> 4 mysql> SELECT LENGTH('ąść'); -> 6 LOAD_FILE() – zwraca plik dyskowy mysql> UPDATE t SET blob_col=LOAD_FILE('/tmp/picture') WHERE id=1;
Najważniejsze funkcje operujące na łańcuchach LOWER() – zmniejszenie znaków (łańcuch nie może być binarny!) mysql> SET @str = BINARY 'New York'; mysql> SELECT LOWER(@str), LOWER(CONVERT(@str USING latin1)); +-------------+-----------------------------------+ | LOWER(@str) | LOWER(CONVERT(@str USING latin1)) | | New York | new york | LTRIM() – obcinanie znaków spacji po lewej stronie mysql> SELECT LTRIM(' barbar'); -> 'barbar' ORD() – podaje kod znaku (znaków) mysql> SELECT ORD('2'); -> 50 REPEAT() – powtarza sekwencję mysql> SELECT REPEAT('MySQL', 3); -> 'MySQLMySQLMySQL'
Najważniejsze funkcje operujące na łańcuchach REVERSE() – odwraca łańcuch mysql> SELECT REVERSE('abc'); -> 'cba' RTRIM() – usuwa nadmiarowe spacje z prawej strony mysql> SELECT RTRIM('barbar '); -> 'barbar' SPACE() – tworzy n spacji mysql> SELECT SPACE(6); -> ' ' TRIM() – usuwa wybrane znaki mysql> SELECT TRIM(' bar '); -> 'bar' mysql> SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx'); -> 'barxxx' mysql> SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx'); mysql> SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz'); -> 'barx'
Najważniejsze funkcje operujące na łańcuchach SUBSTRING() – wyszukiwanie w łańcuchu mysql> SELECT SUBSTRING('Quadratically',5); -> 'ratically' mysql> SELECT SUBSTRING('foobarbar' FROM 4); -> 'barbar' mysql> SELECT SUBSTRING('Quadratically',5,6); -> 'ratica' mysql> SELECT SUBSTRING('Sakila', -3); -> 'ila' mysql> SELECT SUBSTRING('Sakila', -5, 3); -> 'aki' mysql> SELECT SUBSTRING('Sakila' FROM -4 FOR 2); -> 'ki' UPPER() – odwrotnie do LOWER() mysql> SELECT UPPER('Hej'); -> 'HEJ'
Funkcje czasu i daty w SQL/MySQL
Kalendarz juliański, kalendarz gregoriański Kalendarz juliański – opracowany na życzenie Juliusza Cezara, zastąpił kalendarz księżycowy, wprowadzony 45 pne Kalendarz solarny Wprowadził poprawkę niwelującą błędy (jeden miesiąc w 46 roku wydłużono o 90 dni) 365 dni + 1 dzień przestępny co 4 lata (początkowo co 3 lata) Opóźnienie 1 dzień na 128 lat Kalendarz gregoriański – wprowadzony bullą Inter gravissimas przez papieża Grzegorza XIII. Wprowadził poprawkę niwelującą błędy juliańskie (10 brakujących dni) Opóźnienie 1 dzień na 3322 lata Lata przestępne: co 4 lata z wyjątkiem lat podzielnych przez 100, ale niepodzielnych przez 400
Kalendarz juliański, kalendarz gregoriański
Funkcje daty i czasu ADDDATE(date,INTERVAL expr unit) – dodaje odstęp do daty mysql> SELECT DATE_ADD('2008-01-02', INTERVAL 31 DAY); -> '2008-02-02'
Funkcje daty i czasu ADDTIME(date,INTERVAL expr unit) – dodaje odstęp do daty mysql> SELECT ADDTIME('2007-12-31 23:59:59.999999', '1 1:1:1.000002'); -> '2008-01-02 01:01:01.000001' mysql> SELECT ADDTIME('01:00:00.999999', '02:00:00.999998'); -> '03:00:01.999997'
Funkcje daty i czasu CONVERT_TZ(dt,from_tz,to_tz) – konwersja na strefę czasową mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET'); -> '2004-01-01 13:00:00' mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00'); -> '2004-01-01 22:00:00' CURDATE() – aktualna data mysql> SELECT CURDATE(); -> '2008-06-13' mysql> SELECT CURDATE() + 0; -> 20080613 CURTIME() – aktualny czas mysql> SELECT CURTIME(); -> '23:50:26' mysql> SELECT CURTIME() + 0; -> 235026.000000
Funkcje daty i czasu CURTIMESTAMP() – aktualny czas (zamiennik dla NOW()) mysql> SELECT NOW(); -> '2007-12-15 23:50:26' mysql> SELECT NOW() + 0; -> 20071215235026.000000 DATE() – podaje jedynie część "data" mysql> SELECT DATE('2003-12-31 01:02:03'); -> '2003-12-31' DATEDIFF() – podaje różnicę w dacie (tylko część "data") mysql> SELECT DATEDIFF('2007-12-31 23:59:59','2007-12-30'); -> 1 mysql> SELECT DATEDIFF('2010-11-30 23:59:59','2010-12-31'); -> -31
Funkcje daty i czasu DATE_FORMAT() mysql> SELECT 22:23:00', '%W %M %Y'); -> 'Sunday October 2009' mysql> SELECT DATE_FORMAT('2007-10-04 22:23:00', -> '%H:%i:%s'); -> '22:23:00' mysql> SELECT DATE_FORMAT('1900-10-04 22:23:00', -> '%D %y %a %d %m %b %j'); -> '4th 00 Thu 04 10 Oct 277' mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', -> '%H %k %I %r %T %S %w'); -> '22 22 10 10:23:00 PM 22:23:00 00 6' mysql> SELECT DATE_FORMAT('1999-01-01', -> '%X %V'); -> '1998 52' mysql> SELECT DATE_FORMAT('2006-06-00', -> '%d'); -> '00'
Funkcje daty i czasu DAYNAME() – podaje nazwę dnia mysql> SELECT DAYNAME('2007-02-03'); -> 'Saturday' DAYNAME() – podaje numer dnia w standardzie ODBC mysql> SELECT DAYOFWEEK('2007-02-03'); -> 7 EXTRACT() – podaje odpowiednią część daty mysql> SELECT EXTRACT(YEAR FROM '2009-07-02'); -> 2009 mysql> SELECT EXTRACT(YEAR_MONTH FROM '2009-07-02 01:02:03'); -> 200907 mysql> SELECT EXTRACT(DAY_MINUTE FROM '2009-07-02 01:02:03'); -> 20102 mysql> SELECT EXTRACT(MICROSECOND FROM '2003-01-02 10:30:00.000123'); -> 123
Funkcje daty i czasu FROMDAYS() – podaje datę na podstawie numeru dnia mysql> SELECT FROM_DAYS(730669); -> '2007-07-03' FROM_UNIXTIME() – podaje datę we timestamp unixa mysql> SELECT FROM_UNIXTIME(1196440219); -> '2007-11-30 10:30:19' mysql> SELECT FROM_UNIXTIME(1196440219) + 0; -> 20071130103019.000000 mysql> SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(), -> '%Y %D %M %h:%i:%s %x'); -> '2007 30th November 10:30:59 2007' HOUR() – podaje godzinę mysql> SELECT HOUR('10:05:03'); -> 10
Funkcje daty i czasu LASTDAY () – podaje ostatni dzień wskazanego miesiąca mysql> SELECT LAST_DAY('2003-02-05'); -> '2003-02-28' mysql> SELECT LAST_DAY('2004-02-05'); -> '2004-02-29' mysql> SELECT LAST_DAY('2004-01-01 01:01:01'); -> '2004-01-31' mysql> SELECT LAST_DAY('2003-03-32'); -> NULL MAKEDATE () – podaje utworzoną datę mysql> SELECT MAKEDATE(2011,31), MAKEDATE(2011,32); -> '2011-01-31', '2011-02-01' mysql> SELECT MAKEDATE(2011,365), MAKEDATE(2014,365); -> '2011-12-31', '2014-12-31' mysql> SELECT MAKEDATE(2011,0); -> NULL
Funkcje daty i czasu MONTHNAME() – podaje nazwę miesiąca mysql> SELECT MONTHNAME('2008-02-03'); -> 'February' NOW() – aktualny timestamp mysql> SELECT NOW(); -> '2007-12-15 23:50:26' mysql> SELECT NOW() + 0; -> 20071215235026.000000 QUARTER() – podaje nazwę kwartału mysql> SELECT QUARTER('2008-04-01'); -> 2 SEC_TO_TIME() – zmienia sekundy na godzinę mysql> SELECT SEC_TO_TIME(2378); -> '00:39:38'
Funkcje daty i czasu STR_TO_DATE() – zamienia łańcuch na datę mysql> SELECT STR_TO_DATE('01,5,2013','%d,%m,%Y'); -> '2013-05-01' mysql> SELECT STR_TO_DATE('May 1, 2013','%M %d,%Y'); mysql> SELECT STR_TO_DATE('a09:30:17','a%h:%i:%s'); -> '09:30:17' mysql> SELECT STR_TO_DATE('a09:30:17','%h:%i:%s'); -> NULL mysql> SELECT STR_TO_DATE('abc','abc'); -> '0000-00-00' mysql> SELECT STR_TO_DATE('9','%m'); -> '0000-09-00' mysql> SELECT STR_TO_DATE('9','%s'); -> '00:00:09'
Wbudowane funkcje kontroli sterowania (uwaga: nie mylić z instrukcjami kontroli sterowania) FUNKCJE STEROWANIA – używamy w SQL INSTRUKCJE STEROWANIA – używamy w procedurach
Funkcje sterowania IF(expr1, expr2, expr3) – jak IF w Excelu mysql> SELECT IF(1>2,2,3); -> 3 mysql> SELECT IF(1<2,'yes','no'); -> 'yes' mysql> SELECT IF(STRCMP('test','test1'),'no','yes'); -> 'no' mysql> SELECT IF(0.1,1,0); -> 0 mysql> SELECT IF(0.1<>0,1,0); -> 1 IFNULL(expr1, expr2) – sprawdzenie, czy NULL mysql> SELECT IFNULL(1,0); -> 1 mysql> SELECT IFNULL(NULL,10); -> 10 mysql> SELECT IFNULL(1/0,10); mysql> SELECT IFNULL(1/0,'yes'); -> 'yes'
Funkcje sterowania CASE – wersja 1: zwraca result, jeżeli value=compare_value CASE value WHEN [compare_value] THEN result [WHEN [compare_value] THEN result ...] [ELSE result] END CASE – wersja 2: zwraca result, dla pierwszego spełnionego warunku CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END mysql> SELECT CASE 1 -> WHEN 1 THEN 'one' -> WHEN 2 THEN 'two' -> ELSE 'more' END; -> 'one' mysql> SELECT CASE WHEN 1>0 THEN 'true' ELSE 'false' END; -> 'true' mysql> SELECT CASE BINARY 'B' -> WHEN 'a' THEN 1 WHEN 'b' THEN 2 END; -> NULL
Problemy związane z językami lokalnymi
Character set Character set – zestaw znaków wraz z kodowaniem 1 A 6 B 2 Ą 3 4 2 3 5 Zestaw znaków zawiera wszystkie możliwe symbole wraz z ich kodami. Dwom różnym symbolom (np. "a" i "A") odpowiadają zawsze dwa różne kody. Należy rozróżnić symbol od kodu, nawet jeśli "wyglądają" podobnie. Innymi słowy symbolowi "2" może odpowiadać kod 2 (albo inny).
Zestawy znaków i porównania Sprawdzenie dostępnych zestawów znaków: mysql> SHOW CHARACTER SET; +----------+-----------------------------+---------------------+--------+ | Charset | Description | Default collation | Maxlen | | big5 | Big5 Traditional Chinese | big5_chinese_ci | 2 | | dec8 | DEC West European | dec8_swedish_ci | 1 | | cp850 | DOS West European | cp850_general_ci | 1 | | hp8 | HP West European | hp8_english_ci | 1 | | koi8r | KOI8-R Relcom Russian | koi8r_general_ci | 1 | | latin1 | cp1252 West European | latin1_swedish_ci | 1 | | latin2 | ISO 8859-2 Central European | latin2_general_ci | 1 | | swe7 | 7bit Swedish | swe7_swedish_ci | 1 | | ascii | US ASCII | ascii_general_ci | 1 | ...
Collation - porównanie Collation to metoda porównywania symboli. a 1 A 6 B 2 3 ż 4 z ź 5 Dla każdego zestawu znaków zawsze istnieje najprostsze porównanie: symbole są różne, jeśli różne są ich kody. Jest to tzw. Porównanie binarne. Przykład innego porównania (collation): a 1 A 6 B 2 3 ż 4 z ź 5
Collation Sprawdzenie dostępnych porównań: mysql> SHOW COLLATION LIKE 'latin1%'; +-------------------+---------+----+---------+----------+---------+ | Collation | Charset | Id | Default | Compiled | Sortlen | | latin1_german1_ci | latin1 | 5 | | | 0 | | latin1_swedish_ci | latin1 | 8 | Yes | Yes | 0 | | latin1_danish_ci | latin1 | 15 | | | 0 | | latin1_german2_ci | latin1 | 31 | | Yes | 2 | mysql> SHOW COLLATION WHERE `Default` = 'Yes'; +---------------------+----------+----+---------+----------+---------+ | Collation | Charset | Id | Default | Compiled | Sortlen | | big5_chinese_ci | big5 | 1 | Yes | Yes | 1 | | dec8_swedish_ci | dec8 | 3 | Yes | Yes | 1 | | cp850_general_ci | cp850 | 4 | Yes | Yes | 1 | | hp8_english_ci | hp8 | 6 | Yes | Yes | 1 | | koi8r_general_ci | koi8r | 7 | Yes | Yes | 1 | | latin1_swedish_ci | latin1 | 8 | Yes | Yes | 1 |
Ustawianie lokalizacji domyślnej Dla całego serwera: mysqld --character-set-server=latin1 ./configure --with-charset=latin1 Dla określonej bazy danych: CREATE DATABASE db_name [[DEFAULT] CHARACTER SET charset_name] [[DEFAULT] COLLATE collation_name] ALTER DATABASE db_name [[DEFAULT] CHARACTER SET charset_name] [[DEFAULT] COLLATE collation_name] Dla tabeli: CREATE TABLE tbl_name (column_list) [[DEFAULT] CHARACTER SET charset_name] [COLLATE collation_name]] ALTER TABLE tbl_name [[DEFAULT] CHARACTER SET charset_name] [COLLATE collation_name]
Ustawianie lokalizacji domyślnej Dla kolumny w tabeli: CREATE TABLE t1 ( col1 VARCHAR(5) CHARACTER SET latin1 COLLATE latin1_german1_ci ); ALTER TABLE t1 MODIFY col1 VARCHAR(5) CHARACTER SET latin1 COLLATE latin1_swedish_ci; Uwaga: zmiana zestawu znaków dla tabeli/kolumny/bazy, w której istnieją dane może doprowadzić do utraty danych
Procedury i funkcje (kontynuacja)
Własne funkcje SHOW PROCEDURE/FUNCTION STATUS mysql> show function status; +-----------+---------+----------+----------------+---------------------+---------------------+---------------+---------+ | Db | Name | Type | Definer | Modified | Created | Security_type | Comment | | poligon | nazwa | FUNCTION | root@localhost | 2009-12-10 21:36:12 | 2009-12-10 21:36:12 | DEFINER | | | populacja | exp2lvl | FUNCTION | root@localhost | 2009-08-21 16:35:32 | 2009-08-21 16:35:32 | DEFINER | | 2 rows in set (0.00 sec) mysql> show function status; +-----------+---------+----------+----------------+ | Db | Name | Type | Definer | | poligon | nazwa | FUNCTION | root@localhost | | populacja | exp2lvl | FUNCTION | root@localhost |
Budowa obiektów składowanych - zmienne Zmienne w programach składowanych zmienne sesyjne zmienne lokalne (dla bloków BEGIN-END) Zmienne lokalne: deklarowane za pomocą DECLARE muszą być deklarowane istnieją tylko w kontekście swoich bloków nie wymagają używania @ mogą być ustawiane za pomocą SET mogą być ustawiane za pomocą SELECT i SELECT INTO
Zmienne w obiektach składowanych Zliczamy byty o podanym imieniu w 2 tablicach CREATE PROCEDURE Sample(IN parametr char(30)) BEGIN DECLARE x1 CHAR(30) DEFAULT 0; DECLARE x2 CHAR(30) DEFAULT 0; SELECT count(*) into x1 FROM czlowiek where imie like parametr; SELECT count(*) into x2 FROM pracownik where i like parametr; select x1 as czlowiek, x2 as pracownik; END; mysql> call sample('jan'); +----------+-----------+ | czlowiek | pracownik | | 0 | 3 | 1 row in set (0.00 sec)
INSTRUKCJE sterowania (nie mylić z FUNKCJAMI) Funkcje sterowania są zwykłymi funkcjami SQL IF(), CASE(), IFNULL(), NULLIF() Instrukcje sterowania są przeznaczone tylko dla obiektów składowanych. Oczywiście w obiektach składowanych MOŻNA używać również funkcji sterowania IF, CASE, LOOP, LEAVE, ITERATE, REPEAT, WHILE
Instrukcja IF Instrukcja IF IF search_condition THEN statement_list [ELSEIF search_condition THEN statement_list] ... [ELSE statement_list] END IF CREATE PROCEDURE Sample(IN parametr char(30)) BEGIN IF parametr='Jan' THEN SELECT ('Janek!') as wynik; ELSE SELECT ('NIE Janek?') as wynik; END IF; END; mysql> call sample('Jan'); +--------+ | wynik | | Janek! | mysql> call sample('Janusz'); +------------+ | wynik | | NIE Janek? |
Instrukcja IF IF z wykorzystaniem bloku BEGIN-END DROP PROCEDURE IF EXISTS Sample; DELIMITER ;; CREATE PROCEDURE Sample(IN parametr char(30)) BEGIN IF parametr='Jan' THEN SELECT ('Janek!') as wynik; SELECT ('Kope lat!') as wynik; END; ELSE SELECT ('NIE Janek?') as wynik; END IF; ;; DELIMITER ;
Instrukcja CASE Instrukcja CASE mysql> call sample(1); +------------+ | JEDEN | Instrukcja CASE CASE case_value WHEN when_value THEN statement_list [WHEN when_value THEN statement_list] ... [ELSE statement_list] END CASE mysql> call sample(2); +------------+ | DWA | CREATE PROCEDURE Sample(IN parametr int) BEGIN CASE parametr WHEN 1 THEN SELECT('JEDEN'); WHEN 2 THEN SELECT('DWA'); ELSE SELECT ('MNOSTWO!!!'); END; END CASE; mysql> call sample(5); +------------+ | MNOSTWO!!! |
Instrukcje LOOP i LEAVE LOOP jest pętlą nieskończoną, z której wyjście zapewnia LEAVE nie jest to rozwiązanie "eleganckie" [begin_label:] LOOP statement_list END LOOP [end_label] mysql> call sample(3); +------------+ | (parametr) | | 3 | 1 row in set (0.00 sec) | 11 | CREATE PROCEDURE Sample(IN parametr int) BEGIN select (parametr); petla: LOOP IF parametr>10 THEN LEAVE petla; END IF; SET parametr = parametr + 1; END LOOP; END;
Instrukcje LOOP i LEAVE REPEAT jest pętlą warunkową, która wykonuje się minimum 1 raz [begin_label:] REPEAT statement_list UNTIL search_condition END REPEAT [end_label] mysql> call sample(8); +------------+ | (parametr) | | 8 | 1 row in set (0.00 sec) | 9 | | 10 | CREATE PROCEDURE Sample(IN parametr int) BEGIN REPEAT select (parametr); SET parametr = parametr + 1; UNTIL parametr>10 END REPEAT; END;
Instrukcje LOOP i LEAVE mysql> call sample(4); +------+ | (n) | | 0 | | 1 | | 2 | | 3 | 1 row in set (0.00 sec) WHILE jest typową pętlą warunkową [begin_label:] WHILE search_condition DO statement_list END WHILE [end_label] CREATE PROCEDURE Sample(IN parametr int) BEGIN DECLARE n INT; SET n = 0; WHILE n<parametr DO select (n); SET n = n + 1; END WHILE; END;
Wykorzystanie obiektów składowanych CREATE PROCEDURE MakeCzlowiek() BEGIN DECLARE ile_sylab INT; DECLARE nazwisko char(50) default ''; DECLARE imie1 char(50) default ''; DECLARE temp char(10) default ''; select 2+CAST(2*rand() as signed) into ile_sylab; while (ile_sylab>0) do select dana into temp from sylaba order by rand() limit 1; set nazwisko := concat(nazwisko,temp); set ile_sylab := ile_sylab - 1; end while; set nazwisko := concat(nazwisko,'cki'); set nazwisko := concat(ucase(substring(nazwisko,1,1)),substring(nazwisko,2)); select dana into imie1 from imie order by rand() limit 1; SELECT nazwisko; insert into czlowiek(imie, nazwisko) values (imie1, nazwisko); END; mysql> call MakeCzlowiek(); select * from czlowiek; +-------------+ | Nazanacki |
Wykorzystanie obiektów składowanych DROP PROCEDURE IF EXISTS MakeLudzie; DELIMITER ;; CREATE PROCEDURE MakeLudzie(IN ilu int) BEGIN delete from czlowiek; while (ilu>0) do call MakeCzlowiek(); set ilu := ilu - 1; end while; select count(*) as ilu_mamy_ludzi from czlowiek; END; ;; DELIMITER ; mysql> call MakeLudzie(100); +----------------+ | ilu_mamy_ludzi | | 100 | 1 row in set (0.06 sec)
TRIGGER – specyficzna stored procedure TRIGGER – funkcja składowana wywoływana automatycznie, przez serwer po zaistnieniu pewnego zdarzenia TRIGGER (wyzwalacz) jest więc swego rodzaju event guardianem obiekt standardowy SQL99 update licznik set imie_ile=select count(*) from imie +----------------+ | imie | |Jan | |Tadeusz | |Piotr | |Kacper | mysql> insert into imie values ('Czesio')
Klasyfikacja TRIGGERÓW Triggery (wyzwalacze) możemy podzielić: według kryterium czasu: triggery BEFORE triggery AFTER triggery INSTEAD OF (rzadko implementowane) według kryterium rodzaju operacji (związek z type operacji, a nie poleceniem!) triggery ON INSERT (działa także w przypadku LOAD DATA) triggery ON DELETE triggery ON UPDATE według kryterium obiektu strzeżonego triggery modyfikacji danych triggery modyfikacji struktury (trigger ALTER, DROP) triggery eventowe (trigger LOGIN)
Budowa TRIGGERA Ogólna postać: Prawa (MySql): CREATE [DEFINER = { user | CURRENT_USER }] TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EACH ROW trigger_stmt delimiter | CREATE TRIGGER testref BEFORE INSERT ON test1 FOR EACH ROW BEGIN UPDATE test4 SET b4 = b4 + 1 WHERE a4 = 3; END; | delimiter ; Prawa (MySql): tworzenie triggerów wymaga praw TRIGGER dla danej tablicy (wcześniej: prawo globalne SUPER)
obiekty NEW i OLD Obiekty przechowujące wartość poprzednią i nową: create table t1 (id int, auto_increment primary key, liczba int); create table historia (z char(100), stamp timestamp) delimiter | CREATE TRIGGER moj1 AFTER UPDATE ON t1 FOR EACH ROW BEGIN INSERT INTO history(z) values (CONCAT(OLD.liczba,'->',NEW.liczba)); END; | delimiter ; update t1 set liczba=2 where id=1; insert into t1(liczba) values (222);
Obiekty OLD i NEW MySQL ułatwia wywołania obiektów poprzez nadanie im nazw delimiter | CREATE TRIGGER pensja_trigger BEFORE UPDATE ON pracownicy_table REFERENCING NEW ROW AS n, OLD ROW AS o FOR EACH ROW IF n.pensja <> o.pensja THEN --wykonaj odpowiednie działania; END IF; delimiter ;
Bezpieczniejsze tworzenie triggerów DROP TRIGGER IF EXISTS moj1; delimiter | CREATE TRIGGER moj1 AFTER UPDATE ON t1 FOR EACH ROW BEGIN INSERT INTO history (zapis) values (3); END; | delimiter ;
Indeks Indeks jest pomocniczą strukturą nakładaną na tabelę (ściślej: kolumnę lub grupę kolumn), służącą polepszaniu efektywności wyszukiwania. Indeksy pogarszają efektywność operacji udpate, delete i insert. CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [index_type] ON tbl_name (index_col_name,...) [index_type] index_col_name: col_name [(length)] [ASC | DESC] index_type: USING {BTREE | HASH}
Indeksy w MySQL Silnik MySQL używa indeksów zwłaszcza do: Generowania wyników klauzuli WHERE Eliminowania krotek (DISTINCT) Generowania wyników JOIN (warto zadbać, aby indeksy były tego samego typu i wielkości – co ma znaczenie przy indeksach tekstowych) Generowania agregatów MIN i MAX Do sortowania za pomocą ORDER BY Uwaga: MySQL używa własnego algorytmu estymacji efektywności indeksów Każdy klucz główny jest indeksowany
Indeksy typu HASH i indeksy typu B-TREE Indeksy zbudowane na drzewach są bardziej elastyczne (dlatego są domyślnym typem) Z uwagi na budowę, indeks typu HASH: Może pracować tylko dla porównań >= <= oraz = (ale za to jest bardzo szybki) Nie przyspiesza sortowania z użyciem ORDER BY (bo nie daje możliwości "znalezienia następnego") Nie może ocenić ilości danych pomiędzy granicami wyszukiwania (BETWEEN) Indeksuje jedynie całą wartość klucza
TEXT i BLOB BLOB (Binary Large OBject) to typ danych służący do przechowywania dużych obiektów binarnych. TEXT to duże obiekty tekstowe (używają charsetu!) CREATE TABLE picture ( ID INTEGER AUTO_INCREMENT, IMAGE BLOB, PRIMARY KEY (ID) ) ENGINE=InnoDB;
Projektowanie baz danych jako proces ETAPY: Ustalenie wymagań odbiorcy Modelowanie konceptualne Modelowanie logiczne Modelowanie fizyczne Realizacja bazy danych Testowanie i walidacja
Problem Mentalna percepcja świata rzeczywistego Model pojęciowy Schemat relacyjnej struktury danych