Oskar Skibski, grupa nr 4, sala 2043

Bazy danych 2015/16

Laboratorium 1 (05.10.2015) - SQL / PODSTAWY

Na dzisiejszych zajęciach nauczymy się korzystać z SQL*Plusa oraz poznamy podstawy języka SQL.

Praca w SQL*Plus

Będziemy pracować w programie SQL*Plus pod Linuxem (windows: o:\orant\bin\sqlplus). Jako, że jest on bardzo toporny będziemy uruchamiać go z uzyciem rlwrap:

> rlwrap -ir sqlplus

Bez tego nie moglibyśmy nawet przywołać poprzednio napisanej linijki strzałką w górę! Rlwrap pozwala także na autouzupełnianie na podstawie poprzednio napisanych słów (TAB) oraz wyszukiwanie wcześniej napisanych komend (CTRL-R).

Login jest zgodny z Państwa loginem pocztowym (czyli ma format: xy123456), hasło to x. Uwaga! Po UDANYM zalogowaniu program pisze, że hasło jest przeterminowane i prosi o jego zmianę. Jest to ważny moment w którym nie można spanikować.

Po zalogowaniu możemy przystąpić do pisania zapytań SQL. Zmęczeni pracą z programu wychodzimy komendą quit lub exit.

SQL*Plus ma parę przyjaznych opcji o których warto wiedzieć:

Zadanie 1.
Uruchom SQL*Plus i zaloguj się. Sprawdź co znaczą komendy save, passw oraz host i wypróbuj ich działanie.

Na dzisiejszych zajęciach będziemy pracować na bazie demobld.sql. Aby odpalić w SQL*Plusie zapytanie zapisane w pliku plik_do_zaladowania.sql przenosimy go do katalogu z którego uruchomiliśmy program i używamy komendy:

SQL> @plik_do_zaladowania.sql

Dla plików z rozszerzeniem .sql dodanie rozszerzenia nie jest potrzebne.

Zadanie 2.
Wgraj bazę demobld. Obejrzyj (poleceniem desc) tabele emp oraz dept.

SELECT * FROM emp;

Aby wybrać niektóre informacje z tabeli używamy polecenia SELECT:

SELECT kolumny FROM tabela WHERE warunki;

Przykładowo:

SELECT * FROM emp;
SELECT ename AS imie, sal AS pensja FROM emp WHERE job = 'MANAGER' ORDER BY pensja; 

Drugie zapytanie wybiera tylko managerów i sortuje ich podług pensji. Kolumnom można zmieniać nagłówki w wynikowej tabeli (jak powyżej) pisząc kolumna AS nowa_nazwa. Można też pominąć AS.

ORDER BY sortuje wiersze wyniku rosnąco względem podanej kolumny. Aby posortował malejąco należy dodać słowo DESC po nazwie kolumny. Można także podać więcej kolumn rozdzielając je przecinkami. Uwaga! Jeżeli sortowanie nie jest podane explicite wówczas nie możemy nic zakładać o kolejności wierszy.

Aby uniknąć powtórzeń identycznych wierszy listę kolumn poprzedzamy słowem DISTINCT:

SELECT DISTINCT deptno FROM emp; # wybiera numery departamentów

W liście kolumn po SELECT, ale także w warunkach po WHERE i ORDER możemy używać wbudowanych funkcji zarówno arytmetycznych (+, -, *, /, abs, ...) jak i napisowych (concat, lower, substr, ...). Cała lista funkcji znajduje się na stronie Oracle: funkcje SQL.

W warunkach możemy też używać operatorów porównania (<, >, =, <>, ...), spójników AND, OR, a także warunku IN i BETWEEN. Wygodną konstrukcją jest też LIKE pattern, która dopasowuje napis do prostego wyrażenia w którym % oznacza dowolny ciąg znaków, a _ oznacza jeden dowolny znak. Przykładowo:

SELECT * FROM emp WHERE job LIKE '%A_ER';

A skąd mamy wiedzieć jakie tabele mamy utworzone w bazie? Ich nazwy musimy oczywiście pobrać z tabeli, a dokładnie specjalnej tabeli user_tables, która przechowuje o nich informacje.

SELECT table_name FROM user_tables;
Zadanie 3.
  1. wybierz wszystkich urzędników (clerk)
  2. wybierz miasta w których firma ma swoje departamenty
  3. wybierz imiona, pensje i stanowisko wszystkich pracowników którzy: albo mają imię zaczynające się na literę T i zarabiają więcej niż 1500 i mniej niż 2000, albo są analistami
  4. wybierz imiona pracowników którzy nie mają szefów (mgr = manager)
  5. wybierz numery wszystkich pracowników którzy mają podwładnych sortując je malejąco
  6. wybierz wszystkich pracowników i dla każdego wypisz w dodatkowej kolumnie o nazwie 'starszy' 1 jeżeli ma wcześniejsze id niż jego szef, 0 jeżeli ma późniejsze, oraz '-1' jeżeli nie ma szefa
  7. wylicz sinus liczby 3.14

INSERT INTO dept VALUES (50, 'SUPPLY', 'SCRANTON');

Aby dodać nowe rekordy wykonujemy polecenie INSERT:

INSERT INTO tabela VALUES (wartość, wartość, ...);

Możemy dodać nowy rekord podając tylko niektóre wartości, wówczas pozostałe ustawią się domyślnie (bardzo częsty przypadek w realnych zastosowaniach w których definiujemy autoincrementujący się indeks):

INSERT INTO emp (empno, ename, job, sal, deptno) VALUES ('8000', 'HEISENBERG', 'CHEMIST', 10000, 50);

Ponadto możliwe jest wstawienie całego wyniku zapytania, pod warunkiem, że typy kolumn i ich ilość będą zgadzały się z tabelą do jakiej wstawiamy. Przykładowo jeżeli żony wszystkich sprzedawców zostały zatrudnione do rozwożenia pizzy możemy je wstawić wykonując zapytanie:

INSERT INTO emp (empno, ename, job, hiredate, sal, deptno) 
    (SELECT empno+1000, CONCAT('MRS.', ename), 'PIZZA GUY', sysdate, 500, 10 
            FROM emp WHERE job = 'SALESMAN');

UPDATE emp SET sal = sal/2;

Wiersze w tabeli modyfikuje polecenie UPDATE:

UPDATE tabela SET pole = wartość, pole = wartość, ... WHERE warunek;

Przykładowo:

UPDATE emp SET sal = sal/2;   # :(
UPDATE emp SET job = 'CLERK', deptno = 30 WHERE ename = 'JONES';

Warto zwrócić uwagę na to, że po prawej stronie równości także może występować nazwa kolumny.

DELETE FROM emp WHERE deptno = 30;

Kasowanie rekordów także jest bardzo proste, wystarczy podać nazwę tabeli i warunek na wiersze do skasowania.

DELETE FROM tabela WHERE warunek;

Przykładowo kiedy rozwiązujemy departament z Chicago (30) wykonujemy zapytania:

DELETE FROM emp WHERE deptno = 30;
DELETE FROM dept WHERE deptno = 30;
Zadanie 4.
  1. do tabeli z departamentami wstaw departament IT z Warszawy
  2. dodaj siebie jako informatyka w tym departamencie bez przełożonego z pensją 2000
  3. daj sobie podwyżkę o kwotę podatku 23%
  4. skasuj wszystkich którzy zarabiają więcej niż Ty (więcej niż 2460)
  5. okazało się, że Miller ma brata bliźniaka i przychodzą do pracy na zmianę; wstaw jego brata jako nowego pracownika z tymi samymi danymi i numerem 8015 (nie przepisuj ich jednak do zapytania) po czym osobnym zapytaniem podziel ich pensje na pół

CREATE TABLE ...

Zapytanie tworzące tabelę w SQL ma nastepującą postać:

CREATE TABLE tabela (
  kolumna_1 typ_danych [dodatkowe warunki],
  kolumna_2 typ_danych [dodatkowe warunki],
  ...
  kolumna_n typ_danych [dodatkowe warunki],
  [dodatkowe warunki]
);

W Oracle SQL istnieje 5 podstawowych typów danych:

Na kolumnach można określić dodatkowe warunki. Przede wszystkim można określić że wartość w danej komórce musi być zdefiniowana - NOT NULL. Można też napisać że wartość (jeżeli jest zdefiniowana) musi być unikalna - UNIQUE. Bardzo ważne jest też określenie w tabeli klucza głównego - PRIMARY KEY - który pozwala unikalnie zidentyfikować dany wiersz. Jest on dzięki temu bardzo dobrym kandydatem na klucz zewnętrzny wiążacy z tą tabelą w innej tabeli.

Kolumnie tabeli można także ustawić inne warunki. Możemy na przykład ustawić wartość domyślną (zwykle jest to NULL) poleceniem DEFAULT, albo zupełnie dowolny test wartości poleceniem CHECK.

Zbierając powyższe informacje możemy dokładniej zdefiniować tabelę pracowników (warto porównać z aktualną).

CREATE TABLE emp (
  empno NUMBER(4) PRIMARY KEY,
  ename VARCHAR2(10) NOT NULL UNIQUE,
  job VARCHAR2(9) NOT NULL,
  mgr NUMBER(4),
  hiredate DATE DEFAULT '01-JAN-81',
  sal NUMBER(7,2) CHECK (sal > 500 AND sal < 5000),
  comm NUMBER(7,2) DEFAULT 0,
  deptno NUMBER(2) NOT NULL
);

Pod definicją kolumn możemy dodać dodatkowe warunki, na przykład unikalność pary kolumn (UNIQUE(job, deptno) oznacza, że na danym stanowisku w danym departamencie jest tylko jeden pracownik).

Jeżeli coś źle zdefiniujemy, np. ustawimy za krótkie pole tekstowe, możemy to zmienić poleceniem ALTER TABLE:

ALTER TABLE emp MODIFY (ename VARCHAR2(15));
ALTER TABLE emp ADD (dunno NUMBER(3));
ALTER TABLE emp DROP COLUMN dunno;
Zadanie 4.
Stwórz tabele Student(imie, nazwisko, nr_indeksu, plec, aktywny, data_przyjecia) nie zapominając o odpowiednich warunkach na kolumny.
Tabelę kasuje polecenie DROP TABLE tabela.

Oskar Skibski (oski@mimuw.edu.pl), Wydział Matematyki, Informatyki i Mechaniki