Bazy danych 2 Anna Fiedorowicz Wydział Matematyki, Informatyki i Ekonometrii 24.02.2016
Literatura 1. S. Urman, R. Hardman, M. McLaughlin, Oracle Database 10g. Programowanie w języku PL/SQL, Helion, 2007. 2. R. Coburn: SQL dla każdego, Helion, 2001. 3. A. Klusiewicz, SQL i PL/SQL podstawy, 2013 (http://jsystems.pl/storage/sqlplsql1.pdf). 4. M. McLaughlin, Oracle Database 11g PL/SQL Programming, McGraw-Hill, 2008. 5. Dokumentacja dostępna na stronie Oracle. 6. W.J. Gilmore, B. Bryla, Beginning PHP and Oracle: From Novice to Professional, APress 2007. 7. Y. Vasiliev, PHP i Oracle. Tworzenie aplikacji webowych: od przetwarzania danych po Ajaksa, Helion 2009. 8. T. Converse, J. Park, C. Morgan, PHP5 i MySQL. Biblia, Helion, 2005.
Baza danych: zbiór danych zapisanych w ściśle określony sposób, w strukturach odpowiadających przyjętemu modelowi danych. W relacyjnej bazie danych, podstawową strukturą jest tabela rekordów. W uproszczeniu, baza danych obejmuje dane oraz wyspecjalizowany program komputerowy służący do gromadzenia i przetwarzania danych. W modelu relacyjnym, zestaw programów służących do korzystania z bazy jest nazywany RDBMS (Relational Database Management System - system zarządzania relacyjną bazą danych). SQL - strukturalny język zapytań, jest uniwersalnym interfejsem umożliwiającym tworzenie i utrzymanie struktury bazy danych, dostęp do danych oraz zapewnienie bezpieczeństwa danym, poprzez system uprawnień użytkowników. SQL jest tzw językiem deklaratywnym, decyzję o sposobie pobrania i przechowywania danych pozostawia się systemowi zarządzania bazą danych. Systemy RDBMS, w których podstawowym językiem jest SQL, to dla przykładu Oracle, MS SQL Server, IBM DB2, Firebird, MySQL, PostgreSQL,...
Podział języka SQL: DML (Data Manipulation Language) - umożliwia wybieranie, dodawanie, modyfikację, usuwanie danych w bazie (SELECT, INSERT, UPDATE, DELETE). DDL (Data Definition Language) - stworzenie i utrzymanie struktury bazy (CREATE, ALTER, DROP). DCL (Data Control Language) - zarządzanie uprawnieniami w bazie (GRANT, REVOKE). (Niektóre) standardy języka SQL: Rok Nazwa Uwagi 1986 SQL-86 pierwszy standard ANSI 1992 SQL-92 SQL2, uściślenie standardu 2003 SQL-2003 wprowadzenie m.in. obsługi XML-a (SQL/XML) 2011 SQL:2011 aktualny standard ANSI.
Serwer bazy danych Oracle Serwer bazy danych Oracle obejmuje szereg plików, procesów i struktur pamięci, umożliwiających przede wszystkim trwałe przechowywanie danych i wykonywanie instrukcji SQL. Oprócz tego niektóre ze składowych służą do poprawienia efektywności korzystania z bazy danych, do zapewnienia odtwarzalności bazy danych w przypadku awarii oprogramowania lub sprzętu, do wykonywania innych zadań potrzebnych przy eksploatacji bazy danych. Baza danych Oracle oprócz tego, że wykorzystuje język SQL, posiada też rozszerzenie proceduralne języka SQL wbudowany wewnętrzny język tworzenia procedur składowanych PL/SQL.
Serwer bazy danych Oracle Ogólnie rzecz biorąc, serwer bazy danych Oracle składa się z dwóch części: bazy danych: zbioru plików znajdujących się na dysku, zawierających dane; instancji: procesy serwera, wraz z przydzielonymi strukturami pamięci i procesami tła, umożliwiające dostęp do danych.
Baza danych Oracle: składa się z plików systemu operacyjnego, nazywanych plikami bazodanowymi, które są miejscem przechowywania danych. Zwykle mamy do czynienia z sytuacją, w której tylko jedna instancja Oracle ma dostęp do bazy danych.
Instancja: każda baza danych Oracle database jest powiązana z odpowiednią instancja. W momencie uruchomienia serwera bazy danych, następuje alokacja w pamięci operacyjnej obszaru pamięci, który jest współdzielony (dostępny dla wszystkich użytkowników bazy danych), nazywanego System Global Area (SGA) (tzw Globalny Obszar Wpółdzielony) oraz uruchomienie przez Oracle procesów serwera i procesów tła. Instancja Oracle to właśnie połączenie obszaru pamięci SGA oraz procesów tła.
Użytkownik nie pobiera danych bezpośrednio z pliku bazy danych. Polecenie SQL zadane przez użytkownika trafia najpierw do odpowiedniego bufora w strukturze SGA (za pośrednictwem odpowiedniego procesu serwera), następnie jest przetwarzane i analizowane, potem pobierane są dane z plików danych do obszaru SGA. Dopiero stąd informacja jest przekazywana do użytkownika. Program Global Area (PGA): obszar pamięci przydzielony (na wyłączność) dla każdego procesu serwera i procesu tła. Każdy proces ma przydzielony własny obszar PGA.
Baza danych Oracle funkcjonuje w architekturze klient-serwer, zapewniając jednoczesny dostęp do danych dla wielu użytkowników, realizowany za pomocą mechanizmu transakcji. Moment podłączenia się użytkownika do bazy jest równoznaczny z otwarciem nowej sesji dla danego użytkownika. W obrębie sesji, użytkownik może realizować jedną lub więcej transakcji, jedną po drugiej (transakcja jest jednostką interakcji użytkownika z bazą danych i składa się z pojedynczych operacji realizowanych w bazie danych (np. przez polecenia SQL). Równolegle, jeden użytkownik może mieć w danym momencie otwartych więcej niż jedną sesję.
Użytkownicy i schematy Użytkownik tworząc obiekt, np. tabelę, staje się jego właścicielem. Obiekty te są tworzone w schemacie użytkownika (logicznej przestrzeni bazy danych). Schemat użytkownika jest tworzony automatycznie podczas definiowania użytkownika i posiada unikalną nazwę (identyczną z nazwą użytkownika). Nazwa schematu jest wykorzystywana, aby wskazać obiekty bazy danych stanowiące własność danego użytkownika (w różnych schematach mogą istnieć obiekty, np. tabele, o tych samych nazwach). Odwołanie do obiektu znajdującego się w schemacie innego użytkownika realizowane jest następująco: nazwa_użytkownika.nazwa_obiektu
Użytkownik HR i jego schemat Oracle posiada przedefiniowanego użytkownika HR, który służy do celów testowych. W schemacie HR mamy kilka tabel z przykładowymi danymi: Domyślnie, konto HR jest zablokowane. Aby je odblokować, należy wydać instrukcję (z poziomu administratora czyli SYSTEM): ALTER USER HR IDENTIFIED BY password ACCOUNT UNLOCK;
Obiekty bazy danych W Oracle istnieją obiekty służące do przechowywania danych, jak i wspomagające zarządzanie tymi danymi: tabele: przechowywanie danych; indeksy: struktury danych zwiększające prędkość wykonywania operacji na tabelach; tabele tymczasowe: przechowują dane potrzebne w czasie jednej sesji (transakcji), wspomagają zarządzanie nimi; widoki: logiczna struktura, definiowana przez zapytanie SQL; sekwencje: generują kolejne liczby (wykorzystywane do tworzenia wartości kluczy); wyzwalacze: procedury wykonywane automatycznie, reagujące na pewne zdarzenia w bazie danych; procedury, pakiety, funkcje,...
Instrukcja SELECT Instrukcja select w najprostszej postaci pobiera wszystkie dane z wybranej tabeli. select * from department; SELECT wybranych kolumn Po wyrażeniu SELECT określamy nazwy kolumn, które mają zostać wybrane do wyświetlenia. Można wybierać stałe lub wyrażenia. Aliasy kolumn Czasem zdarza się że nazwy kolumn są mało zrozumiałe lub przyjazne dla użytkownika. W takim wypadku w wyniku zapytania możemy zamienić je na własne aliasy. select full_name as nazwisko i imie from employees; Klauzula DISTINCT Słowo kluczowe distinct służy do wyświetlenia wartości lub szeregu wartości bez powtórzeń. Stosuje się je w przypadku gdy chcemy wiedzieć jakie w ogóle wartości występują w danej kolumnie a nie interesuje nas ich częstotliwość występowania.
Sortowanie sortowanie klauzula ORDER BY Możemy wyświetlić dane posortowane wg wybranej kolumny. W tym celu dodajemy do zapytania klauzulę order by określającą kolumnę wg której dane mają być sortowane. ASC - sortowanie rosnące, DESC - malejące. Jeśli nie istnieje potrzeba stosowania sortowania, nie powinniśmy z niej korzystać ponieważ powoduje dodatkowe niepotrzebne obciążenie serwera bazy danych. Klauzule NULLS FIRST I NULLS LAST Aby zmienić sposób traktowania wartości pustych przy sortowaniu, musimy po nazwie sortowanej kolumny dodać klauzulę NULLS FIRST lub NULLS LAST.
Filtrowanie wierszy Operatory Budując zapytania do bazy danych Oracle możemy korzystać z operatorów które pozwalają porównywać, wykonywać operacje, łączenia i porównania wartości. Operatory arytmetyczne Pozwalają wykonywać operacje matematyczne na wartościach. Należą do nich: +,,, / Operator konkatenacji Operator ten służy do łączenia dwu wartości tekstowych. Operatory porównań >, >=, =, <, <=, <>,! = Operator zakresu x [NOT] BETWEEN y AND z Operator ten sprawdza, czy wartość x mieści [nie mieści] się w przedziale domkniętym <y,z> Operator przynależności do listy x [NOT] IN (x1, x2,..., xn) Operator ten sprawdza, czy wartość x znajduje [nie znajduje ] się na liście wartości x1, x2,..., xn.
Operator wzorca x [NOT] LIKE y Operator ten sprawdza, czy wartość napisu x przystaje [nie przystaje] do maski y. Podczas definiowania maski możemy korzystać ze znaków specjalnych: % zastępuje dowolną ilość dowolnych znaków, natomiast _ zastępuje dokładnie jeden dowolny znak. Operator testowania wartości pustych x IS [NOT] NULL Operator ten sprawdza, czy x zawiera [nie zawiera] wartości NULL. Operatory logiczne NOT, AND, OR Operatory te służą do nadawania więcej niż jednego warunku w zapytaniu.
Uwaga: "Arytmetyka wartości pustych" Każde wyrażenie arytmetyczne zawierające choć jeden składnik lub czynnik z wartością pustą daje pusty wynik. TRUE AND NULL => NULL FALSE AND NULL => FALSE TRUE OR NULL => TRUE FALSE OR NULL => NULL
Funkcje jednowierszowe. Funkcje znakowe Upper: Zamienia wszystkie litery na wielkie. Lower: Zamienia wszystkie litery na małe. Initcap: Zwiększa pierwsze litery wszystkich wyrazów. np. select initcap( ola, ala ) from dual; Uwaga: dual: specjalna tablica w Oracle, z jednym wierszem i jedna kolumna, używamy jej w przypadku pisania zapytań, które nie odwołuja się do danych z żadnej tablicy (widoku). Lpad(text,n,znak) Funkcja uzupełniająca z lewej strony znakami podanymi jako trzeci argument w taki sposób by wynik osiągnął długość podaną jako drugi parametr. Jeśli wynik jest dłuższy niż zadeklarowana długość, zostaje ucięty z prawej strony. np. select Lpad(job_code,5, x ) from employees; Rpad(text,n,znak) Funkcja uzupełniająca z prawej strony wynik znakami podanymi jako trzeci argument w taki sposób, by wynik osiągnął długość podaną jako drugi parametr. Jeśli wynik jest dłuższy niż zadeklarowana długość, zostaje ucięty z prawej strony.
Funkcje znakowe RTrim(text,text2), LTrim(text,text2) Funkcje te usuwają z prawej lub lewej strony napisu text znaki zawarte w text2. Jeśli nie podamy wartości text2, usunięte zostaną spacje (i w praktyce do tego tych funkcji używa się najczęściej). Replace (text, text1 [,text2]) Funkcja zamienia wszystkie wystąpienia ciągu text1 w ciągu text na text2. W przypadku braku ciągu text2 z ciągu text usuwane są wszystkie wystąpienia ciągu text1. translate (text, text1,text2) Funkcja działa podobnie jak funkcja replace, tylko że zamienia w ciagu text wszystkie wystąpienia pojedynczych liter z ciągu text1 na odpowiednie litery z ciągu text2. np. select translate(last_name, ąćęłńóśźż, acelnoszz ) from employees; length (text) Zwraca długość ciągu text, jeśli text ma wartość NULL funkcja zwraca NULL. np. select length(last_name) from employees;
Funkcje znakowe Substr(text, m [,n]): Funkcja wycina z ciągu text n znaków począwszy od pozycji m. Jeżeli n nie jest podane, to wycina wszystkie znaki od pozycji m do końca ciągu text. Jeżeli m jest ujemne, to znaki są odliczane od końca ciągu text. Przykłady: (1) Wyświetlenie pierwszych czterech znaków nazwiska. select substr(last_name,1,4) from employees; (2) Funkcja substr z użyciem dwóch parametrów zwróci ciąg znaków zaczynając od drugiego znaku, do końca (czyli usunie pierwszy znak). select substr(last_name,2) from employees; (3) Substr z m ujemnym. Parametr n najbezpieczniej w takiej sytuacji jest podać większy niż długość najdłuższego wyrazu (jeżeli m jest większa niż długość, zwraca null). select substr(last_name, -2, 20) from employees; //ostatnie dwa znaki z nazwiska
Funkcje znakowe to_char Funkcja ta ma kilka zastosowań. Jedno z nich odnosi się do zamiany liczb na postać znakową. Inne formy to_char zostaną omówione później. to_char (liczba [,wzorzec]) zamienia liczbę na postać znakową według podanego wzorca. np. Chcemy wyświetlić roczne wynagrodzenie pracowników podzielone przez 12, otrzymaliśmy mało czytelny wynik: select last_name, salary/12 as "miesięczne zarobki" from employees; Stosując funkcję to_char możemy zamienić go na odpowiadający nam format: select last_name, to_char((salary/12), 9999.99 ) as "miesięczne zarobki" from employees;
Wzorzec w funkcji to_char jest napisem, który może zawierać następujące elementy: Element Opis Przykład Wynik 9 Cyfra (liczba dziewiątek określa szerokość pola) 999999 1234 0 Wyświetl wiodące zera 099999 001234 $ Ruchomy znak dolara $999999 $1234 L Ruchomy znak lokalnej waluty L999999 zł1234. Kropka dziesiętna na wskazanej pozycji 9999.99 1234.00, Przecinek na wskazanej pozycji 999,999 1,234 MI Znak minus z prawej strony (przy wartościach ujemnych) 9999MI 1234- PR Liczby ujemne w nawiasach 9999PR <1234> EEEE Notacja inżynierska (w formacie muszą być cztery E) 9.9EEEE 1.2E+03 V Pomnóż przez 10 n razy (n to liczba dziewiątek po V) 9999V99 123400
Funkcje znakowe to_number (text [,wzorzec]) Funkcja zamienia ciąg znaków na liczbę według wzorca zbudowanego podobnie dla funkcji to_char (jak powyżej). Funkcja ta jest przydatna, gdy w naszej bazie liczby przechowywane są w postaci tekstowej. SELECT To_Number(postal_code, 99999) FROM locations WHERE country_id= US ; decode Select decode (nazwa_kolumny,wartość, zamiennik, wartość2, zamiennik2,wartość domyślna) [alias] from nazwa_tabeli; Funkcja testuje wartość w podanej kolumnie i w zależności od wartości mieszczącej się w pierwszym argumencie zwraca wartość podaną w drugim argumencie. Jeśli nie znajdzie odpowiedniej wartości w podanych warunkach, wyświetli wartość domyślną podaną jaką ostatni warunek.
Funkcje numeryczne ROUND (x,[,y]) Zaokrągla x z dokładnością do y miejsc po przecinku. Jeśli y nie zostało podane, jest domyślnie ustawiane jako 0. ( select round(15.75, 1) from dual; -> 15.8 TRUNC (x,[,y]) Ucina x z dokładnością do y miejsc po przecinku. Jeśli y nie zostało podane, jest domyślnie ustawiane jako 0. Uwaga! round, trunc z ujemnym parametrem y zaokrągla (obcina) liczbę z lewej strony przecinka, czyli do dzisiątek, setek, tysięcy, itp.) POWER (x,y) > x y. SQRT(x) > x. SIGN(x) Zwraca wartość 0, 1 lub -1 w zależności od znaku liczby x. ABS(x) Wartość bezwzględna liczby x. MOD(x,y) Reszta z dzielenia x przez y. Jeśli y = 0 zwraca x. SIN(x), COS(x), TAN(x) Funkcje trygonometryczne, x jest podawane w radianach.
Daty Aktualna data jest przechowywana w zmiennej systemowej SYSDATE. select sysdate from dual; Daty można również od siebie odjać. Wynikiem będzie liczba dni pomiędzy datami. Do daty możemy również dodać liczbę całkowita i jako wynik uzyskamy datę za podaną ilość dni. MONTHS_BETWEEN(date1,date2) Zwraca ilość miesięcy pomiędzy datami. ADD_MONTHS(date,n) Dodaje do podanej daty n miesięcy, np. SELECT Add_Months(SYSDATE,3) FROM dual; LAST_DAY(date) Zwraca datę ostatniego dnia miesiąca zawierającego podaną datę.
Daty ROUND(date[,p]) Funkcja zaokrągla datę do północy, jeśli jest przed południem lub do północy dnia następnego, jeśli jest po południu. W przypadku podania dodatkowego parametru p zaokrągla datę do pełnego miesiąca (p= month ) lub roku (p= year ), np. zaokrąglenie do pełnego miesiąca: SELECT Round(SYSDATE, month ) FROM dual; TRUNC(date[,p]) Ucina daty. Parametr p działa analogicznie, jak dla round.
Daty to_date (text [,text1]) Funkcja zamienia ciąg znaków text na datę według wzorca zawartego w text1. Wzorzec pozwala poprawnie zinterpretować znaki zawarte w ciągu text. Używamy najczęściej przy wstawianiu dat do bazy. SELECT To_date( 20010509, yyyymmdd ) FROM dual; SELECT To_date( 2001-05-09, yyyy-mm-dd ) FROM dual; SELECT To_date( 2001 V 09 18:34, yyyy rm dd hh24:mi ) FROM dual; SELECT To_date( January 15, 1989, Month dd, YYYY, NLS_DATE_LANGUAGE = English ) FROM dual;
Formaty dla funkcji to_date: Parametr Opis Komentarz YYYY Czterocyfrowy rok YYY YY Y Ostatnie 3, 2 lub 1 cyfra roku. RRRR Przyjmuje dwucyfrowy rok, a zwraca w czterocyfrowej notacji. Warto ci z zakresu 0-49 zwróci jako lata 20 21 wieku. Warto ci z zakresu 50-99 zwróci jako lata 19 20 wieku. MM Miesi c (01-12). MON Trzyliterowa nazwa miesi ca. sty, lut, mar,... MONTH Nazwa miesi ca. stycze, luty, itp. RM Rok Miesiąc w notacji w notacji rzymskiej. rzymskiej. I-XII DD Dzie w miesi cu (1-31). DDD Dzie w roku (1-366). HH Godzina w dobie (1-12). HH24 Godzina w dobie (0-23). MI Minuta (0-59). SS Sekunda (0-59).
Funkcja to_char dla dat to_char (date [,text1]) Zamienia datę na postać znakową według wzorca zawartego w ciągu text1. Funkcję to_char można wykorzystać do przetwarzania dat wg wzorca. Od omawianej wcześniej odmiany to_char różni się rodzajem parametrów. Tutaj przyjmuje daty, wcześniej były to liczby. Dla funkcji to_char stosuje się te same wzorce dat jak dla funkcji to_date. Można też użyć poniższych. Parametr Opis YEAR Rok, słownie Q Kwartał roku (1, 2, 3, 4). WW Tydzień w roku. W Tydzień w miesiącu. D Dzień w tygodniu (1-7). DAY Nazwa dnia tygodnia.
Funkcja EXTRACT EXTRACT(part from datetime) zwraca wartość odpowiedniego pola z daty lub godziny. Funkcji możemy użyć, aby wybrać rok (YEAR), miesiąc (MONTH) lub dzień (DAY) z daty, albo godzinę (HOUR), minutę (MINUTE) lub sekundę (SECOND) z pola typu timestamp. Wybierzmy wszystkich pracowników zatrudnionych od 2005 roku: SELECT * FROM employees WHERE EXTRACT(YEAR FROM hire_date)>=2005; Poniższa instrukcja wybiera godzinę, minutę i sekundę z daty i godziny systemowej: SELECT EXTRACT(HOUR FROM SYSTIMESTAMP), EXTRACT(MINUTE FROM SYSTIMESTAMP), EXTRACT(SECOND FROM SYSTIMESTAMP) FROM DUAL;
Funkcje NVL, NULLIF, COALESCE Funkcja NVL(wyrażenie, wartość zastępcza) - jeżeli wartością wyrażenia jest NULL, zwraca wartość zastępczą. SELECT city, nvl(state_province, brak ) from locations;
Funkcje NVL, NULLIF, COALESCE Funkcja NVL(wyrażenie, wartość zastępcza) - jeżeli wartością wyrażenia jest NULL, zwraca wartość zastępczą. SELECT city, nvl(state_province, brak ) from locations; COALESCE(wartość1, wartość2, wartość3,...) - służy do wyświetlania z ciągu wartości pierwszej, która nie jest NULL. Należy zachować zgodność typów wartości na liście. SELECT city, COALESCE(state,shortcut, brak ) FROM locations;
Funkcje NVL, NULLIF, COALESCE Funkcja NVL(wyrażenie, wartość zastępcza) - jeżeli wartością wyrażenia jest NULL, zwraca wartość zastępczą. SELECT city, nvl(state_province, brak ) from locations; COALESCE(wartość1, wartość2, wartość3,...) - służy do wyświetlania z ciągu wartości pierwszej, która nie jest NULL. Należy zachować zgodność typów wartości na liście. SELECT city, COALESCE(state,shortcut, brak ) FROM locations; Funkcja NULLIF(wartość1, wartość2) - służy do sprawdzenia czy dwie wartości są równe. Jeśli wartość1=wartość2, to zwraca NULL, przeciwnie - zwraca pierwszą z podanych wartości. SELECT e.last_name, e.job_id, NULLIF(j.job_id, e.job_id) AS "old job id" FROM employees e, job_history j WHERE e.employee_id = j.employee_id;
Wyrażenie CASE Wyrażenie CASE można stosować w dwojaki sposób: CASE wartość WHEN wartość1 THEN wyrażenie1 WHEN wartość2 THEN wyrażenie2... WHEN wartość_n THEN wyrażenie_n ELSE wartość domyślna END Powyższa forma odpowiada zaprezentowanej wcześniej funkcji DECODE (klauzula ELSE... nie jest wymagana).
Wyrażenie CASE Wyrażenie CASE można stosować w dwojaki sposób: CASE wartość WHEN wartość1 THEN wyrażenie1 WHEN wartość2 THEN wyrażenie2... WHEN wartość_n THEN wyrażenie_n ELSE wartość domyślna END Przykład: SELECT last_name, salary, CASE job_id WHEN AD_PRESS THEN salary*0.2 WHEN AD_VP THEN salary*0.15 WHEN FI_MGR THEN salary *0.1 ELSE 0 END AS premia from employees;
Wyrażenie CASE W drugiej formie można stosować CASE jako instrukcję warunkową: CASE WHEN warunek1 THEN wyrażenie1 WHEN warunek2 THEN wyrażenie2... ELSE wyrażenie_else END Powyższa konstrukcja zwróci wartość wyrażenia1, jeżeli warunek1 będzie prawdziwy, wyrażenia2, jeżeli warunek2 będzie spełniony, itd., jeżeli żaden warunek nie będzie spełniony, zwróci wartość wyrażenia_else. Klauzula ELSE nie jest wymagana. Warunki są sprawdzane zgodnie z ich kolejnością, tzn. wartość zostanie zwrócona dla pierwszego prawdziwego warunku, a dalsze warunki nie są wtedy sprawdzane.
Wyrażenie CASE SELECT last_name, department_id, CASE WHEN department_id IN (60, 210, 230) THEN IT WHEN department_id =20 THEN Marketing WHEN department_id =30 THEN Sprzedaż ELSE inni END AS "dział" FROM employees ORDER BY 2;
Wyrażenie CASE Przykład niewłaściwej kolejności warunków w CASE: SELECT last_name, salary, CASE WHEN salary >5000 THEN ok WHEN salary > 10000 THEN super ELSE kiepsko END FROM employees; Drugi warunek salary > 10000 nigdy nie będzie sprawdzany!
Wyrażenie CASE Przykład niewłaściwej kolejności warunków w CASE: SELECT last_name, salary, CASE WHEN salary >5000 THEN ok WHEN salary > 10000 THEN super ELSE kiepsko END FROM employees; Drugi warunek salary > 10000 nigdy nie będzie sprawdzany! Poprawnie powinno być: SELECT last_name, salary, CASE WHEN salary >10000 THEN super WHEN salary > 5000 THEN ok ELSE kiepsko END FROM employees;