Zaawansowane programowanie w T

advertisement
124
Bazy danych
Zaawansowane programowanie w TSQL
Bazy danych
125
Przegląd zagadnień
Skladnie T-SQL
Obsluga bledów
Podsumowanie
Laboratorium
Znajomość języka SQL, jakim posługuje się SZBD, jest bardzo waŜne,
jeśli chcesz wydajnie pracować z bazami danych. Przed przystąpieniem do tego
wykładu powinieneś znać podstawowe składnie SQL, takie jak SELECT czy
INSERT. Nie będziemy poświęcać im tu miejsca, a jedynie wplatać je w nieco
bardziej zaawansowane składnie.
126
Bazy danych
Składnie T-SQL
Instrukcje sterujace
Kursory
Skladnie specjalne
Transact-SQL (T-SQL) to implementacja języka SQL w systemie
Microsoft SQL Server. Język ten nieco róŜni się od standardu, ale większość
podstawowych składni jest taka, jak w standardzie.
Bazy danych
127
Instrukcje sterujące
Język T-SQL stale ewoluuje. Właściwie z języka zapytań stał się
językiem programowania baz danych. Programiści tworzący oprogramowanie
mogą się łatwo nauczyć języka T-SQL dzięki istniejącym analogiom
z tradycyjnymi
językami
programowania
strukturalnego.
Jedymi z częściej uŜywanych składni są instrukcje sterujące.
Instrukcja sterująca IF...ELSE daje moŜliwość warunkowego wykonywania
bloków kodu. W implementacji T-SQL wygląda ona jak poniŜej.
DECLARE @zmienna int
SET @zmienna = 100
IF @zmienna > 100
PRINT 'Zmienna jest większa niŜ 100'
ELSE
BEGIN
PRINT 'Zmienna jest mniejsza niŜ 100'
SET @zmienna = 0 -- zerowanie zmiennej
END
Zwróć uwagę, Ŝe rolę klamrowych nawiasów w T-SQL pełni blok
BEGIN...END. Jeśli blok po słowie IF lub ELSE składa się z wielu linii kodu,
musisz uŜyć właśnie składni BEGIN...END.
W T-SQL istnieje takŜe składnia CASE...END, która działa analogicznie do
składni IF, jednak działa w zapytaniach typu SELECT na poziomie
pojedynczego wiersza (umoŜliwia sprawdzanie wartości kolumny w kaŜdym
rekordzie i wplatanie instrukcji sterującej w zapytanie wyszukujące dane).
Kolejna składnia sterująca to pętla WHILE. W T-SQL wygląda to następująco.
DECLARE @zmienna int
SET @zmienna = 0
WHILE @zmienna < 10
BEGIN
PRINT 'Iteracja nr ' + CAST(@zmienna AS
varchar(2))
SET @zmienna = @zmienna + 1
END
NaleŜy pamiętać, Ŝe pętla WHILE moŜe być wykonywana w nieskończoność,
jeśli programista nie zapewni wyjścia z pętli.
Kursory
Kursor to zestawy rekordów umieszczane w pamięci i przechowujące
wyniki zapytań typu SELECT. UmoŜliwiają zaawansowane formatowanie
wyników wyszukiwania danych i przetwarzanie rekordów jeden po drugim (ale
128
Bazy danych
w ściśle określonej kolejności determinowanej przez wynik zapytania, które
stanowi definicję kursora).
DECLARE Employee_Cursor CURSOR FOR
SELECT LastName, FirstName
FROM Northwind.dbo.Employees
WHERE LastName like 'B%'
OPEN Employee_Cursor
FETCH NEXT FROM Employee_Cursor
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM Employee_Cursor
END
CLOSE Employee_Cursor
DEALLOCATE Employee_Cursor
Składnie specjalne
Nowoczesne języki SQL obfitują w specjalne składnie, które znacznie
rozszerzają funkcjonalność.
Przykładem takiej składni moŜe być PIVOT. Składnia ta umoŜliwia stworzenie
tabeli wynikowej z zapytania SELECT, w której na nagłówkach wierszy
i kolumn znajdują się wartości z tabel źródłowych.
USE AdventureWorks
GO
SELECT VendorID, [164] AS Emp1, [198] AS Emp2,
[223] AS Emp3, [231] AS Emp4, [233] AS Emp5
FROM
(SELECT PurchaseOrderID, EmployeeID, VendorID
FROM Purchasing.PurchaseOrderHeader) p
PIVOT
(
COUNT (PurchaseOrderID)
FOR EmployeeID IN
( [164], [198], [223], [231], [233] )
) AS pvt
ORDER BY VendorID;
-- Przykładowy wynik
VendorID
Emp4
1
4
2
5
3
4
4
4
5
5
Emp1
Emp5
4
Emp2
Emp3
3
5
4
4
1
5
5
4
3
5
4
4
2
5
5
5
1
5
5
Bazy danych
129
PowyŜszy wynik obrazuje moŜliwości tej składni umoŜliwiając zbudowanie
tabeli wyświetlającej ilość zamówień u wybranych producentów dokonanych
przez pięciu pracowników (kaŜdy pracownik o określonym EmployeeID).
130
Bazy danych
Obsługa błędów
Gdzie wykrywac bledy?
Metody wykrywania bledów
W trakcie działania kodu SQL mogą wydarzyć się nieprzewidziane
błędy. Błędy te mogą wynikać z róŜnych przyczyn. Mogą to być błędy
wynikające z narzuconych w bazie danych ograniczeń lub na przykład
błędy wynikające z prób wykonania niedozwolonych operacji. Wykrycie
tych błędów i odpowiednia na nie reakcja to zadanie dla programisty
baz danych.
Bazy danych
131
Gdzie wykrywać błędy?
Błędy wykrywamy najczęściej w:
•
•
•
•
transakcjach - po wykryciu błędu wycofujemy transakcję,
procedurach składowanych - wykrywamy błędy powstałe głównie
w wyniku niepoprawnych wartości parametrów przez uŜytkownika,
triggerach - podobnie jak w transakcjach, po napotkaniu błędu
wycofywana jest transakcja wywołująca trigger,
blokach kodu SQL - wszelkie rozbudowane bloki kodu wymagają
wykrywania błędów.
Metody wykrywania błędów
Jak moŜna wykrywać błędy? Metod na to jest wiele. Po pierwsze
moŜna zastosować składnie sterujące, np. IF...ELSE, do sprawdzania wartości
zmiennych jeszcze przed wystąpnieniem błędu. Druga metoda to wykorzystanie
istniejących w SZBD funkcje wykrywające błędy. W systemie Microsoft SQL
Server taką funkcją jest @@ERROR, która zwraca numer błędu napotkanego w
ostatnio napotkanego błędu w bieŜącej sesji.
Aktualnie istnieją takŜe inne - moŜna by rzec lepsze metody wykrywania
i obsługi błędów. Chodzi o strukturalną obsługę wyjątków. Jako wyjątek
rozumiemy błąd, który wymaga obsługi. PoniŜszy fragment kodu obrazuje
przykładową obsługę wyjątków przy pomocy składni TRY...CATCH (TRY próbuj, CATCH - przechwyć i obsłuŜ).
BEGIN TRY
-- generujemy błąd
SELECT 1/0;
END TRY
BEGIN CATCH
-- obsługujemy błąd
RAISERROR('Nie dzielimy przez zero',16,1)
END CATCH;
132
Bazy danych
Podsumowanie
Skladnie T-SQL
Obsluga bledów
Programowanie w języku zapytań to waŜna umiejętność. Powinni ją
opanować zarówno programiści, jak i administratorzy. RóŜne języki SQL
oferują róŜne składnie. Jednak reguły, jakimi powinien kierować się tworzący
kod, są te same nizaleŜnie od SZBD. Bardzo często opanowanie w
zaawansowanym stopniu składni jednego języka pozwala w przyszłości na
łatwe opanowanie innego.
Bazy danych
133
Laboratorium
KaŜdy producent SZBD w swoich systemach oferuje składnie, które
rozszerzają standard ANSI SQL. W tym ćwiczeniu poznasz trzy składnie, które
słuŜą do zaawansowanego wybierania danych i formatowania wyników zapytań
SELECT.
Obsługa błędów jest waŜnym aspektem programowania w kaŜdym języku takŜe w języku T-SQL. System Microsoft SQL Server 2005 oferuje strukturalną
obsługę wyjątków (błędów). W tym ćwiczeniu zobaczysz w działaniu składnię
TRY...CATCH, która słuŜy do przechwytywania i obsługi błędów.
134
Bazy danych
Krok 1 - Instrukcja sterująca CASE
►
►
►
►
►
►
►
Zaloguj się do maszyny wirtualnej ZBD jako uŜytkownik
Administrator z hasłem P@ssw0rd.
Kliknij Start. Z grupy programów Microsoft SQL Server 2005
uruchom SQL Server Management Studio.
W oknie logowania kliknij Connect.
Kliknij w menu głównym programu Management Studio na File.
Kliknij Open - File.
Odszukaj plik C:\Labs\Lab05\Queries.sql i kliknij Open.
Zaznacz kod, który wykonuje zapytanie SELECT z uŜyciem składni
CASE (patrz kod poniŜej).
USE AdventureWorks
GO
SELECT
C.LastName,
C.FirstName,
CASE
WHEN E.Gender = 'M' THEN 'male'
ELSE 'female'
END AS Gender
FROM HumanResources.Employee E
INNER JOIN Person.Contact C
ON E.ContactID = C.ContactID
►
Wciśnij F5, aby uruchomić zaznaczony fragment kodu.
PowyŜsza składnia wybiera dane z tabel Person.Contact (nazwisko i imię
pracownika) oraz HumanResources.Employee (płeć - jeśli w kolumnie
Gender składnia CASE napotka wartość 'M', to zamienia ją w zestawie
wynikowym na 'male' - męŜczyzna, jeśli napotka inną wartość, wypisze 'female'
- kobieta).
Składnia CASE jest instrukcją sterującą działającą na poziomie
pojedynczego wiersza w zapytaniach SELECT. MoŜna jej uŜyć do
zaawansowanego formatowania wyników zapytań SELECT.
Krok 2 - Instrukcja PIVOT
►
Zaznacz kod, który wykonuje zapytanie SELECT z opcją PIVOT
(patrz kod poniŜej).
Bazy danych
135
SELECT
VendorID
, [164] AS Emp1
, [198] AS Emp2
FROM
(SELECT
PurchaseOrderID,
EmployeeID,
VendorID
FROM Purchasing.PurchaseOrderHeader) p
PIVOT
(
COUNT (PurchaseOrderID)
FOR EmployeeID IN
( [164], [198])
) AS pvt
WHERE VendorID < 6
ORDER BY VendorID
►
Wciśnij F5, aby uruchomić zaznaczony fragment kodu.
PowyŜsza składnia wybiera z tabeli Purchasing.PurchaseOrderHeader
informacje: ile zamówień na produkty producentów identyfikowanych przez
kolumnę VendorID (ograniczono VendorID do wartości mniejszych od 6)
zrealizowali pracownicy identyfikowani przez wartości 164 i 198 w kolumnie
EmployeeID.
Składnia PIVOT to odpowiednik kwerendy krzyŜowej z programu
Microsoft Access. Dokonuje ona zamiany - wartości z rekordów stają
się nagłówkami kolumn i wierszy, natomiast w wierszach pojawiają
się agregacje - w powyŜszym przykładzie funkcja agregująca COUNT
liczy ilość zrealizowanych przez danego pracownika zamówień.
W Books Online znajdziesz takŜe opis składni UNPIVOT, która działa
odwrotnie - pozwala przejść od zagregowanych wartości do
pojedynczych rekordów (ale oczywiście wyniki nie będą takie same,
jak przed wykonaniem składni PIVOT).
Krok 3 - Stronicowane danych z uŜyciem funkcji rankingu
►
Zaznacz kod, który wykonuje zapytanie SELECT z uŜyciem funkcji
rankingu.
SELECT T.Name
FROM (
SELECT
Name,
ROW_NUMBER()
OVER(ORDER
DepartmentID) AS Number
FROM HumanResources.Department
) AS T
WHERE T.Number BETWEEN 3 AND 6
►
Wciśnij F5, aby uruchomić zaznaczony fragment kodu.
BY
136
Bazy danych
PowyŜsze zapytanie stanowi rozwiązanie problemu stronicowania danych.
W tym wypadku wynikiem jest lista nazw działów (departamentów) z tabeli
HumanResources.Department, przy czym wyświetlone zostają działy od
trzeciego do szóstego (cztery działy - trzeci, czwarty, piąty i szósty) biorąc pod
uwagę sortowanie według kolumny DepartmentID.
Składnia zadziała tak samo nawet, gdy numeracja w tej kolumnie nie będzie
ciągła. Składnia wykorzystuje podzapytanie, w którym dla kaŜdego wiersza
generowana jest liczba porządkowa za pomocą funkcji ROW_NUMBER
(funkcja ta musi przed generowaniem wartości określić kryterium sortowania,
stąd składnia ORDER BY).
Funkcje rankingu (nazywane tak ze względu na zastosowanie)
w systemie Microsoft SQL Server 2005: ROW_NUMBER, RANK,
DENSE_RANK, NTILE. Ich opis znajdziesz w Books Online.
Bazy danych
137
Obsługa błędów
Krok 1 - Tworzenie tabeli archiwizującej informacje o błędach
►
►
►
►
►
►
►
Zaloguj się do maszyny wirtualnej ZBD jako uŜytkownik
Administrator z hasłem P@ssw0rd.
Kliknij Start. Z grupy programów Microsoft SQL Server 2005
uruchom SQL Server Management Studio.
W oknie logowania kliknij Connect.
Kliknij w menu głównym programu Management Studio na File.
Kliknij Open - File.
Odszukaj plik C:\Labs\Lab05\Errors.sql i kliknij Open.
Zaznacz kod, który tworzy tabelę, w której będą zapisywane
informacje o błędach (patrz kod poniŜej).
USE AdventureWorks
GO
CREATE TABLE ErrorLog
(
ErrorID int IDENTITY(1,1) PRIMARY KEY,
ErrorNumber int NOT NULL,
ErrorMessage nvarchar(200) NOT NULL,
ErrorDate datetime DEFAULT GETDATE()
)
GO
►
Wciśnij F5, aby uruchomić zaznaczony fragment kodu.
PowyŜszy kod tworzy tabelę ErrorLog, która będzie zawierała informacje o
występujących błędach. W kolumnie ErrorNumber zapisany zostanie numer
błędu, w kolumnie ErrorMessage - komunikat błędu, zaś w kolumnie
ErrorDate - data i godzina wystąpienia błędu (wartość domyślna - bieŜąca data
i czas - jest generowana przy pomocy funkcji systemowej GETDATE).
Krok 2 - Przechwytywanie błędów
►
Zaznacz kod, który implementuje obsługę błędów (patrz kod poniŜej).
BEGIN TRY
SELECT 1/0
END TRY
BEGIN CATCH
INSERT ErrorLog(ErrorNumber, ErrorMessage)
SELECT ERROR_NUMBER(), ERROR_MESSAGE()
END CATCH
►
Wciśnij F5, aby uruchomić zaznaczony fragment kodu.
PowyŜszy kod ilustruje działanie składni TRY...CATCH. W bloku TRY
umieszczamy składnie, które mogą spowodować wystąpienie błędów, zaś
138
Bazy danych
blok CATCH zapisuje obsługę błędów (w tym przypadku zapisanie
informacji o błędzie do tabeli ErrorLog). Informacje na temat błędu są
uzyskiwane przy uŜyciu funkcji ERROR_NUMBER (numer błędu)
i ERROR_MESSAGE (komunikat błędu).
Microsoft SQL Server 2005 dysponuje pokaźną listą funkcji
systemowych do uzyskiwania informacji na temat występujących
błędów. Poszukaj w Books Online opisów funkcji: ERROR_LINE,
ERROR_SEVERITY i ERROR_PROCEDURE.
Krok 3 - Przeglądanie informacji o wystąpieniu błędów
►
Zaznacz kod, który wyświetla zawartość tabeli ErrorLog (patrz kod
poniŜej).
SELECT * FROM ErrorLog
►
Wciśnij F5, aby uruchomić zaznaczony fragment kodu.
Przykładowy wynik działania powyŜszego zapytania:
ErrorID ErrorNumber ErrorMessage
ErrorDate
----------- ----------- --------------------------------- ----------------------1
8134
Divide by zero error encountered. 2006-07-02 11:03:56.427
Zapytanie zwraca zawartość tabeli ErrorLog - czyli informacje o dotychczas
zapisanych błędach.
Download