Skrypty, procedury przechowywane i wyzwalane Wprowadzenie do systemów baz danych
Potrzeba dodatkowego zabezpieczenia danych Bezpośredni dostęp użytkownika do zapytań DLL (SELECT, DELETE, INSERT INTO i UPDATE) może powodować lukę w bezpieczeństwie. Zasady integralności i bezpieczeństwa danych powinny być kontrolowane przez serwer, a nie przez aplikację kliencką. Więzy integralności określone w instrukcji CREATE TABLE i transakcje są często niewystarczające i potrzebny jest dodatkowy mechanizm kontroli integralności. Język SQL jest językiem deklaratywnym i dla rozwiązania pewnych zagadnień istnieje potrzeba wprowadzenia elementów proceduralności – proceduralnego języka SQL.
Zagadnienia Przetwarzanie wsadowe, skrypty SQL Procedury przechowywane (składowane) Wyzwalacze Funkcje użytkownika Narzędzia Producenci stworzyli różne wersje proceduralnych języków SQL Microsoft – język T-SQL Oracle – język PL/SQL PostgreSQL – PL/pgSQL Prezentacja omawia przede wszystkim język T-SQL i PL/pgSQL
Skrypt – program wsadowy Sekwencja instrukcji SQL zapisana w osobnym pliku Program wsadowy to grupa instrukcji T-SQL zebrana w jedną logiczną całość Skrypt rozdziela się na programy wsadowe instrukcją GO – dotyczy tylko języka T-SQL Instrukcje w skryptach, innych systemów zarządzania bazami danych, niż MS SQL Server, rozdziela się średnikami
Deklarowanie zmiennych DECLERE @<nazwa_zmiennej> [AS] <typ_zmiennej>[, @<nazwa_zmiennej> [AS] <typ_zmiennej>,…] Przykłady: DECLERE @NR int, @Nazwiko AS varchar(15)
Przypisywanie wartości zmiennym (instrukcja SET) DECLARE @NR int, @tekst AS varchar(15) SET @NR = 10 SET @tekst = 'Numer = ' print @nr print @tekst + CAST(@NR AS varchar(15))
Przypisywanie wartości zmiennym (instrukcja SET) USE studenci GO DECLARE @średnia_ocen as NUMERIC(5,3) SET @średnia_ocen = (SELECT AVG(ocena) FROM oceny) PRINT @średnia_ocen PRINT 'średnia ocen studentów = ' + CAST(@średnia_ocen AS CHAR(5))
Przypisywanie wartości zmiennym (instrukcja SELECT) USE studenci GO DECLARE @średnia_ocen as NUMERIC(5,3) SELECT @średnia_ocen = AVG(ocena) FROM oceny PRINT @średnia_ocen PRINT 'średnia ocen studentów = ' + CAST(@średnia_ocen AS CHAR(5))
Ważne funkcje systemowe @@IDENTITY – zwraca ostatnią wartość identyfikatora ostatniej instrukcji INSERT lub SELECT INTO @@ROWCOUNT – zwraca liczbę wierszy, których dotyczyła ostatnia instrukcja @@VERSION – zwraca informację o serwerze @@ERROR – zwraca numer błędu ostatniej instrukcji T-SQL (0 oznacza brak błędu)
Przykład użycia @@IDENTITY USE studenci GO DECLARE @ID int INSERT INTO student(nazwisko, imie, data_urodzenia, nr_albumu, adres_miasto, adres_ulica) VALUES (N'Nowik', N'Jan', '1991-11-11', N'123', N'Gdynia', N'Polska 35') SET @ID = @@IDENTITY PRINT @ID
Przykład: @@ROWCOUNT, @@ERROR, @@VERSION USE studenci GO SET NOCOUNT ON; SELECT * from student; PRINT 'Liczba wierszy: ' + CAST(@@ROWCOUNT AS char(4)) PRINT 'Błąd: ' + CAST(@@ERROR AS char(4)) PRINT 'Wersja systemu: ' + @@VERSION
Instrukcja GO GO rozdziela skrypt na kilka programów wsadowych GO umieszcza się zawsze w nowej linii Pewne instrukcje wymagają osobnych programów wsadowych, co można uzyskać dzieląc skrypt instrukcjami GO
Dynamiczne tworzenie zapytań instrukcja EXEC Argumentem instrukcji EXEC jest zmienna łańcuchowa lub łańcuch tekstu zawierający instrukcję Wykonywana instrukcja może być tworzona dynamicznie w trakcie wykonywania skryptu EXEC({<zmienna łańcuchowa> | <łańcuch tekstu>} USE studenci GO DECLARE @tabela AS varchar(20) SET @tabela = 'student' EXEC('SELECT * from ' + @tabela)
Procedury przechowywane (składowane) Procedura przechowywana to rodzaj skryptu (programu wsadowego) przechowywanego w bazie danych, a nie w osobnym pliku Procedura w odróżnieniu od skryptu może posiadać parametry wejściowe, wyjściowe i wartości wynikowe
Tworzenie procedury przechowywanej CREATE PROCEDURE <nazwa_procedury> [@nazwa_parametru [AS] typ_danych [=wartość_domyślna | NULL] [OUTPUT|OUT], …] AS kod procedury
Przykład procedury dodającej studenta CREATE PROCEDURE dbo.InsertStudent ( @nazwisko varchar(20), @imie varchar(20), @nr_albumu char(11), @adres_miasto varchar(20), @adres_ulica varchar(50) ) AS SET NOCOUNT OFF; INSERT INTO [student] ([nazwisko], [imie], [nr_albumu], [adres_miasto], [adres_ulica]) VALUES (@nazwisko, @imie, @nr_albumu, @adres_miasto, @adres_ulica); SELECT id_studenta, nazwisko, imie, nr_albumu, adres_miasto, adres_ulica FROM student WHERE (id_studenta = SCOPE_IDENTITY())
Wywołanie procedury USE [studenci] GO EXEC InsertStudent 'Aabik', 'Jan', '1234567', 'Gdynia', '10 Lutego 11'
Uwagi Słowo kluczowe OUTPUT określa parametry wyjściowe procedury OUTPUT musi być użyte przy deklaracji procedury i przy jej wywołaniu Pominięcie OUTPUT przy wywołaniu spowoduje, że wartość parametru wyjściowego nie zostanie przypisana EXEC można pominąć , gdy wywołanie procedury jest pierwszą instrukcją w programie wsadowym, ale lepiej tego nie robić
Przykład zmiennego parametru CREATE PROCEDURE dbo.InsertStudent_NR ( @nazwisko varchar(20), @imie varchar(20), @nr_albumu char(11), @adres_miasto varchar(20), @adres_ulica varchar(50), @numer int OUTPUT ) AS SET NOCOUNT OFF; INSERT INTO [student] ([nazwisko], [imie], [nr_albumu], [adres_miasto], [adres_ulica]) VALUES (@nazwisko, @imie, @nr_albumu, @adres_miasto, @adres_ulica); SET @numer = @@IDENTITY
Wywołanie procedury zmieniającej parametr USE [studenci] GO DECLARE @numer int EXEC InsertStudent_NR 'Kitel', 'Jan', 'q234567', 'Gdynia', '10 Lutego 11',@numer OUTPUT PRINT @numer
Instrukcje sterujące przebiegiem programu IF … ELSE CASE GOTO WHILE RETURN BEGIN … END TRY/CATH WAITFOR – maksymalnie do 24h WAITFOR DELAY '01:00' - czekaj 1h WAITFOR TIME '01:00' - czekaj do godziny 1
Zastosowania Tworzenie procesów wymagających wywoływania akcji proceduralnych Poprawa bezpieczeństwa Poprawa wydajności
Wywoływanie funkcji SELECT 2*log(10) AS wynik 4,60517 SELECT moja_funkcja(argumenty) W bazie danych ORACLE w zapytaniu musi być klauzula FROM
Funkcje definiowane przez użytkownika CREATE FUNCTION <nazwa_funkcji> [@nazwa_parametru [AS] typ_danych [=wartość_domyślna], … RETURNS {typ_skalarny|TABLE [(def_tabeli)] AS BEGIN kod_funkcji {RETURN obliczony_wynik | RETURN (instrukcja SELECT)} END
Przykład funkcji skalarnej CREATE FUNCTION dbo.suma ( @param1 varchar(20) = 'Ala ma kota', @param2 varchar(20) = ' a kot ma Alę' ) RETURNS varchar(40) AS BEGIN DECLARE @suma varchar(40) SET @suma = @param1 + @param2 RETURN @suma END
Przykład funkcji zwracającej tabelę CREATE FUNCTION dbo.ponad_avg() RETURNS @table_variable TABLE (student varchar(40), [średnia] REAL) AS BEGIN DECLARE @Param1 real SELECT @Param1 = AVG(ocena) FROM oceny INSERT INTO @table_variable SELECT Student, AVG(ocena) AS Expr1 FROM lista_ocen GROUP BY Student HAVING (AVG(ocena) > @Param1) RETURN END
Przykłady wywołań funkcji Wywołanie funkcji zwracającej tabelę select * from ponad_avg() Wywołanie funkcji skalarnej select dbo.suma('tekst1', ' Text2') as wynik select dbo.suma('tekst1',default) as wynik
Tworzenie obiektów bazy danych w kodzie zarządzanym SQL Server 2005 umożliwia tworzenie obiektów bazy danych w preferowanym języku platformy .NET Najprościej jest tworzyć te obiekty przy pomocy Visual Studio otwierając w wybranym języku SQLServer Project Po skompilowaniu VS utworzy bibliotekę, która zostanie dołączona do bazy danych a stworzone w projekcie obiekty staną się obiektami bazy danych
Tworzenie funkcji - PostgreSQL CREATE FUNCTION nazwa([typ1[,...typN]]) RETURNS typ_zwracany AS {’nazwa_pliku’ | ’definicja’} LANGUAGE ’nazwa_języka’ Nazwa języka to jeden z dostępnych w PostgreSQL języków: C, sql, plpgsql, pltcl, plperl Przed pierwszym użyciem język proceduralny trzeba zainstalować poleceniem CREATE LANGUAGE
Przykład CREATE FUNCTION funkcja(text) RETURNS bool AS ’DECLARE tekst ALIAS FOR $1; BEGIN INSERT INTO tabela1 VALUES (tekst); RETURN ’yes’; END;’ LANGUAGE ’plpgsql’
Elementy języka PL/pgsql Komentarze Deklaracje zmiennych Instrukcje przypisania Instrukcje SQL Instrukcje warunkowe Pętle WHILE i FOR Wyjątki i komunikaty
Tworzenie wyzwalacza PostgreSQL CREATE TRIGGIER nazwa {AFTER | BEFORE} zdarzenie1 [OR zdarzenie2 ...] ON nazwa_tabeli FOR EACH {ROW | STATEMENT} EXECUTE PROCEDURE nazwa_funkcji(argumenty) Zdarzeniem może być INSERT, DELETE, UPDATE Instrukcja CREATE TRIGGIER występuje w SQL3, ale nie występuje w SQL2 i SQL1
Tworzenie wyzwalacza SQL Server CREATE TRIGGIER nazwa ON nazwa_tabeli lub widoku {{FOR | AFTER} <[DELETE][,][INSERT][,][UPDATE] | INSTED OF}} AS instrukcje SQL
Instrukcja CREATE RULE Instrukcja CREATE RULE jest rozszerzeniem języka SQL zastosowanym w PostgreSQL CREATE RULE nazwa AS ON {SELECT | UPDATE | DELETE | INSERT} TO nazwa_tabeli [WHERE warunek] DO [INSTED] {instrukcja sql | NOTHING}
Zastosowania Centralne sprawdzanie poprawności danych Śledzenie zmian np. zapisanie w osobnej tabeli kto i kiedy dokonywał zmian, a nawet zapisanie danych, które zmieniono Polepszenie bezpieczeństwa np. wysyłanie wiadomości pocztą elektroniczną o niektórych zmianach Komunikacja z innymi bazami danych (języki c, pgperl, pgtcl) Replikacja danych Przygotowanie danych dla aplikacji klienckich
Wady System oparty głównie na wyzwalaczach i procedurach wyzwalanych może być trudny do zarządzania Pogarsza się przejrzystość bazy danych Brak standardowej składni zapisu procedur przechowywanych i wyzwalaczy – zastosowanie ich praktycznie uniemożliwia zmianę SZBD W miarę wzrostu liczby wyzwalaczy rosną koszty przetwarzania