select

advertisement
Wykład 5: Zaawansowany
SQL
Zaawansowany SQL
 Typy danych SQL i schematy
 Więzy integralności (spójności)
 Wyzwalacze (triggers)
 Procedury składowane (stored procedures)
 Funkcje
 Autoryzacja
 Role
 Zanurzony SQL
 Dynamiczny SQL
Typy danych czas-data
 date: Data zawierające (4 cyfry) rok, miesiąc i dzień
Przykład: date ‘2007-1-27’
 time: czas w godzinach, minutach i sekundach.
 Przykład: time ‘11:55:30’
time ‘11:55:30.65’
 timestamp: data oraz czas
 Przykład: timestamp ‘2007-1-27 11:55:30.75’
 interval: Przedział czasu
 Przykład: interval ‘1’ day
 odejmowanie jednej wartości date/time/timestamp od innej
daje wartość typu interval
 Wartości typu interval mogą być dodawane do wartości
date/time/timestamp

Typy danych czas-data (cd.)
 Możemy pobierać wartości poszczególnych pól z wartości
date/time/timestamp
 Przykład: extract (year from r.starttime)
 MSSQL używa funkcji DAY, MONTH, YEAR, DATEADD,
DATEDIFF, DATEPART oraz GETDATE:

SELECT YEAR(starttime) from r;
 Możemy rzutować łańcuchy znaków na wartości typu
date/time/timestamp
 Przykład:


cast <wyrażenie tekstowe> as date
Przykład MSSQL:

cast ('1 październik 2003' as datetime)
Typy definiowalne
 create type – taka konstrukcja w SQL tworzy typ definiowalny
(typ uzytkownika)
create type zloty as numeric (12,2) final

Tylko ORACLE wspiera tą konstrukcję!
 create domain - taka konstrukcja w SQL-92 tworzy dziedziny
typów - definiowalnych
create domain person_name char(20) not null
 Typy i dziedziny są podobne. Dziedziny mogą posiadać więzy
np. not null

Większość producentów SZRBD nie wspiera tych konstrukcji!
Więzy dla dziedzin
 Domain constraints są podstawową postacią więzów
spójności. Sprawdzają wartości wprowadzane do bazy i
sprawdzają czy porównania w kwerendach mają sens:


CREATE DOMAIN VALID_EMPL_IDS INTEGER
CHECK (VALUE BETWEEN 101 AND 199);
 Nowe dziedziny mogą być tworzone z istniejących typów
danych
 Przykład: create domain zloty numeric(12, 2);
create domain euro numeric(12,2);
 Nie można przyrównać/przypisać wartości typu zloty do
wartości typu euro.
 Ale możemy przekształcić typy tak jak poniżej:
(cast r.A as euro)
(Powinno również przemnożyć wynik przez kurs wymiany)
Typy opisujące duże obiekty
 Obiekty takie jak zdjęcia, pliki wideo, ... są przechowywane w bazie
jako large object:
 blob: binary large object – obiekt jest kolekcją binarnych danych,
których interpretacji dokonuje aplikacja poza systemem bazy
danych
 clob: character large object – kolekcja znaków
 Jeżeli w kwerendzie znajduje się zapytanie o duże obiekty
zwracany jest wskaźnik a nie sam obiekt.
 Przykład ORACLE:
 Typ BLOB pozwala na przechowanie do 8 terabajtów danych
binarnych w bazie danych.
 Typ CLOB pozwala na przechowanie do 8 terabajtów
jednobajtowych znaków w bazie danych.
 Typ NCLOB wielobajtowe CBLOB.
 Typ BFILE przechowuje duże dane binarne w plikach
zewnętrznych wzlędem bazy danych.
Więzy spójności
 Więzy spójności zapobiegają przypadkowemu uszkodzeniu
bazy danych. Sprawdzają, czy zmiany w bazie nie powodują
utraty spójności danych.
 Rachunek oszczędnościowy musi mieć stan co najmniej
30,000.00
 Pensja pracownika nie może być mniejsza niż 7 zł za
godzinę
 Klient musi posiadać telefon (niepusta wartość atrybutu)
Więzy spójności dla pojedynczej relacji
 not null
 primary key
 unique
 check (P ), gdzie P jest predykatem
Więzy not null
 Deklarujemy, że oddzial_nazwa dla relacji aktywa jest not null
oddzial_nazwa char(15) not null
 Dziedzina Euro ma być not null
create domain Euro numeric(12,2) not null
Więzy unique
 unique ( A1, A2, …, Am)
 Specyfikacja unique stwierdza, że atrybuty
A1, A2, … Am
tworzą klucz kandydujący.
 W przeciwieństwie do kluczy głównych klucze kandydujące mogą
być puste (null)
Klauzula check
 check (P ), gdzie P jest predykatem (MySQL nie
realizuje klauzuli check)
Przykład: Deklarujemy oddzial_nazwa jako klucz główny i żądamy aby wartości
aktywów nie były ujemne.
create table oddzial
(oddzial_nazwa
char(15),
oddzial_miasto
char(30),
aktywa
integer,
primary key (oddzial_nazwa),
check (aktywa >= 0))
Zbliżają się wybory, w MS SQL sprawdzamy, czy wyborca ma 18 lat w dniu wyborów:
ALTER TABLE wyborca ADD CONSTRAINT
CK_wiek_18
CHECK (DateDiff(yy,DateofBirth, DateofVote)>=18);
Klauzula check
 check może być wykorzystane jako więzy dla krotek (w
poprzednim przypadku warunek dotyczył jednego
atrybutu, poniżej mamy dwa atrybuty wymienione w
warunku)
Przykład:
CREATE TABLE Campus (
location char(25),
enrollment integer,
rank integer,
CHECK(enrollment >= 10,000 OR rank > 5)
);
Klauzula check (cd.)
 W standardzie SQL-92 klauzula check pozwala na ograniczanie
dziedzin:
 Można jej użyć np. do sprawdzenia czy stawka godzinowa
jest większa od wartość określona prawem.
create domain stawka_godzina numeric(5,2)
constraint sprawdz_stawke check(value > = 4.00)
 W ten sposób więzy są nałożone na dziedzinę atrybutu i
zapewniają, że nikt w bazie nie może nam przypisać stawki
mniejszej
 Klauzula constraint sprawdz_stawke jest opcjonalna;
wykorzystywana przy sygnalizacji, jakie więzy zostały
naruszone przy modyfikacji danych.
Więzy referencyjnej spójności
 Zapewniają, że wartość pojawiająca się w jednej relacji dla
danego zbioru atrybutów pojawi się również w innej relacji dla
jakiegoś zbioru atrybutów.
 Przykład: Jeśli “Centum” jest nazwą oddziału pojawiającą się
w jednej z krotek w relacji rachunek, to musi istnieć
odpowiednia krotka w relacji oddzial dla oddziału “Centrum”.
 Klucze główne, klucze kandydujące oraz klucze obce mogą być
specyfikowane jako części polecenia SQL create table :
 Klauzula primary key wymienia atrybuty tworzące klucz
główny.
 Klauzula unique [key] wymienia atrybuty tworzące klucz
kandydujący.
 Klauzula foreign key wymienia atrybuty tworzące klucz obcy
oraz nawę relacji kojarzonej poprzez klucz obcy. Domyślnie
klucz obcy odnosi się do klucza głównego drugiej tabeli.
Więzy spójności w SQL – Przykład
create table klient
(klient_nazwisko char(20),
klient_ulica
char(30),
klient_miasto
char(30),
primary key (klient_nazwisko ))
create table oddzial
(oddzial_nazwa char(15),
oddzial_miasto char(30),
aktywa
numeric(12,2),
primary key (oddzial_nazwa ))
Więzy spójności w SQL – przykład (cd.)
create table rachunek
(rachunek_numer
char(10),
oddzial_nazwa
char(15),
stan
integer,
primary key (rachunek_numer),
foreign key (oddzial_nazwa) references oddzial )
create table depozytor
(klient_nazwisko
char(20),
rachunek_numer
char(10),
primary key (klient_nazwisko, rachunek_numer),
foreign key (rachunek_numer ) references rachunek,
foreign key (klient_nazwisko ) references klient )
Kaskadowe działanie w SQL
create table rachunek
...
foreign key(oddzial_nazwa) references oddzial
on delete cascade
on update cascade
...)
 Klauzula on delete cascade spowoduje, że jeśli usuwanie jakiegoś
oddziału w relacji oddział powoduje naruszenie więzów spójności to
odpowiednia krotka w relacji rachunek zostanie także usunięta.
 Podobnie sprawa wygląda dla kaskadowych uaktualnień (zmiana
nazwy w tabeli oddzial z „Grudziądz” na „Grudziądz Rynek” powinna
się przenieść do tabeli rachunek).
Kaskadowe działanie w SQL (cd.)
 Jeśli istnieje łańcuch zależności kluczy obcych z on delete cascade
określonym dla każdej zależności to usuwanie (modyfikacja) na jednym
końcu łańcucha propaguje się do drugiego końca (jak kostki domina).
 Jeżeli kaskadowe działanie narusza więzy integralności na jakimś stopniu
kaskady, system porzuca transakcję.
 W wyniku, wszystkie zmiany zostaną wycofane (rollback).
 Więzy spójności są sprawdzane na końcu transakcji
 Cząstkowe kroki mogą łamać więzy spójności przy założeniu,
późniejsze kroki usuną naruszenie
 W przeciwnym przypadku byłoby niemożliwe opisywanie pewnych
faktów, np. wstawienie dwóch krotek, których klucze obce wskazują
wzajemnie na siebie: zawieranie małżeństwa
Więzy spójności w SQL (cd.)
 Alternatywą dla kaskad mogą być:

on delete set null


on delete set default



Wstawia w krotce podrzędnej wartości puste
Wstawia w krotce podrzędnej watości dpmyślne
on delete restrict
on delete no action (MS SQL)

Nie pozwala na usuwanie jeśli istnieje krotka zależna
 Ale wartości puste komplikują „logikę” więzów integralności
jeśli jakikolwiek atrybut klucza obcego ma wartość null, to krotka
spełnia więzy integralności z definicji!
 W MySQL set null nie może dotyczyć sytuacji gdy pole w tabeli ma
warunek not null (oczywiste!)

Zapewnienia (assertions)
 Nie wszystkie warunki można wyrazić przy pomocy więzów
omawianych poprzednio (jak check)
 Zapewnienie (assertion) jest predykatem wyrażającym
warunek, który zawsze ma spełniać cała baza.
 Zapewnienie w SQL przyjmuje postać
create assertion <nazwa_zapewnienia> check <predykat>
 Kiedy wstawione jest „zapewnienie” system sprawdza jego
poprawność oraz sprawdza czy predykat jest spełniony przy
modyfikacji, która może nie spełniać warunku.
 Takie testowanie może wprowadzić duże obciążenie do
bazy, zapewnienia powinny być używane z ostrożnością.
 MS SQL ich nie posiada
Przykład zapewnienia
 Średnia ocen jest > 3.0 and średnia dochod <
1000
CREATE ASSERTION Avgs CHECK(
3.0 < (SELECT avg(ocena) FROM Student)
AND 1000 > (SELECT avg(dochod) FROM Student))
 Student ze średnią < 3.0 może się tylko strać o kampus z
rankingiem > 4.
 CREATE ASSERTION RestrictApps CHECK(
NOT EXISTS (SELECT * FROM Student, Apply,
Campus WHERE Student.ID = Apply.ID AND
Apply.location = Campus.location AND
Student.GPA < 3.0 AND Campus.rank <= 4))

Przykład zapewnienia
 Każdy kredyt posiada przynajmniej jednego kredytobiorcę, który
posiada rachunek ze stanem przynajmniej 3000.00 zł
create assertion stan_wiezy check
(not exists (
select *
from kredyt
where not exists (
select *
from kredytobiorca, depozytor, rachunek
where kredyt.kredyt_numer = kredytobiorca.kredyt_numer
and kredytobiorca.klient_nazwisko =
depozytor.klient_nazwisko
and depozytor.rachunek_numer =
rachunek.rachunek_numer
and rachunek.stan >= 3000)))
Przykład zapewnienia
 Suma wszystkich kwot kredytów w każdym oddziale musi być
mniejsza od sumy stanów rachunków w tym oddziale.
create assertion suma_wiezy check
(not exists (select *
from oddzial
where (select sum(kwota )
from kredyt
where kredyt.oddzial_nazwa =
oddzial.oddzial_nazwa )
>= (select sum (stan )
from rachunek
where rachunek.oddzial_nazwa =
oddzial.oddzial_nazwa )))
PROGRAMOWANIE
Skarb DBA
(głównie na przykładzie MS SQL Server)
 Struktury proceduralne
Programowanie „wsadowe” (batch)
 Zmienne
 Instrukcje sterujące
 Przetwarzanie błędów
Procedury składowane
Funkcje definiowalne
Synonimy
Wyzwalacze DML





 Wyzwalacze i procedury składowane – należą do najważniejszych





narzędzi DBA (database administrator) oraz DBAD (application
developer)
Wyzwalacze mogą zaoszczędzić |DBA utraconego czasu i
problemów poprzez automatyzację monitorowania stanu bazy i
zadań administracyjnych.
Procedury składowane mogą być wykorzystywane do tworzenia
skryptów administracyjnych , które będą używane wielokrotnie i
zmniejszają czas niezbędny do administracji i szansę na powstanie
błędów.
To będzie bliższe klasycznemu programowaniu
Oprócz tego mamy jeszcze UDFy User Defined Functions
Zaczniemy od podstaw: batche, zmienne i instrukcje sterujące!
Batche
 Batch to szereg instrukcji (T-)SQL umieszczonych w jednym pliku
 W pliku *.sql można umieścić wiele batchy, oddzielamy je instrukcją
GO
 Reguły






Niektóre instrukcje muszą być przesłane w ich własnym batchu:
CREATE PROCEDURE, CREATE VIEW, CREATE FUNCTION,
CREATE DEFAULT, CREATE RULE, CREATE SCHEMA, CREATE
TRIGGER
Zmienne muszą być zdefiniowane i wykorzystane w tym samym batchu
Wieloliniowe komentarze /* …. */ muszą się zawierać w jednym batchu
Struktury tabel nie mogą być zmieniane w tym samym batchu
Błąd kompilacji zatrzyma wykonanie wszystkich instrukcji batcha
Błąd wykonania wstrzyma wykonanie kolejnych instrukcji
 USE tempdb;
GO
CREATE TABLE T1 (C1 int NOT NULL);
INSERT INTO T1 VALUES (1);
INSERT INTO T1 VALUES (2,2);
INSERT INTO T1 VALUES (3);
GO
SELECT * FROM T1;
DROP TABLE T1;
GO
 CREATE TABLE jest kompilowane, po kolei są kompilowane
instrukcje INSERT i wykonywane, ale druga Instrukcja zawiera błąd,
więc do tablei zostanie dodany tylko jeden wiersz
Zmienne
 Zmienną definiujemy poprzedzają jej nazwę małpą (@)
 W jednym batchu możemy użyć do 10^4 zmiennych
 DECLARE @Var1 int;
DECLARE @Var2 as varchar(25);
DECLARE @Var3 decimal(5,2),
@Var4 int;
 Przypisanie wartości:

SET @Var1 = 5;
SET @Var2 = ‘A varchar string’;
SELECT @Var2 = ‘Another varchar string’,
@Var3 = 123.45
Zmienne 2
 Inna forma przypisania (przy pomocy zapytania do bazy SELCT)
 USE PPDB;
DECLARE @CustName varchar(50);
SELECT @CustName = CustomerName
FROM Customer WHERE CustomerID = 1;
 Funkcje systemowe (np. @@Error) nazywane czasami (błędnie )
zmiennymi globalnymi
Instrukcje sterujące
 BEGIN … END grupuje instrukcje używane razem z IF, WHILE,
CASE
 IF … ELSE

USE AdventureWorks;
GO
UPDATE HumanResources.EmployeePayHistory
SET PayFrequency = 4
WHERE EmployeeID = 1;
IF @@ERROR <> 0 -- funkcja sysytemowa
BEGIN
PRINT ‘An error occured in the previous
statement.’;
RETURN;
END
ELSE
PRINT ‘No error occured in the previous
statement.’;
Instrukcje sterujące 2
 WHILE

DECLARE @Counter int;
SET @Counter = 1;
WHILE (@Counter <= 10)
BEGIN
PRINT @Counter;
SET @Counter = @Counter + 1;
END
 Powyżej mamy przykład typowej pętli, ale instrukcję WHILE można
też wykorzystywać z warunkiem EXISTS do wykonywania operacji
na wierszach tabeli

WHILE EXISTS (SELECT * FROM T1 WHERE C1 = 1)BEGIN
-- Wykonaj jakieś operacje na wierszach
-- tabeli T1 z warunkiem C1 = 1
END
 W instrukcji WHILE można korzystać z BREAK i CONTINUE,
których użycie jest typowe dla pętli („oczywista oczywistość”).
Instrukcje sterujące 3
 CASE

USE AdventureWorks2008;
GO
SELECT Name,
CASE Name
WHEN ‘Human Resources’ THEN ‘HR’
WHEN ‘Finance’ THEN ‘FI’
WHEN ‘Information Services’ THEN ‘IS’
WHEN ‘Executive’ THEN ‘EX’
WHEN ‘Facilities and Maintenance’ THEN ‘FM’
END AS Abbreviation
FROM AdventureWorks2008.HumanResources.Department
WHERE GroupName = ‘Executive General and Administration’;
 Instrukcja CASE jest używana w celu zamiany wartości kolumny w
zapytaniu SELECT. W Transact-SQL CASE przetwarza wiersz po
wierszu
Zarządzanie błędami
 Błędy składni
 Błędy wykonania
 PRINT ‘Przed błędem’;
SELECT 1/0;
PRINT ‘Po błędzie’;
 Komunikaty błędów
 Numer błędu (powyżej 50 000 błędy definiowalne przez użytkownika)
 Waga błędu (Severity Level) – powyżej 10 mają charakter informacyjny
 Stan (State) (liczba wskazujące gdzie pojawił się błąd?)
 Numer linii
 Tekst komunikatu
 Przykład:
 Przed błędem
 Msg 8134, Level 16, State 1, Line 2
 Divide by zero error encountered.
 Po błędzie
Zarządzanie błędami 2
 Blok TRY … CATCH …
 Składnia

BEGIN TRY
-- Kod mogący generować błędy
END TRY
BEGIN CATCH
-- Logika obsługi błędów
END CATCH;
 Blok CATCH musi następować zaraz po bloku TRY
 Wewnątrz bloku CATCH można użyć kilku funkcji informacyjnych
(por. następny slajd)
 Funkcje te użyte poza blokiem CATCH zwrócą NULL
Zarządzanie błędami 3
 Funkcje informacyjne bloku CATCH






ERROR_LINE()
ERROR_NUMBER()
ERROR_MESSAGE()
ERROR_PROCEDURE() jeśli błąd pojawił się w procedurze jej nazwa jest
zwracana, w przeciwnym razie NULL
ERROR_SEVERITY()
ERROR_STATE()
 Przykład:

USE AdventureWorks2008;
BEGIN TRY
SELECT 1/0;
END TRY
BEGIN CATCH
INSERT INTO dbo.ErrorLog (Line, Number, ErrorMsg, [Procedure],
Severity, [State])
VALUES (ERROR_LINE(), ERROR_NUMBER(), ERROR_MESSAGE(),
ERROR_PROCEDURE(), ERROR_SEVERITY(), ERROR_STATE());
END CATCH;
Zarządzanie błędami 4
 Funkcja @@ERROR
 Zwraca tylko numer błędu
 Instrukcje typu
 SELECT 1/0
 PRINT @@ERROR

Ale co będzie wynikiem poniższego kodu?
 SELECT 1/0;
IF @@ERROR <> 0
PRINT @@ERROR;

Warunek IF @@ ERROR <> 0 resetuje wartość funkcji !!!
Należy wiec użyć zmiennej pośredniej, która zapamięta stan funkcji


DECLARE @SaveError int;
SELECT 1/0;
SET @SaveError = @@ERROR;
IF @SaveError <> 0
PRINT @SaveError;
 Funkcji @@ERROR używamy głównie ze względu na
kompatybilność ze starszymi wersjami SQL Server np. 2000
Zarządzanie błędami 5
 Generacja błędów:
 Czasami chcemy / musimy wygenerować własne błędy (nie
przewidziane przez system)
 Posługujemy się wtedy procedurą składowaną sp_addmessage


Przykład:
EXEC sp_addmessage 50005, -- Message ID
10, -- Severity Level
‘ID bieżącej bazy: %d, nazwa bazy: %s.’;
 Instrukcja RAISEERROR wygeneruje odpowiedni błąd,
 Składnia:




RAISERROR ( { msg_id | msg_str | @local_variable }
{ ,severity ,state }
[ ,argument [ ,...n ] ] )
[ WITH option [ ,...n ] ]
Zarządzanie błędami 6
 Przykład:
 DECLARE @DBID int;
DECLARE @DBNAME nvarchar(128);
SET @DBID = DB_ID();
SET @DBNAME = DB_NAME();
RAISERROR (50005,
10, -- Severity.
1, -- State.
@DBID, -- First substitution argument.
@DBNAME); -- Second substitution argument.
GO
 Można też generować błędy bez dodawania komunikatów do systemu

RAISERROR (‘Custom Message’,
10, -- Severity
1); -- State
 Oprócz dodawania komunikatów mamy też ich usuwanie:

sp_dropmessage
Procedury składowane (MSSQL)
 Procedury składowane są zbiorami operacji przechowywanymi na





serwerze i wykonywanymi przez klienta aplikacji.
Wartości parametrów mogą być przekazywane do procedury
przechowywanej jako wejścia.
Parametry wyjściowe mogą być używane do zwracania wartości
zmiennej do kodu wywołującego.
Procedura składowana może mieć s sumie do 2100 parametrów.
Pojedyncza wartość całkowita jest zazwyczaj używana do
wskazywania sukcesu lub porażki (wykonania procedury).
Istnieje wiele operacji, które mogą być wykonywane przez procedury
przechowywane w bazie danych:
 Zmiana struktury bazy danych i wykonywanie zdefiniowanych
przez użytkownika transakcje są powszechnymi operacjami
 Procedury składowane mogą być wykorzystane do zwracania
wyniku zapytania SELECT, ale istnieją lepsze narzędzia
Procedury składowane 2
 Omówimy budowanie procedur składowanych Transact-SQL, ale
możliwe jest również zbudowanie takich procedur przy użyciu .NET
(CLR)
 Zalety:



Bezpieczeństwo:
 Prawo do wykonania procedury składowanej jest przyznawane niezależnie
od dostępu do obiektów bazy danych których ona dotyczy.
 Użytkownik, który uzyskuje dostęp do wykonania procedury
składowanej może wykonywać wszystkie operacje w procedurze
przechowywanej. Możliwe jest również , że wykonujemy ją jako inny
użytkownik.
Modularne programowanie:
 Wielokrotne wykorzystywanie,
 Skomplikowane procedury mogą być rozbijane na bloki
Czas wykonania


Procedury są kompilowane raz (w zasadzie)
Czas przesyłania kodu do serwera
Procedury składowane 3
 Wiele operacji bazodanowych może być wykonanych przez inne
obiekty/struktury
 Procedury składowane mogą wykonać prawie wszystkie operacje.
Ale poniższe są zabronione:
 Tworzenie lub modyfikacja następujących obiektów:








Aggregate
Default
Function
Procedure
Rule
Schema
Trigger
View

Instrukcja USE

SET PARSEONLY lub warianty SHOWPLAN
Procedury składowane 4
 Procedura może zwrócić więcej niż jeden zbiór rezultatów do






wywołującej ją aplikacji.
Funkcje tablicowe definiowalne przez użytkownika są lepszym
rozwiązaniem jeśli ma być zwrócony jeden wynik.
Wyniki procedury nie mogą być używane w klauzuli FROM
kwerendy (istnieje funkcja OPENQUERY(), która pozwala na
obejście tego ograniczenia).
Procedury mogą korzystać z tablic tymczasowych.
Tablica tymczasowa istnieje tylko na czas działania procedury.
Procedura zagnieżdżona może korzystać z tablic tymczasowych
utworzonych przez procedurę wywołującą (nadrzędną).
Odwołując się do obiektów wewnątrz procedury zalecane jest
używanie nazwy schematu, unika się w ten sposób błędów
związanych z domyślnym przeszukiwaniem bazy przez procedurę.
Procedury składowane 5
 Składnia

CREATE PROC[EDURE] [schema_name.]proc_name
[({@param1} type1 [ VARYING] [= default1] [OUTPUT])] {, …}
[WITH {RECOMPILE | ENCRYPTION | EXECUTE AS 'user_name'}]
[FOR REPLICATION]
AS batch | EXTERNAL NAME method_name

schema_name – nazwa schematu do którego jest
przypisywana tworzona procedura.
proc_name – oczywista …
Parametr procedury składowanej ma taki sam sens logiczny jak
zmienna lokalna w batchu
@param1 – nazwa pierwszego parametru
type1 - typ pierwszego parametru
default1 – opcjonalna wartość domyślna (może być NULL)
OUTPUT – wskazuje, że parametr może zwrócić wartość z
procedury do systemu (wywołującej aplikacji)






Procedury składowane 6
 Prekompilowana postać procedury jest przechowywana na serwerze
 Opcja WITH RECOMPILE spowoduje, że procedura będzie
rekompilowana przed każdym użyciem.
 To niszczy jedną z ważnych zalet procedur.
 Klauzula EXECUTE AS określa kontekst bezpieczeństwa (jako kto)
wykonywania procedury. W ten sposób można kontrolować, którego
konta użyje baza danych do sprawdzenia uprawnień do obiektów, z
których korzysta procedura.
 Domyślnie tylko członkowie ról sysadmin, db_owner oraz
db_ddladmin mogą wykorzystywać instrukcję CREATE
PROCEDURE. Ale zgodnie z zasadami, członkowie tych ról mogą
przekazać te uprawnienia innym użytkownikom przy pomocy
polecenia GRANT CREATE PROCEDURE.
Procedury składowane 7
 Przykład
 USE sample;
GO
CREATE PROCEDURE increase_budget (@percent INT=5)
AS UPDATE project
SET budget = budget + budget*@percent/100;
 Można tworzyć procedury tymczasowe: lokalne (#nazwa_procedury)
i globalne (##nazwa_procedury).
 Stosują się do nich podobne zasady jak do tablic tymczasowych
 Procedury mają (w pewnym sensie) dwie fazy : faza tworzenia i faza
wykonania
 Polecenie EXECUTE wykonuje istniejąca procedurę (kto może
wykonywać daną procedurę?)
Procedury składowane 8
 Składnia

[[EXEC[UTE]] [@return_status =] {proc_name| @proc_name_var}
{[[@parameter1 =] value | [@parameter1=] @variable
[OUTPUT]] | DEFAULT}..
[WITH RECOMPILE]
 Wszystkie opcje poza @return_status mają analogiczne znaczenie
jak w instrukcji tworzenia procedury
 @return_status – przechowuje status wykonania procedury
 Przykład:

SELECT * FROM project;
EXEC increase_budget 7;
SELECT * FROM project;
GO
Procedury składowane 9
 Przykład z wykorzystaniem opcji OUTPUT


USE sample;
GO
CREATE PROCEDURE delete_emp @employee_no INT, @counter INT
OUTPUT
AS
SELECT @counter = COUNT(*)
FROM works_on
WHERE emp_no = @employee_no
DELETE FROM employee
WHERE emp_no = @employee_no
DELETE FROM works_on
WHERE emp_no = @employee_no
GO
-DECLARE @quantity INT – deklarcja
EXECUTE delete_emp @employee_no=28559, @counter=@quantity
OUTPUT
PRINT @quantity
GO
Procedury składowane 10
 Usuwanie procedury
DROP PROCEDURE nazwa_procedury
 Modyfikacja procedury składowanej
 ALTER PROCEDURE …
 Jest to praktycznie ta sama składnia co dla CREATE
PROCEDURE
 Po co skoro można DROP PRCEDURE oraz CREATE PROC ?
 Ale wtedy znikają zdefiniowane już uprawnienia

Procedury składowane 11
 Od wersji SQL Server 2008 można do procedury przekazywać
parametry o wartościach tabelarycznych (czyli tabele)
 Jest to jedno z lepszych rozszerzeń wprowadzonych do tej wersji
serwera
 Przykład:

W poniższym kodzie korzystamy z typu tablicowego OrderDetailsType,
który musiał być wcześniej zdefiniowany

CREATE
PROC OrderTransactionUpdateTVP (
@OrderID INT OUTPUT, @CustomerID INT,
@OrderDate DateTime, @Details as OrderDetailsType
READONLY )
AS
SET NoCount ON ;
Begin Try
Begin Transaction;
-- Jeśli @OrderID jest NULL to mamy nowe
-- zamówienie a wiêc dodajemy do tabeli ORDER
Procedury składowane 11
If @OrderID IS NULL
BEGIN;
Insert Orders(OrderDate, CustomerID)
Values (@OrderDate, @CustomerID);
-- Get OrderID value from insert
SET @OrderID = Scope_Identity();
END;
-- poniższa instrukcja tylko wyświetla zawartość tabeli
ale można z nią zrobić dużo więcej...
SELECT * FROM @Details ;
Commit Transaction;
End Try
Begin Catch;
RollBack;
End Catch
RETURN;
GO
 Teraz wykorzystamy tą procedurę
Declare @OrderID INT;
DECLARE @DetailsTVP as OrderDetailsType;
INSERT @DetailsTVP
(LineNumber,ProductID,IsNew,IsDirty,IsDeleted)
VALUES
(5, 101, -1, -1, 0),
(2, 999, 0, -1, 0),
(3, null, 0, 0, 0);
exec OrderTransactionUpdateTVP
@OrderID = @OrderID Output ,
@CustomerID = '78',
@OrderDate = '2008/07/24',
@Details = @DetailsTVP;
 Procedura powinna wypisać wartości z tabeli @DetailsTVP
Funkcje definiowalne (UDF)
 UDF mogą zawierać skomplikowaną logikę T-SQL w kwerendzie i
rozwiązywać problemy, które były niemożliwe do rozwiazania lub
wymagały użycia kursorów.
 Dzisiaj stają się jednym z podstawowych narzędzi programisty baz
danych.
 Zalety:
 Por. pierwsze zdanie slajdu „I’ve solved several nasty problems
using user-defined functions” Paul Nilsen .
 Mogą być użyte do budowania nowych funkcji dla
skomplikowanych wyrażeń
 Oferuje podobne zalety jak widoki, gdyż mogą być użyte w
klauzuli FROM. Ponadto pozwalają na użycie parametrów,
czego nie maja widoki.
 Oferują zalety procedur składowanych, gdyż są kompilowane i
optymalizowane w ten sam sposób
UDF 2
 Głównym argumentem przeciwko korzystaniu z UDF może być
zmniejszenie wydajności, przy niewłaściwym ich użyciu
 Jakakolwiek funkcja, która ma być użytq w każdym wierszu w
warunku WHERE na pewno pogorszy (i to chyba znacznie)
wydajność.
 Trzy typy UDF
 Funkcje skalarne zwracające pojedynczą wartość
 Funkcje „Inline” o wartościach tabelarycznych. Podobne do
widoków
 Wielo–liniowe funkcje o wartościach tabelarycznych, tworzące
zbiór wyników przy pomocy kodu
UDF 3
 Funkcje skalarne

Wartość jest zwracana przez polecenie RETURN
Muszą być deterministyczne – dla tych samych parametrów
zwracać tą samą wartość (nie można więc korzystać z
newid(), rand())

Nie mogą modyfikować bazy

Nie mogą zwracać wartości typu blob, text, ntext, timestamp,
image ani wartości typu tabelarycznego czy typu kursora.

Nie mogą zawierać TRY. . .CATCH ani RAISERROR.
Mogą wywoływać inne UDFy lub też same siebie(aż do 32
poziomu zagnieżdżenia).


UDF 4
 Szablon funkcji skalarnej:

CREATE FUNCTION FunctionName (InputParameters)
RETURNS DataType
AS
BEGIN;
Code;
RETURN Expression;
END;
Parametry wejścia muszą określać również typ, może być
podana wartość domyślna
 Przykład:


CREATE FUNCTION dbo.fsMultiply (@A INT, @B INT = 3)
RETURNS INT
AS
BEGIN;
RETURN @A * @B;
END;
go
SELECT dbo.fsMultiply (3,4),
dbo.fsMultiply (7, DEFAULT);
UDF 5
 Funkcje typu inline
 Składnia

CREATE FUNCTION FunctionName (InputParameters)
RETURNS Table
AS
RETURN (Select Statement);

Pełnią rolę podobną do widoków ale mogą mieć parametry
Przykład:
 USE OrderProcessingSystem;
GO
CREATE FUNCTION ppinline1(@custcode as int)
RETURNS TABLE
AS
RETURN(
SELECT * FROM orders o JOIN products p ON
o.product=p.code
WHERE CustomerAccount=@custcode);
GO
SELECT * FROM ppinline1(4504);

UDF 6
 Wieloliniowe funkcje tabelaryczne
 Składania:

CREATE FUNCTION FunctionName (InputParamenters)
RETURNS @TableName TABLE (Columns)
AS
BEGIN;
-- kod, który wypełni tabelę
RETURN;
END;
UDF 7

Przykład:
 CREATE FUNCTION ppmulti1()
RETURNS @pp1 TABLE (
ca int,
kwota money)
AS
BEGIN
INSERT @pp1 SELECT CustomerAccount, sum(StoreSales)
FROM orders group by CustomerAccount;
-- tutaj moze być wiele instrukcji SQLa;
RETURN
END;
GO

SELECT * FROM ppmulti1()
UDF 8
 Skorelowanie UDF

CREATE FUNCTION ppmulti2( @AC as int)
RETURNS @pp1 TABLE (
AccountNumber int,
kwota money)
AS
BEGIN
IF @AC IS NULL
INSERT @pp1 SELECT CustomerAccount, sum(StoreSales)
FROM orders group by CustomerAccount;
ELSE
INSERT @pp1 SELECT CustomerAccount, sum(StoreSales)
FROM orders
WHERE CustomerAccount=@AC
GROUP BY CustomerAccount;
RETURN
END;
GO
UDF 8

SELECT * FROM ppmulti2(5224) ORDER BY AccountNumber DESC

SELECT c.AccountNumber, Firstname, LastName, kwota
FROM Customers C CROSS APPLY ppmulti2(C.AccountNumber);

 Wiązanie schematu (schema binding!)
 Jeśli w definicji funkcji użyjemy opcji
WITH SCHEMA BINDING
 To nie będziemy mogli usuwać tabel do których odnosi się dana
funkcja, a nawet nie będzie można modyfikować tabel, a
przynajmniej tej części ich struktury do której odnosi się funkcja.

Wyzwalacze (triggers)
 Wyzwalacz trigger jest poleceniem, które jest wykonywane
automatycznie jako dodatkowy skutek modyfikacji bazy danych.
 Aby zaprojektować wyzwalacz musimy:
 określić „czas” i „warunki” w jakich wyzwalacz ma zostać
aktywowany
 określić działania wykonywane przez ten wyzwalacz.
 Wyzwalacze wprowadzono do standardu dopiero w SQL-1999, ale
w wielu implementacjach istniały już znacznie wcześniej.
Wyzwalacze 2
 Ogólna postać:

CREATE TRIGGER <nazwa>
BEFORE | AFTER | INSTEAD OF <zdarzenia>
<klauzula referencyjna> // optional
FOR EACH ROW // optional
WHEN (<warunek>) // optional
<akcja>
gdzie <zdarzenia> mogą być:
INSERT ON R
DELETE ON R
UPDATE [OF A1, A2, ..., An] ON R
AFTER <zdarzenia> są najbardziej użyteczne i powszechne.
Pozostałe generują problemy i nie zaleca się ich używania
(Widom)
Wyzwalacze (triggers)
 <warunek>: jak zwykle
 <działanie>: sekwencja poleceń SQL
 FOR EACH ROW (/ FOR EACH STATEMENT)




Jeśli obecne wykonuje wyzwalacz raz dla każdej zmienianej
krotki.
Jeśli nie ma to wykonuje dla każdej instrukcji (for each
statement)
Terminologia: "row-level" kontra "statement-level"
W każdym przypadku wyzwalacz wykonuje się po tym jak
polecenie się wykona (after statement completes).
Wyzwalacze (triggers)
 <klauzula referencyjna>:
REFERENCING <obiekt1> AS <var1> <obiekt2> AS <var2>, itd.
<obiekt> może być:
 OLD TABLE – poprzednimi wartościami usuniętych lub uaktualnionych
krotek, poziom wierszy lub poziom poleceń, DELETE lub UPDATE
 NEW TABLE - poprzednimi wartościami usuniętych lub uaktualnionych
krotek, poziom wierzy lub poziom poleceń, INSERT lub UPDATE
 OLD ROW – poprzednia wartość usunietej lub uaktualnionej krotki, tylko
poziom wierszy, DELETE lub UPDATE
 NEW ROW - poprzednia wartość watawionej lub uaktualnionej krotki,
tylko poziom wierszy, INSERT lub UPDATE
Wyzwalacze (przykłady)
 Jeśli wstawiana jest krotka do tabeli Aplikacja dla kandydata z oceną >3.9 i
IQ>150 do UMK, ustaw decyzję na tak.




CREATE TRIGGER AutoAccept
AFTER INSERT ON Aplikacja
REFERENCING NEW ROW AS NewApp
FOR EACH ROW WHEN
(
NewApp.miejsce = ‘UMK' AND
3.9 < (SELECT ocena FROM Student WHERE ID = NewApp.ID) AND
150 < (SELECT IQ FROM Student WHERE ID = NewApp.ID)
)
UPDATE Aplikacja
SET decyzja = ‘T'
WHERE ID = NewApp.ID
AND miejsce = NewApp.miejsce
AND data = NewApp.data
Wyzwalacze (przykłady)
 To samo ale bez FOR EACH ROW.
 CREATE TRIGGER AutoAccept
 AFTER INSERT ON Aplikacja
 REFERENCING NEW TABLE AS NewApps
 UPDATE Aplikacja
SET decyzja = ‘T'
WHERE ((ID,miejsce,data) IN (SELECT ID,miejsce,data FROM NewApps)
and NewApp.location = ‘UMK'
AND 3.9 < (SELECT ocena FROM Student WHERE ID = NewApp.ID)
AND 150 < (SELECT IQ FROM Student WHERE ID = NewApp.ID))
Inny przykład wyzwalacza
 Przypuśćmy, że zamiast pozwalać na ujemne stany na rachunkach
bank prowadzi następującą politykę
 ustala stan rachunku na zero
 otwiera kredyt z kwotą równą debetowi
 nadaje kredytowi numer taki sam jak numer rachunku na którym
zrobiono debet
 Warunkiem wykonania wyzwalacza jest zmiana relacji rachunek
powodująca, że stan przyjmuje wartość ujemną.
Przykład wyzwalacza SQL:1999
create trigger debet_trigger after update on rachunek
referencing new row as nrow
for each row
when (nrow.stan < 0)
begin atomic
insert into kredytobiorca
(select klient_numer, rachunek_numer
from depozytor
where nrow.rachunek_numer =
depozytor.rachunek_numer);
insert into kredyt values
(nrow.rachunek_numer, nrow.oddzial_nazwa, -nrow.stan);
update rachunek set stan = 0
where rachunek.rachunek_numer = nrow.rachunek_numer;
end
Wyzwalacze: zdarzenia i akcje w SQL
 Zdarzenie wyzwalającym może być insert, delete lub update
 Wyzwalacze przy zmianie krotki mogą być ograniczone do
określonych atrybutów (stan)
 Np. create trigger debet_trigger after update of stan on
rachunek
 Można dowoływać się zarówno do wartości przed jak i po
modyfikacji
 referencing old row as : w przypadki usuwania i zmiany
 referencing new row as : w przypadku wstawiania i zmiany
 Wyzwalacze mogą być aktywowane przed i po zdarzeniu co może
służyć jako dodatkowe więzy. Np. zmienić spacje na null.
create trigger setnull_trigger before update on r
referencing new row as nrow
for each row
when nrow.telefon_numer = ‘ ‘
set nrow.telefon_numer = null
Różne poziomy „wyzwalania”
 Zamiast wykonywać osobne działanie dla każdego wiersza można
wykonać pojedyncze działanie dla wszystkich wierszy
podlegających tej transakcji
 Używamy
for each statement zamiast for each row
 Używamy
referencing old table albo referencing new
table aby odwoływać się do tymczasowych tabel (transition
tables) zawierających zmodyfikowane wiersze
 Warto stosować w sytuacjach, gdy mamy zmienić dużą liczbę
wierszy
Działania zewnętrzne
 Czasami chcemy aby wyzwalacze były aktywowane z zewnątrz
Np. wykonanie zamówienia produktu , którego ilość w hurtowni
znacznie zmalała, włączenie się alarmu,
 Wyzwalacze nie mogą być wykorzystane do bezpośredniej implementacji
działania świata zewnętrznego, ale!
 Wyzwalacze mogą być wykorzystane do zapisania w osobnej tabeli
działań, które mają być podjęte
 Możemy posiadać proces, który w sposób ciągły analizuję tabelę,
przeprowadza działanie zapisane w tabeli i następnie usuwa działanie
z tabeli
 Np. Złóżmy, że hurtownia posiada następujące tabele
 zapasy(produkt, poziom): Ile tego mamy w hurtowni
 minpoziom(produkt, poziom) : Jaki jest poziom mimalny produktu
 ponow_zam(produkt, liczba): Ile powinniśmy zamówić jednorazowo
 zamowienia(produkt, liczba) : Zamówienia do wykonania wykonuje je
proces zewnętrzny w stosunku do bazy danych

Działania zewnętrzne (cd.)
create trigger zamow_trigger after update of liczba on zapasy
referencing old row as orow, new row as nrow
for each row
when nrow.poziom < = (select poziom
from minpoziom
where minpoziom.produkt = orow.produkt)
and orow.poziom > (select poziom
from minpoziom
where minpoziom.produkt = orow.produkt)
begin
insert into zamowienia
(select produkt, liczba
from ponow_zam
where ponow_zam.produkt = orow.produkt)
end
Wyzwalacze w MS-SQL
 CREATE TRIGGER [schema_name.]trigger_name
ON {table_name | view_name}
[WITH dml_trigger_option [,…]]
{FOR | AFTER | INSTEAD OF} { [INSERT] [,] [UPDATE] [,] [DELETE]}
[WITH APPEND]
{AS
sql_statement | EXTERNAL NAME method_name
}
 Klauzula WITH <trigger_option> może zawierać dwie różne opcje:
 WITH ENCRYPTION wskazuje, że kod T-SQL wyzwalacza powinien
być ukryty lub zakodowany
 WITH EXECUTE AS `nazwa użytkownika”
Wyzwalacze w MS-SQL
create trigger debet_trigger on rachunek
for update
as
if inserted.stan < 0
begin
insert into kredytobiorca
(select klient_numer,rachunek_numer
from depozytor, inserted
where inserted.rachunek_numer =
depozytor.rachunek_numer)
insert into kredyt values
(inserted.rachunek_numer, inserted.oddzial_nazwa,
– inserted.stan)
update rachunek set stan = 0
from rachunek, inserted
where rachunek.rachunek_numer = inserted.rachunek_numer
end




Nie ma before, zamiast after użyto on update
Slowo kluczowe AS rozpoczyna opis działania
Zamiast warunku when użyto if
inserted, deleted zamiast referencing new/old table
Kiedy nie należy używać wyzwalaczy
 Dawniej wyzwalaczy używano do
obsługi danych podsumowujących (np. całkowita pensja w
każdym dziale)
 Replikacji bazy danych poprzez zapisywanie zmian do
specjalnych relacji (change lub delta) i stosowanie osobnego
procesu zewnętrznego do zastosowania tych zmian na kopii
bazy danych.
 Dzisiaj robimy to lepiej:
 dane podsumowujące obsługujemy poprzez tzw. widoki
zmaterializowane
 Bazy danych posiadają wbudowane mechanizmy replikacji
 Zamiast wyzwalaczy stosuje się „enkapsulację” (pojęcie z języków
obiektowych)
 Definiuje się metody zmieniające dane
 Działania przeprowadza się jako część tych metod
 Wyzwalacz może wywołać kolejny wyzwalacz (zapętlenie!)

Wyzwalacze – Zalety
 Wyzwalcze dostarczają alternatywnego sposobu sprawdzania
spójności
 Wyzwalacz może wychwycić błędy w logice biznesowej na poziomie
bazy danych.
 Wyzwalacz dostarcza alternatywnego sposobu wykonania zadania
w kolejce. Nie trzeba czekać na kolejkę zadań aby wykonać
zadanie. Można je wykonać przed lub po zmianach w tabelach
bazy danych.
 Wyzwalacz jest bardzo przydatny, gdy używamy go do sprawdzanie
zmian w tabelach bazy danych.
Wyzwalacze - Wady
 Wyzwalacz może dostarczyć tylko rozszerzonej walidacji, nie może
zastąpić innych walidacji. Niektóre proste walidacje mogą być
wykonywane na poziomie aplikacji. Na przykład, mona sprawdzić
dane wprowadzane po stronie klienta przy pomocy javascriptlub po
stronie serwera przy pomocy PHP lub ASP.NET.
 Wyzwalacze wykonują się „niewidzialnie” dla klienta, który łączy się
z serwerem bazy danych, tym samym trudno jest wywnioskować co
się zdarzyło po stronie serwera.
 Wyzwalacze wykonują się przy każdej modyfikacji tabeli, zwiększa
obciążenie bazy danych i spowalnia system.
 Wyzwalacze czy procedury składowane? Zależnie od sytuacji, ale
zasadą może być, że jeśli nie mona czegoś zrobić przy pomocy
procedury składowanej, powinniśmy użyć wyzwalacza.
Procedury składowane
Bezpieczeństwo
 Bezpieczeństwo – zabezpieczenie przed próbami kradzieży lub
modyfikacji danych.
 Poziom bazy danych



Poziom systemu operacyjnego


Mechanizmy autoryzacji i autentykacji, które pozwalają
określonym użytkownikom na dostęp tylko do odpowiednich
danych
Omawiamy głównie autoryzację
Tzw. su systemu operacyjnego mogą zrobić prawie wszystko z
bazą danych! Dlatego wymagane są doskonałe zabezpieczenia
na tym poziomie
Poziom sieci – musimy używać szyfrowania aby zapobiec:


podsłuchowi (nieautoryzowanemu czytaniu komunikatów)
maskaradzie (udawaniu użytkownika autoryzowanego,
przykłady)
Bezpieczeństwo (cd.)

Poziom fizyczny


Fizyczny dostęp do komputerów (kłódka i klucz)
Klęski żywiołowe (wichury, powodzie, pożary, ...)
 Odzyskiwanie danych !

Poziom ludzki


Czy użytkownicy nie „sprzedają” dostępu do danych
Muszą znać podstawowe zasady wyboru bezpiecznych haseł
(nie może to być imię żony i liczba dzieci ani żadne obsceniczne
słowo – Seksmisja!!!)
Autoryzacja
Zakresy autoryzacji na częściach bazy danych (por. MySQL) :
 Read – może przeglądać dane.
 Insert – może wstawiać nowe dane ale nie może zmieniać
istniejących.
 Update – może zmieniać ale nie może usuwać.
 Delete – może usuwać.
Zakresy autoryzacji dla schematów bazy danych
 Index – tworzy i usuwa indeksy.
 Resources – może tworzyć nowe relacje.
 Alteration – może modyfikować schematy relacji (zmieniać
atrybuty).
 Drop – może usuwać relacje.
Nadawanie uprawnień
 Przekazywanie uprawnień od jednego użytkownika do




innego może być reprezentowane przy pomocy grafu .
Węzły tego grafu przedstawiają użytkowników.
Wierzchołkiem grafu jest zawsze administrator bazy
(DBA).
Graf dla nadawania uprawnień update na tabeli kredyt.
Linia Ui  Uj , mówi, że użytkownik Ui nadał uprawnienia
update na loan użytkownikowi Uj.
Graf nadawania uprawnień
 Wymagania: Wszystkie krawędzie grafu muszą być częścią
ścieżki mającej początek na DBA
 Jeśli DBA odwoła uprawnienia użytkownikowi U1:
 Uprawnienia muszą być odebrane U4 gdyż U1 nie ma już
uprawnień
 Uprawnienia nie mogą być odebrane U5 gdyż posiada on
również uprawnienia nadane przez U2
 Nie może być ścieżek, które nie mają połączenia z DBA:
 DBA nadaje uprawnienia U7
 U7 nadaje uprawnienia U8
 U8 nadaje uprawnienia U7
 DBA usuwa uprawnienia U7
 Uprawnienia U7 dla U8 oraz U8 dla U7 muszą zostać usunięte bo
nie ma już ścieżki od DBA ani do U7 ani do U8.
Określanie autoryzacji w SQL
 Polecenie grant jest używane do przekazania (nadania)
uprawnień
grant <lista uprawnień>
on <nazwa relacji lub widoku> to <lista użytkowników>
 < lista użytkowników > ma postać:
 identyfikator użytkownika
 public, co nadaje uprawnienia wszystkim użytkownikom
 rola (o rolach później)
 Nadanie uprawnień do widoku nie implikuje uprawnień do
relacji, na których widok jest zbudowany.
 Nadający uprawnienia musi posiadać nadawane uprawnienia
lub być administratorem bazy danych.
Uprawnienia w SQL
 select: pozwala na odczyt danych z relacji, jak również na




wykonywanie kwerend z wykorzystaniem widoków
 Przykład: nadaj użytkownikom U1, U2, oraz U3 uprawnienia
select do relacji oddzial:
grant select on oddzial to U1, U2, U3
insert: uprawnienia do wstawiania krotek
update: uprawnienia do zmiany wartości atrybutów przy pomocy
polecenia SQL update
delete: uprawnienia do usuwania krotek w relacji
all privileges: wszystkie dopuszczalne uprawnienia
Uprawnienie do nadawania uprawnień
 with grant option: pozwala aby użytkownik posiadający
uprawnienia mógł przekazywać te uprawnienia innym
użytkownikom.
 Przykład:
grant select on oddzial to U1 with grant option
Odbieranie uprawnień w SQL
 Polecenie revoke odbiera uprawnienia.





revoke <lista uprawnień>
on <nazwa relacji lub widoku> from <lista użytkowników>
Przykład:
revoke select on oddzial from U1, U2, U3
<lista przywilejów> może składać się z jednego słowa all. W
takim przypadku odbieramy wszystkie przywileje.
Jeśli <lista użytkowników> zawiera public, wszyscy
użytkownicy, którym nie nadano tego przywileju indywidualnie
tracą uprawnienia.
Można zachować uprawnienia po ich odwołaniu jeżeli nadało je
dwóch różnych użytkowników a tylko jeden je odwołał.
Wszystkie przywileje, które zależą od odbieranego są również
odbierane.
Ograniczenia autoryzacji w SQL
 SQL nie pozwala na autoryzację na poziomie krotek
Np. nie można spowodować aby student widział tylko krotki
odpowiadające swoim danym (to robimy przy pomocy
widoków)
 Wraz z rozwojem sieciowych baz danych pojawiają się nowe
problemy, gdyż większość użytkowników takich baz posiada
jeden (ten sam) identyfikator
 Zadanie autoryzacji w powyższych przykładach przenosi się na
programy aplikacyjne, tzn. poza SQL.
 Zaleta: Szczegółowe rozróżnienie autoryzacji, takie jak dostęp
do indywidualnych krotek może być implementowane na
poziomie aplikacji zewnętrznej
 Wada: autoryzacja spada na programistę, łatwo o błędy np.
dziury w systemie zabezpieczeń

Historia zmian
 Historia zmian – zapis wszystkich zmian (insert/delet/update) na
bazie danych razem z informacją kto, kiedy i gdzie ( z jakiego IP)
je wykonał.
 Korzysta się z niej aby wyśledzić odpowiedzialnych za
wprowadzenie błędnych danych.
 Można je zaimplementować przy pomocy wyzwalaczy ale wiele
baz danych posiada wbudowane odpowiednie narzędzia.
Role
 Role pozwalają na definiowanie zestawu przywilejów dla
grupy użytkowników poprzez tworzenie odpowiednich
“ról”
 Przywileje można nadawać i odpierać rolom tak samo jak
użytkownikom
 Role mogą być przypisane użytkownikom a także innym
rolom
 SQL:1999 zawiera pojęcie ról
create role urzednik
create role menadzer
grant select on oddzial to urzednik
grant update (stan) on rachunek to urzednik
grant all privileges on rachunek to menadzer
grant urzednik to mendzer
grant urzednik to alicja, bolek
grant menadzer to czeslaw
„Zanurzony” (Embedded) SQL
 Standard SQL definiuje zanurzenie SQLa w szeregu
standardowych językach programowania takich jak C, Java czy
Cobol.
 Język do którego wprowadza się polecenia SQL nazywamy
językiem gospodarza (host language), a struktury języka
udostępnione w ten sposób nazywamy zanurzeniem SQL
(embedded SQL)
 Polecenie EXEC SQL używane jest do identyfikowania
zanurzonego SQLa przez tzw. preprocesor
EXEC SQL <polecenie zanurzonego SQL > END_EXEC
Ale w niektórych językach może być nieco inaczej np w Javie:
# SQL { …. };
Przykład
 Z poziomu języka gospodarza znajdź nazwy i miasta klientów z
kwotą większą niż zmienna suma na jakimkolwiek rachunku.
 Określamy kwerendę SQL i deklarujemy dla niej cursor
EXEC SQL
declare c cursor for
select depozytor.klient_nazwisko, klient_miasto
from depozytor, klient, rachunek
where depozytor.klient_nazwisko = klient.klient_nazwisko
and depozytor rachunek_numer =
rachunek.rachunek_numer
and rachunek.stan > :suma
END_EXEC
Zanurzony SQL (Cd.)
 Polecenie open powoduje wykonanie kwerendy
EXEC SQL open c END_EXEC
 Polecenie fetch powoduje, że wartości pojedynczej krotki zostają
umieszczone w zmiennych języka gospodarza.
EXEC SQL fetch c into :cn, :cc END_EXEC
Powtarzanie tej komendy „wyciąga” kolejne krotki z wyniku kwerendy
 W ramach języka istnieje tzw. obszar komunikacyjny SQLCA i
zmienne, które przyjmują odpowiednie wartości przy określonych
zdarzeniach, np. zmienna SQLSTATE przyjmuje wartość ‘02000’ jeśli
w wyniku kwerendy nie ma już dalszych krotek.
 Polecenie close powoduje zamknięcie przez bazę danych
tymczasowej relacji przechowującej wynik kwerendy.
EXEC SQL close c END_EXEC
W Javie jest trochę inaczej (bardziej naturalnie)
Modyfikacje poprzez kursor
 Możemy zmodyfikować bazę z poziomu zanurzonego SQL. Jeżeli
chcemy do każdego rachunku w oddziale Toruń dodać 100 zł to
najpierw wykonujemy polecenie:
declare c cursor for
select *
from rachunek
where oddzial_nazwa = ‘Toruń’
for update
 A potem pobieramy kolejne rekordy (fetch) i po każdym pobraniu
wykonujemy polecenie
update rachunek
set stan = stan + 100
where current of c
ODBC i JDBC
 API (application-program interface) dla programów komunikujących
się z serwerami baz danych
 Aplikacje odwołują się do funkcji API aby
 Połączyć się z bazą danych
 Wysłać polecenia SQL do serwera baz danych
 Pobrać krotki wyniku (jedna po drugiej i zapisać je w zmiennych
programu)
 ODBC (Open Database Connectivity) działa z językami C, C++, C#,
raz Visual Basic
 JDBC (Java Database Connectivity) współpracuje Javą
ODBC
 Standard Open DataBase Connectivity (ODBC)


jest standardem dla aplikacji do komunikowanie się z
serwerem bazy danych
po to aby



otworzyć połączenie z bazą,
wykonywać zapytania i modyfikować bazę danych,
pobierać wyniki zapytań.
 Aplikacje takie jak GUI, arkusze kalkulacyjne, ... mogą korzystać
z ODBC
ODBC (cd.)
 Każdy system bazodanowy „współpracujący z” ODBC dostarcza
sterownika (biblioteki) która musi być „linkowana” z programem
klienckim.
 Kiedy program klienta wywołuje ODBC API, kod w bibliotece
komunikuje się z serwerem aby wykonać żądaną operację i
zwrócić jej wynik.
 Połączenie z bazą danych otwiera SQLConnect(). Parametrami
są :




uchwyt połączenia,
serwer z którym chcemy się połączyć
id użytkownika,
hasło
Przykład kodu ODBC
 int ODBCexample()
{
RETCODE error;
HENV
env;
/* environment */
HDBC
conn; /* database connection */
SQLAllocEnv(&env);
SQLAllocConnect(env, &conn);
SQLConnect(conn, „ferm.fizyka.umk.pl", SQL_NTS, „pp",
SQL_NTS, „pppasswd", SQL_NTS);
{ …. zrób coś w bazie danych … }
SQLDisconnect(conn);
SQLFreeConnect(conn);
SQLFreeEnv(env);
}
Funkcje i procedury
 SQL:1999 wprowadza funkcje i procedury
Funkcje/procedury mogą być pisane w SQL lub zewnętrznym
języku programowania
 Niektóre systemy bazodanowe dostarczają funkcji o
wartościach typu tabelarycznego (wynikiem funkcji jest
relacja)
 SQL:1999 dostarcza podstawowego zestawu poleceń
typowych dla zwykłych języków programowania
 pętle, konstrukcja if-then-else, przypisania
 Wiele systemów baz danych posiada własne rozwiązania
niezgodne z tym standardem

Download