Programowanie w SQL procedury i funkcje UWAGA: Proszę nie zapominać o prefiksowaniu nazw obiektów ciągiem [OLIMP\{nr indeksu}] Funkcje użytkownika 1. Funkcje o wartościach skalarnych ang. scalar valued user defined function zwracają jako wynik pojedyńczą wartość. Instrukcja tworząca przykładową funkcję skalarną poniżej: CREATE FUNCTION guid studenta @nr indeksu varchar 6 S uniqueidentifier SELECT guid FROM studenci WHERE nr indeksu = @nr indeksu Przykład wykorzystania funkcji a zarazem wywołanie funkcji w innej funkcji: CREATE FUNCTION srednia@nr indeksu varchar 6 S float SELECT AVGCT ocena float FROM egzaminy WHERE student guid = dbo.guid studenta@nr indeksu Z kolei wywołanie funkcji dbo.guid studenta może wyglądać następująco: SELECT dbo.srednia100000 W celu usunięcia funkcji wystarczy wykonać polecenie: DROP FUNCTION dbo.srednia 2. Funkcje o wartościach tabelarycznych ang. table valued function są nazywane również sparametryzowanymi widokami, zwracają jako wartość tablicę rekordów, na przykład: CREATE FUNCTION oceny@nr indeksu varchar 6 S TABLE
SELECT ocena FROM egzaminy WHERE student guid = dbo.guid studenta@nr indeksu 3.... ang. multi statement table valued function jest to funkcja o wartościach tabelarycznych z tym, że zwracana tabela jest traktowana jak zmienna w ciele funkcji, na przykład poniższa funkcja wyświetla ranking w bieżącej rekrutacji do pozycji @top: CREATE FUNCTION ranking rekrutacji@top int S @ranking TABLE nazwanie zmiennej tabelarycznej i deklaracja tabeli pozycja int IDENTITY, deklaracja kolumny typu int, która uzupełniana jest kolejnymi wartościami od 1 w ogólności IDENTITY [początkowa wartość, inkrementacja] imie varchar 30, nazwisko varchar 30, punkty int INSERT @ranking SELECT TOP @top imie, nazwisko, punkty ORDER BY punkty DESC oraz przykład wywołania SELECT * FROM dbo.ranking rekrutacji10 Procedury 4. Procedury składowane są to prekompilowane wyrażenia języka SQL przechowywane na serwerze bazodanowym. Mogą być definiowane z parametrami wejściowymi i wyjściowymi, na przykład: CREATE PROCEDURE dodaj kandydata @imie varchar 30, @nazwisko varchar 30, @plec char 1,
@adres varchar 50, @punkty int INSERT rekrutacja VALUES @imie, @nazwisko, @plec, @adres, @punkty została zdefiniowana tylko z parametrami wejściowymi: @imie, @nazwisko, @plec, @adres, @punkty, a jej wywołanie może wyglądać następująco: EXECUTE rekrutacja Adam, Wawrzyniak, M, Poznan, 186 Poniżej przykład definicji procedury z obydwoma typami parametrów: CREATE PROCEDURE lista kandydatow @wzor imienia varchar 30, @wzor nazwiska varchar 30, @liczba int OUTPUT SET NOCOUNT ON wyłączenie wyświetlania liczby przetworzonych rekordów SELECT @liczba = COUNT * WHERE imie LIKE @wzor imienia AND nazwisko LIKE @wzor nazwiska SELECT * WHERE imie LIKE @wzor imienia AND nazwisko LIKE @wzor nazwiska W celu wykorzystania procedury lista kandydatów konieczna jest deklaracja zmiennej do której przekazana zostanie wartość zatem na przykład: DECLARE @liczba int EXEC lista kandydatow A%, W%, @liczba OUTPUT SELECT @liczba Domyślne wartości parametrów Zarówno w przypadku funkcji jak i procedur możliwe jest określenie domyślnych parametrów wywołania określając ich warotść, na przykład: CREATE PROCEDURE lista przedmiotow @wzor symbolu varchar 3 = %, @wzor nazwy varchar 30 = % SELECT symbol, nazwa, punkty
FROM przedmioty WHERE symbol LIKE @wzor symbolu AND nazwa LIKE @wzor nazwy Dla powyżej zdefiniowanej procedury możliwe są następujące sposoby wywołania: EXEC lista przedmiotow EXEC lista przedmiotow M% EXEC lista przedmiotow A%, n% ale jeżeli chcemy zmienić tylko drugi parametr należy odwołać się do niego po nazwie następująco: EXEC lista przedmiotow @wzor nazwy = n% czyli wywołanie: EXEC lista przedmiotow @wzor nazwy = n%, @wzor symbolu = A% ze zmienioną kolejnością parametrów, jest równoważne wywołaniu: EXEC lista przedmiotow A%, n% Triggery procedury wyzwalane 5. Triggery są to pezparametrowe procedury użytkownika wyzwalane automatycznie w wyniku wykonania jednego z poleceń: INSERT, DELETE, UPDATE, w trakcie FOR, po AFTER lub zamiast INSTEAD niego. Wykorzystują tabele systemowe inserted i deleted. Poniżej przykład triggera, który jest zdefiniowany na tabeli studenci i usuwaja wpisy z tabeli egzaminy dla studentów których chcemy usunąć z tabeli studenci: CREATE TRIGGER trigger usun wpisy ON studenci FOR DELETE IF EXISTS SELECT * FROM deleted DELETE egzaminy WHERE student guid IN SELECT guid FROM deleted Sprawdzanie istnienia obiektów w bazie danych Informacje o tabelach, widokach, procedurach i funkcjach zawartych w bazie danych znajdują się w tabelach: sysobjects, syscolumns. Informacje o użytkownikach bazy danych znajdują się z kolei w tabeli sysyusers. W celu sprawdzenia czy dany obiekt istnieje już w bazie danych można również skorzystać z funkcji OBJECT IDnazwa obiektu, typ obiektu na przykład w przypadku procedury, możemy ją usunąć bez błędu w następujący sposób: IF OBJECT ID lista przedmiotow, P IS NOT NULL DROP PROCEDURE lista przedmiotow Zadania
UWAGA: We wszystkich tworzonych procedurach i funkcjach należy dodać podstawową obsługę błędów. Zadanie 1. Napisać procedurę dodawania nowych przedmiotów. Zadanie 2. Napisać procedurę dodawania nowego studenta, przy czym konieczne jest wcześniejsze sprawdzenie, czy przeszedł on pomyślnie proces rekrutacji. Po dodaniu studenta, należy odpowiednie dane usunąć z tabeli rekrutacja. Pomocna może się również okazać funkcja wyznaczająca pierwszy wolny numer indeksu. Zadanie 3. Napisać procedurę dodawania nowego wpisu z egzaminu. W tym przypadku należy umożliwić egzaminatorowi posługiwanie się symbolem lub pełną nazwą przedmiotu podczas dodawania wpisu. Zadanie 4. Napisać trigger, który będzie przenosił usuwane dane z tabeli studenci do odpowiedniej tabeli danych historycznych, np. studenci historia.