Bazy Danych Programowanie w SQL Wojciech St. Mościbrodzki

Slides:



Advertisements
Podobne prezentacje
Copyright © The OWASP Foundation Permission is granted to copy, distribute and/or modify this document under the terms of the OWASP License. The OWASP.
Advertisements

Java Data Objects.
Projekt Do kariery na skrzydłach – studiuj Aviation Management Projekt współfinansowany ze ś rodków Europejskiego Funduszu Społecznego. Biuro projektu:
Introduction to SystemC
Procedury wyzwalane Procedura wyzwalana (ang. trigger) - stanowi kod użytkownika przechowywany wewnątrz bazy i uruchamiany w określonych sytuacjach np.
Pomysł Sukces Wstępne rozwiązanie Symulacja Wynik zadowala? Poprawa rozwiązania Nie Tak Podstawowa pętla projektowania.
Analiza wywołania i przebiegu przerwań w systemie Linux
Skrypty, procedury przechowywane i wyzwalane
Projekt Do kariery na skrzydłach – studiuj Aviation Management Projekt współfinansowany ze ś rodków Europejskiego Funduszu Społecznego. Biuro projektu:
Projekt Do kariery na skrzydłach – studiuj Aviation Management Projekt współfinansowany ze ś rodków Europejskiego Funduszu Społecznego. Biuro projektu:
ALLEGRO PIERWSZA GRA: WYŚCIG
Język SQL Część II.
Grupowanie wielowymiarowe w MS SQL
Bazy danych 8. SQL podstawy P. F. Góra semestr letni 2004/05.
PHP + MySQL część II.
Rekursja Teoretyczne podstawy informatyki Wykład 5
Dzielenie relacyjne / Relational Division
Metody autoryzacji użytkowników wymaga integracji z systemem operacyjnym nie wymaga logowania mała pewność mechanizmu wymaga logowania duża pewność mechanizmu.
Bezpieczeństwo Procedury składowane Funkcje i Wyzwalacze
ZSBD PL/SQL CZĘŚĆ 3 Wykład 5 Prowadzący: dr Paweł Drozda.
WYZWALACZE (TRIGGERY) Wyzwalacz jest specjalnym rodzajem procedury składowanej, która może być wykonana w odpowiedzi na jedną z trzech sytuacji: UPDATE.
Testowanie oprogramowania metodą badania pokrycia kodu
Łukasz Monkiewicz.
Współprogramy Plan: Motywacja Składnia Scenariusz obiektu współprogramu Przykłady Producent – konsument ( instrukcja attach ) Czytelnik -pisarze ( instukcja.
Przykład włamania do aplikacji internetowej poprzez modyfikację zapytań SQL Skrypty ASP Serwer bazy danych MS SQL Server Piotr Kuźniacki BDi.
DIRECT &INDIRECT QUESTIONS
1 Building Integration System - Training Internal | ST-IST/PRM1 | 02/2008 | © Robert Bosch GmbH All rights reserved, also regarding any disposal,
Tadeusz Janasiewicz IT Group, Tadeusz Janasiewicz, WSUS, IT Group, r.
SQL – Structured Query Language (3)
Rozproszone transakcje z wykorzystaniem usługi Service Broker w SQL Server 2008 R2 Andrzej Ptasznik.
REKURENCJA.
Dr inż. Piotr Czapiewski. Overloading Znaczenie inne niż w większości języków obiektowych Metoda dynamicznego tworzenia pól i metod Magiczne metody.
Instrukcje: CREATE, INSERT, UPDATE, DELETE, DROP
Użytkownicy i przywileje Sesja - przykład Błędy Komunikacja międzyskryptowa Wykład 83PD Technologie internetowe.
BLOOD DONATION.
Click to show the screen.
db4o Kacper Skory Marcin Talarek
Portal Systemu Jakości Kształcenia Jak się zalogować? Instrukcja dla pracowników UMCS Przygotowanie: Urszula Wojtczak, Zespół Obsługi Systemu Jakości Kształcenia.
Tablice.
Przeglądanie inOrder function BSTinorder(BSTNode root) if root NOT NULL BSTinorder(root.left) Print(root) BSTinorder(root.right) 2, 4, 6, 8, 9, 10, 12,
Podstawy programowania
Uniwersytet Mikołaja Kopernika Wydział Fizyki, Astronomii i Informatyki Stosowanej Podyplomowe Studium Programowania i Zastosowań Komputerów Autor: Marcin.
KLAWIATURA Co to jest?.
TYPY STRUKTURALNE Tablice Tablicą nazywamy złożoną strukturę danych, która zawiera zbiór elementów tego samego typu.
xHTML jako rozszerzenie HTML
Instalacja serwera WWW na komputerze lokalnym
PHP Operacje na datach Damian Urbańczyk. Operacje na datach? Dzięki odpowiednim funkcjom PHP, możemy dokonywać operacji na datach. Funkcje date() i time()
Elementy programowania97 Użycie zmiennych w procedurze Sub ObliczWiek() 'deklaracja zmiennych Dim ImieNazwisko As String Dim DataUrodzenia As Date Dim.
Warsztaty C# Część 2 Grzegorz Piotrowski Grupa.NET PO
Warsztaty C# Część 3 Grzegorz Piotrowski Grupa.NET PO
A. Jędryczkowski – 2006 ©. Tablica to struktura danych zawierająca zbiór obiektów tego samego typu i odpowiada matematycznemu pojęciu wektora (tablica.
Turbo Pascal umożliwia wykorzystanie w programach zbiorów teoriomnogościowych, których elementy muszą należeć do pewnego określonego typu. Typ zbiorowy.
Pliki elementowe – A. Jędryczkowski © 2007 Turbo Pascal umożliwia wykorzystanie w programach plików elementowych. Pliki takie zawierają informację zakodowaną
Budowa programu #include /*instrukcje preprocesora */ #include int main(void) { /*podstawowa funkcja programu */ int a=1; /*deklaracja i inicjalizacja.
IBM Tivoli Storage Manager Strojenie A Presentation by Paweł Krawczyk June 8, 2011.
Temat 5: Elementy meta.
Temat 1: Umieszczanie skryptów w dokumencie
Instrukcja switch switch (wyrażenie) { case wart_1 : { instr_1; break; } case wart_2 : { instr_2; break; } … case wart_n : { instr_n; break; } default.
Instrukcja switch switch (wyrażenie) { case wart_1 : { instr_1; break; } case wart_2 : { instr_2; break; } … case wart_n : { instr_n; break; } default.
Rozdział 3: Bezpieczeństwo w sieci opartej na systemie Windows 2000.
Komtech Sp. z o.o. Magic Janusz ROŻEJ.
Magic Janusz ROŻEJ Komtech Sp. z o.o.
1.
Bazy Danych Wykład 7 Wojciech St. Mościbrodzki
Wydział Elektroniki Kierunek: AiR Zaawansowane metody programowania Wykład 6.
1 SBD, L.Banachowski Zaawansowane cechy SQL Powtórzenie wyk ł adu 5.
Bazy Danych W06 Wojciech St. Mościbrodzki
1 SBD, L.Banachowski Oprogramowanie strony serwera cz. 1 Powtórzenie wyk ł adu 6.
Wykład 3 Prowadzący: dr Paweł Drozda. Użytkownik bazy danych – osoba lub aplikacja, mająca dostęp do części danych zgromadzonych w bazie Uprawnienia –
Previously discusses: different kinds of variables
Zapis prezentacji:

Bazy Danych Programowanie w SQL Wojciech St. Mościbrodzki wojmos@wojmos.com

Prawa dostępu do obiektów w mySQL Główne zadania DBMS: Identyfikacja i autoryzacja użytkowników Definiowanie poziomów dostępu Zarządzanie prawami dostępu do obiektów Obsługa sytuacji wyjątkowych

Prawa dostępu w mySQL Prawa dotyczą obiektów bazodanowych: Połączeń, baz, tablic, triggerów Użytkowników (w mySQL - w kontekście logowania!) Polecenia związane z zarządzaniem prawami: CREATE USER RENAME USER DROP USER GRANT REVOKE SHOW GRANTS SET PASSWORD

GRANT Polecenie GRANT służy do nadawania: PRAW na OBIEKTY określonym UŻYTKOWNIKOM GRANT priv_type [(column_list)] [, priv_type [(column_list)]] ... ON [object_type] priv_level TO user_specification [, user_specification] ... [REQUIRE {NONE | ssl_option [[AND] ssl_option] ...}] [WITH with_option ...] PRAWA (przywileje) to operacje dozwolone, np. CREATE, INSERT, SELECT, EXECUTE, FILE, RELOAD itp. OBIEKTY to tabele, kolumny, funkcje, procedury UŻYTKOWNIK jest określony kontekstem: login+hasło+adres(połączenie)

PRAWA (przywileje) W MySQL definiuje się następujące poziomy praw: global (odnosi się do całości obiektów serwera) – GRANT <prawo> on *.* database (tylko dla danej bazy danych) – GRANT <prawo> on moja.* table (tylko dla jednej tablicy w bazie) – GRANT <prawo> on moja.auto column (tylko dla określonej kolumny) – GRANT <prawo> on moja.auto(id) W zależności od poziomu prawa, są one inaczej pamiętane w systemowej bazie danych: global level – tablica mysql.user database level – tablica mysql.db table level – tablica mysql.tables_priv column level – tablica mysql.columns_priv

GRANT – SQL vs mySQL mySQL nadaje prawa w kontekście logowania (nie tylko usera) mySQL implementuje prawa globalne i bazodanowe mySQL rozszerza zakres praw w mySQL usunięcie tabeli nie usuwa praw(!); prawa-zombie mySQL pozwala na nadanie prawa INSERT do określonych kolumn, przy jednoczesnym zabraniu go na inne (użyte zostaną wartości DEFAULT)

Prawa dostępu - mySQL Najczęściej używane: Prawa do zarządzania: ALL, ALTER, DELETE, DROP, INSERT, SELECT, TRIGGER, UPDATE Prawa do zarządzania: CREATE USER, CREATE VIEW, CREATE, INDEX, EXECUTE, RELOAD, SHOW DATABASES, SHOW VIEW, SHUTDOWN, SUPER, Pozostałe: ALTER ROUTINE, CREATE ROUTINE, CREATE TEMPORARY TABLES, EVENT, FILE, LOCK TABLES, PROCESS, REPLICATION CLIENT, REPLICATION SLAVE, GRANT SELECT ON moja.samochod TO wojmos WITH GRANT OPTION Specjalne prawo: GRANT OPTION – możliwość przekazywania uprawnień

Implementacja kontekstu użytkownika Prawa użytkownika przypisuje się parze (user, host) Identyfikacja odbywa się za pomocą pary (user, password) CREATE USER user_specification [IDENTIFIED BY [PASSWORD] 'password'] UWAGA: niestosowanie klauzuli IDENTIFIED BY umożliwia logowania bez hasła IDENTIFIED BY PASSWORD umożliwia ominięcie podawania hasła otwartym tekstem mysql> create user wojmos; mysql> select user, host, password from mysql.user; +--------+-----------+-------------------------------------------+ | user | host | password | | root | localhost | *E35C24480CDB73576312748BA0DCF2E4648A7E6C | | wojmos | % | |

CREATE USER, DROP USER i SET PASSWORD CREATE USER – tworzenie użytkowników DROP USER – usuwanie użytkowników (z prawami!) SET PASSWORD – ustawianie haseł RENAME USER – zmiana nazwy GRANT USAGE CREATE USER user_specification [IDENTIFIED BY [PASSWORD] 'password'] DROP USER user [, user] ... RENAME USER old_user TO new_user SET PASSWORD [FOR user] = { 'encrypted password‘ | PASSWORD('some password') | OLD_PASSWORD('some password') } GRANT USAGE ON *.* TO ‘wojmos'@'%.wojmos.com' IDENTIFIED BY 'newpass';

Hasła podawane w CREATE USER i SET PASSWORD mysql> create user 'sample1'; mysql> create user 'sample2' identified by 'lipton'; mysql> create user 'sample3' identified by password '*90E462C37378CED12064BB3388827D2BA3A9B689'; mysql> create user 'sample3' identified by password 'lipton'; ERROR 1372 (HY000): Password hash should be a 41-digit hexadecimal number mysql> create user 'sample4'; mysql> set password for sample4 = PASSWORD('lipton'); mysql> create user 'sample5'; mysql> set password for sample5 = OLD_PASSWORD('lipton'); mysql> select user, host, password from mysql.user; +---------+-----------+-------------------------------------------+ | user | host | password | | root | localhost | *E35C24480CDB73576312748BA0DCF2E4648A7E6C | | sample2 | % | *D0CD8B382FCD172A273DE23563C530DB2E12D059 | | wojmos | % | | | sample1 | % | | | sample3 | % | *90E462C37378CED12064BB3388827D2BA3A9B689 | | sample4 | % | *D0CD8B382FCD172A273DE23563C530DB2E12D059 | | sample5 | % | 58ac86b863e0cbbf |

Przykład działania GRANT OPTION REVOKE priv_type [(column_list)] [, priv_type [(column_list)]] ... ON [object_type] priv_level FROM user [, user] ... REVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user] ... GRANT ALL ON *.* TO wojmos with GRANT OPTION root GRANT ALL ON sample.* TO sample1 with GRANT OPTION wojmos GRANT ALL ON sample.* TO sample2 sample1 CREATE TABLE X(id int) sample2 DROP USER SAMPLE1 CREATE TABLE Y(id int) <===========? sample2

Kontekst użytkownika mySQL umożliwia dość szerokie i elastyczne zarządzanie prawami: mysql> create user koza@localhost; mysql> create user koza identified by 'lipton'; mysql> create user koza@'192.168.0.110'; mysql> create user koza@'10.10.0.'; mysqlmysql> select user, host, password from mysql.user where user like 'koza'; +------+---------------+-------------------------------------------+ | user | host | password | | koza | localhost | | | koza | % | *D0CD8B382FCD172A273DE23563C530DB2E12D059 | | koza | 192.168.0.110 | | | koza | 10.10.0. | |

Szyfrowanie tablic – bezpieczeństwo w mySQL Rozważmy typową bazę, z dostępem via Internet / PHP: USER(id int, login char(10), pass char(10), firstname char(20), lastname char(50)) Typowy (powszechne rozwiązanie) plik show.php: http://show.php?q=‘select * from product where id=7’ Typowy atak: http://show.php?q=‘select * from user’

Tworzenie własnych funkcji i procedur

Tworzenie własnych funkcji i procedur Funkcje są definiowanymi przez użytkownika rozszerzeniami SQL. MySQL pozwala na 3 mechanizmy: Funkcje wkompilowywane w kod serwera Funkcje w postaci kompilowanych bibliotek Funkcje i procedury składowane (stored functions/procedures) (Zwykły użytkownik zasadniczo używa jedynie 3 drogi) Stored function (funkcja składowana) jest wywoływana tak, jak zwykła funkcja SQL. Stored procedure (procedura składowana) jest wywoływana przez call select concat('Ala', ' ma kota'); select count(*) from user; select moja_funkcja(); call moja_procedura();

Własne funkcje CREATE PROCEDURE/FUNCTION DROP PROCEDURE/FUNCTION SHOW PROCEDURE/FUNCTION STATUS SHOW CREATE PROCEDURE/FUNCTION Procedury i funkcje są obiektami konkretnej bazy (od 5.0.1+)! Procedury i funkcje są obiektami serwera (do 5.0.0)! 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)

Funkcje vs procedury Funkcje i procedury składowane mają podobną budowę i znaczenie Funkcje wymagają określenia RETURNS Funkcje składowane i UDF dzielą ze sobą przestrzeń nazw Parametry funkcji są zawsze IN (nie mogą zmienić wartości) Funkcje są wywoływane jak normalne funkcje SQL CREATE [DEFINER] FUNCTION sp_name ([func_parameter[,...]]) RETURNS type [special ...] routine_body func_parameter: name type special: LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER } | COMMENT 'string' routine_body: SQL | BEGIN...END

Funkcje vs procedury Funkcje i procedury składowane mają podobną budowę i znaczenie Procedury nie określają RETURNS – nie zwracają wartości Procedury przekazują wartości tylko przez zmienne Parametry procedur mogą być IN, OUT lub INOUT Procedury wywoływane są tylko poprzez call CREATE [DEFINER] PROCEDURE sp_name ([proc_parameter[,...]]) [special...] routine_body proc_parameter: [ IN | OUT | INOUT ] name type special: LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER } | COMMENT 'string' routine_body: SQL | BEGIN...END

Porównanie CREATE dla funkcji i procedur [DEFINER = { user | CURRENT_USER }] PROCEDURE sp_name ([proc_parameter[,...]]) [characteristic ...] routine_body FUNCTION sp_name ([func_parameter[,...]]) RETURNS type proc_parameter: [ IN | OUT | INOUT ] param_name type func_parameter: param_name type type: Any valid MySQL data type characteristic: LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER } | COMMENT 'string'

DELIMITER i jego znaczenie Procedury i funkcje składają się zwykle z wielu linii kodu. Oznacza to problem z interpretacją znaku ; po stronie klienta. PRZYPOMINAMY: znak terminalny „;” powoduje natychmiastowe wysłanie poleceń do serwera (w celu interpretacji). Druga jego rola to oddzielanie kolejnych poleceń. CREATE FUNCTION nazwa () RETURNS VARCHAR(20) BEGIN RETURN 'Hello world'; END; w tym miejscu kod zostanie wysłany do serwera CREATE FUNCTION nazwa () RETURNS VARCHAR(20) BEGIN RETURN 'Hello world'; powyższy fragment NIE JEST jednak poprawny!

DELIMITER – zmiana znaku terminalnego WNIOSEK: musimy chwilowo zmienić znaczenie znaku ; (aby przestał wysyłać kod do serwera). DELIMITER ;; nowy symbol terminalny CREATE FUNCTION nazwa () RETURNS VARCHAR(20) BEGIN RETURN ‘Hello world'; END; tworzymy funkcję koniec polecenia ;; wysyłamy do serwera DELIMITER ; stary symbol terminalny (sprzątamy po sobie!)

Prosta funkcja składowana Stworzenie funkcji mysql> DROP FUNCTION IF EXISTS Hello; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> show warnings; +-------+------+-------------------------------+ | Level | Code | Message | | Note | 1305 | FUNCTION Hello does not exist | DELIMITER ;; CREATE FUNCTION Hello() RETURNS VARCHAR(20) BEGIN RETURN 'Hello world'; END; ;; DELIMITER ;

Prosta funkcja składowana Stworzenie i wywołanie funkcji DROP FUNCTION IF EXISTS Hello; DELIMITER ;; CREATE FUNCTION Hello() RETURNS VARCHAR(20) BEGIN RETURN 'Hello world'; END; ;; DELIMITER ; mysql> select hello(); +-------------+ | hello() | | Hello world | 1 row in set (0.00 sec)

Prosta procedura składowana Stworzenie procedury mysql> DROP PROCEDURE IF EXISTS Hello; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> show warnings; +-------+------+--------------------------------+ | Level | Code | Message | | Note | 1305 | PROCEDURE Hello does not exist | DELIMITER ;; CREATE PROCEDURE Hello() BEGIN SELECT('Hello world'); END; ;; DELIMITER ;

Prosta funkcja składowana Stworzenie i wywołanie procedury DROP PROCEDURE IF EXISTS Hello; DELIMITER ;; CREATE PROCEDURE Hello() BEGIN SELECT('Hello world'); END; ;; DELIMITER ; mysql> call hello(); +-------------+ | Hello world | 1 row in set (0.00 sec)

Parametry przekazywane do obiektów składowanych Funkcje – parametry zawsze są traktowane jako IN Procedury – parametry mogą mieć typ IN, OUT lub INOUT IN – parametr wejściowy, modyfikacja nie jest widoczna na zewnątrz (inicjalizuje go obiekt wywołujący funkcję) OUT – parametr wyjściowy, pełni rolę wartości zwracanej przez zmienną, ma inicjalnie ustawianą wartość na NULL (inicjalizuje go funkcja) INOUT - parametr wejściowo-wyjściowy, pełni rolę wartości zwracanej przez zmienną, ma inicjalnie ustawianą wartość przez obiekt wywołujący funkcję Dane do przykładu mysql> select * from pracownik; +--------+-----------+-----------+-------------+----------+ | Jan | Kowalski | polski | 73020103456 | Gdansk | | Jan | Kowalski | niemiecki | 73020103456 | Gdansk | | Piotr | Nowak | polski | 43121102934 | Szczecin | | Stefan | Kozlowski | polski | 98101045777 | Warszawa | | Piotr | Nowak | angielski | 43121102934 | Szczecin | | Jan | Kurski | polski | 71101099348 | Gdansk |

Parametry IN Procedura z parametrem typu IN Wywołanie CREATE PROCEDURE Sample(IN parametr char(30)) BEGIN SELECT * FROM pracownik WHERE i LIKE parametr; END; mysql> call Sample('Jan'); +------+----------+-----------+-------------+--------+ | i | n | j | p | miasto | | Jan | Kowalski | polski | 73020103456 | Gdansk | | Jan | Kowalski | niemiecki | 73020103456 | Gdansk | | Jan | Kurski | polski | 71101099348 | Gdansk | 3 rows in set (0.00 sec)

Parametry OUT Procedura z parametrem typu OUT Wywołanie CREATE PROCEDURE Sample(OUT parametr char(30)) BEGIN SELECT count(*) FROM pracownik into parametr; END; call sample(@zmienna); select @zmienna; Query OK, 0 rows affected (0.00 sec) +----------+ | @zmienna | | 6 | 1 row in set (0.00 sec)

Parametry OUT Parametr typu OUT ma inicjalną wartość NULL Wywołanie CREATE PROCEDURE Sample(OUT parametr char(30)) BEGIN SELECT parametr; SELECT count(*) FROM pracownik into parametr; END; mysql> call sample(@zmienna); +----------+ | parametr | | NULL | mysql> call sample('Jan'); ERROR 1414 (42000): OUT or INOUT argument 1 for routine wojmos.sample is not a variable or NEW pseudo-variable in BEFORE trigger

Parametry OUT Parametr typu OUT ma ZAWSZE inicjalną wartość NULL Wywołanie CREATE PROCEDURE Sample(OUT parametr char(30)) BEGIN SELECT parametr; SELECT count(*) FROM pracownik into parametr; END; mysql> select @a:=3; call sample(@a); +-------+ | @a:=3 | | 3 | +----------+ | parametr | | NULL |

Parametry INOUT Procedura z parametrem typu INOUT Wywołanie (parametr inicjowany przez obiekt wołający!) CREATE PROCEDURE Sample(INOUT parametr char(30)) BEGIN SELECT parametr; SELECT count(*) FROM pracownik into parametr; END; mysql> select @a:=3; call sample(@a); +-------+ | @a:=3 | | 3 | +----------+ | parametr | | 3 |

Parametry INOUT Procedura z parametrem typu INOUT Wywołanie (parametr inicjowany przez obiekt wołający!) CREATE PROCEDURE Sample(INOUT parametr char(30)) BEGIN SELECT parametr; SELECT count(*) FROM pracownik into parametr; END; mysql> call sample(@a); select @a; +----------+ | parametr | | 3 | +------+ | @a | | 6 |

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 ;