Bazy postrelacyjne i hybrydowe. ´Cwiczenia

Transkrypt

Bazy postrelacyjne i hybrydowe. ´Cwiczenia
Bazy postrelacyjne i hybrydowe.
Ćwiczenia
Bartosz Zieliński
14 stycznia 2012
Spis treści
1 Powtórzenie SQL
1.1 Nadanie uprawnień do tabel w schemacie HR . . . . . . . . . . . . .
1.2 Zadania z SELECT . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.1 Złaczenia
EMPLOYEES/DEPARTMENTS . . . . . . . . . .
,
1.2.2 Pracownicy i średnie płace . . . . . . . . . . . . . . . . . . . .
1.3 Zadania z DML i DDL . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.1 Tworzenie zmodyfikowanej cześciowej
kopii tabeli EMPLOY,
EES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2 Zadania z podstaw PL/SQL
2.1 Bloki i instrukcje warunkowe
2.1.1 Ocena średniej płacy .
2.2 Petle
. . . . . . . . . . . . . . .
,
2.2.1 Prosta iteracja . . . . .
2.2.2 Ciag
, Fibonacciego . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3 Zadania z obiektów
3.1 Proste typy obiektowe i tabele obiektowe . . . . . . . . . . . . . . .
3.1.1 Typ Employee Type . . . . . . . . . . . . . . . . . . . . . . . .
3.1.2 Typ Department Type i referencje do obiektów wierszowych
3.2 Ewolucja typów . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.1 Dodatkowe kolumny w Employee Type . . . . . . . . . . . .
3.2.2 Dodawanie metod do typów . . . . . . . . . . . . . . . . . . .
3.3 Dziedziczenie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.1 Podtyp typu Employee Type . . . . . . . . . . . . . . . . . . .
2
.
.
.
.
.
4
4
5
5
6
9
.
9
.
.
.
.
.
10
10
10
11
11
11
.
.
.
.
.
.
.
.
13
13
13
15
16
16
17
20
20
S PIS
TRE ŚCI
4 Zadania z kolekcji
4.1 Funkcje i typy pomocnicze . . . . . . . . . . . . . . . . . . .
4.2 Zadania z tabel zagnieżdżonych jednopoziomowo . . . . . .
4.2.1 Tablica ciagów
liczbowych . . . . . . . . . . . . . . .
,
4.3 Tabele wielokrotnie zagnieżdżone . . . . . . . . . . . . . . .
4.3.1 Kraje, regiony, lokalizacje . . . . . . . . . . . . . . .
4.3.2 Ewolucja typów i tabele wielokrotnie zagnieżdżone
5 Zadania z XML Schema
5.1 Instalacja EditiX . . . . . . . . . . . . . . . . . . . . .
5.2 Tworzenie przykładowego schematu. . . . . . . . . . .
5.3 Przechowywanie XML w repozytorium XML DB . . .
5.4 Generowanie dokumentów XML z danych relacyjnych
5.5 XMLPath w Oraclu . . . . . . . . . . . . . . . . . . . .
5.6 XQuery – jezyk
zapytań do dokumentów XML . . . .
,
3
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
22
22
23
23
26
26
28
.
.
.
.
.
.
31
31
31
32
34
38
40
Rozdział
1
Powtórzenie SQL
1.1 Nadanie uprawnień do tabel w schemacie HR
Aby nadać uprawnienia użytkownikowi stud01 uprawnienia do wykonywania
zapytań do tabel ze schematu HR (co bedzie
potrzebne w dalszej pracy) należy na
,
koncie administracyjnym (np. SYS) wykonać nastepuj
acy
kod:
,
,
declare
x varchar2(500);
begin
for y in (select table_name from all_tables
where owner=’HR’) loop
x:=’grant select on HR."’||y.table_name
||’" to stud01’;
execute immediate x;
end loop;
end;
Zmodyfikować stosownie do potrzeb.
4
R OZDZIAŁ 1 P OWT ÓRZENIE SQL
1.2 Zadania z SELECT
1.2.1 Złaczenia
EMPLOYEES/DEPARTMENTS
,
1. Wypisać zawartość tabeli EMPLOYEES ze schematu HR.
Rozwiazanie
,
select * from hr.employees;
2. Wypisać zawartość tabeli DEPARTMENTS ze schematu HR.
Rozwiazanie
,
select * from hr.departments;
3. Wypisać zestawienie
employee_id, first_name, last_name, department_name
używajac
ń
, złacze
,
a) wewnetrznego
(inner join),
,
b) lewego zewnetrznego
(left outer join),
,
c) prawego zewnetrznego
(right outer join),
,
d) pełnego zewnetrznego
(full outer join)
,
tabel EMPLOYEES i DEPARTMENTS. Porównać wyniki.
Rozwiazanie
,
-- a)
select p.employee_id,p.first_name,p.last_name,q.department_name
from hr.employees p inner join hr.departments q
on p.department_id= q.department_id;
-- b)
select p.employee_id,p.first_name,p.last_name,q.department_name
from hr.employees p left outer join hr.departments q
on p.department_id= q.department_id;
-- c)
select p.employee_id,p.first_name,p.last_name,q.department_name
from hr.employees p right outer join hr.departments q
on p.department_id= q.department_id;
5
R OZDZIAŁ 1 P OWT ÓRZENIE SQL
-- d)
select p.employee_id,p.first_name,p.last_name,q.department_name
from hr.employees p full outer join hr.departments q
on p.department_id= q.department_id;
4. Wypisać zestawienie
employee_id, first_name, last_name, department_name,
"Imie i nazwisko szefa"
tak aby w zestawieniu pojawili sie, wszyscy pracownicy.
Rozwiazanie
,
select p.employee_id,p.first_name,p.last_name,q.department_name,
r.first_name||’ ’|| r.last_name "Imie i nazwisko szefa"
from (hr.employees p left outer join hr.departments q
on p.department_id= q.department_id)
left outer join hr.employees r
on p.manager_id= r.employee_id;
1.2.2 Pracownicy i średnie płace
1. Wypisać średnia, płace, wszystkich pracowników zaokraglon
a, do 2 miejsc po
,
przecinku.
Rozwiazanie
,
select round(avg(salary),2) from hr.employees;
2. Wypisać dane pracowników których płaca jest wyższa od średniej.
Rozwiazanie
,
select * from hr.employees p
where p.salary > (
select avg(q.salary) from hr.employees q
);
3. Wypisać dane pracowników których płaca jest wyższa od średniej dla departamentu.
Rozwiazanie
,
select * from hr.employees p
where p.salary > (
select avg(q.salary) from hr.employees q
6
R OZDZIAŁ 1 P OWT ÓRZENIE SQL
where q.department_id= p.department_id
);
4. Wypisać zestawienie
first_name, last_name, "loser/winner"
gdzie w kolumnie "loser/winner" powinna znaleźć sie, wartość ’loser’
gdy pracownik zarabia poniżej średniej dla departamentu i ’winner’ gdy
zarabia powyżej. Skorzystać z wyrażenia CASE.
Rozwiazanie
,
select p.first_name,p.last_name,
case
when p.salary > (
select avg(q.salary) from hr.employees q
where q.department_id= p.department_id) then ’winner’
else ’loser’
end "loser/winner"
from hr.employees p;
5. Wypisać zestawienie średnich i maksymalnych płac oraz ilości pracowników
dla każdego department_id.
Rozwiazanie
,
select count(p.employee_id) "N", avg(p.salary) "avg",
max(p.salary) "max",p.department_id
from hr.employees p
group by p.department_id;
6. To samo co wyżej ale z nazwami departamentów. Uwaga: w zestawieniu
powinien znaleźć sie, także wiersz podsumowujacy
pracowników nie przypi,
sanych do żadnego departamentu.
Rozwiazanie
,
select e."N",e."max",e."avg",q.department_name
from (
select count(p.employee_id) "N", avg(p.salary) "avg",
max(p.salary) "max",p.department_id
from hr.employees p
group by p.department_id
) e left outer join hr.departments q
on q.department_id=e.department_id;
7
R OZDZIAŁ 1 P OWT ÓRZENIE SQL
7. Dodać do zestawienia powyżej kolumne, z imieniem i nazwiskiem pracownika o najwyższej pensji.
Rozwiazanie
,
select e."N",e."max",e."avg",q.department_name,
t.first_name||’ ’|| t.last_name "Best paid"
from ((
select count(p.employee_id) "N", avg(p.salary) "avg",
max(p.salary) "max",p.department_id
from hr.employees p
group by p.department_id
) e left outer join hr.departments q
on q.department_id=e.department_id)
inner join hr.employees t
on t.salary=e."max" and
coalesce(t.department_id,-1)=coalesce(e.department_id,-1);
8. Dodać do zestawiania z punktu powyżej kolumne, z ilościa, pracowników z
pensja, powyżej średniej.
Rozwiazanie
,
select e."N",e."above average",e."max",round(e."avg",2),
q.department_name,t.first_name||’ ’
|| t.last_name "Best paid"
from ((
select count(p.employee_id) "N", avg(p.salary) "avg",
max(p.salary) "max",p.department_id, sum(
case
when p.salary > (
select avg(x.salary) from hr.employees x
where p.department_id= x.department_id
or (p.department_id is null
and x.department_id is null))
then 1
else 0
end
) "above average"
from hr.employees p
group by p.department_id
) e left outer join hr.departments q
on q.department_id=e.department_id)
inner join hr.employees t
on t.salary=e."max" and
coalesce(t.department_id,-1)
=coalesce(e.department_id,-1);
8
R OZDZIAŁ 1 P OWT ÓRZENIE SQL
1.3 Zadania z DML i DDL
1.3.1 Tworzenie zmodyfikowanej cześciowej
kopii tabeli EMPLOYEES
,
1. Stworzyć tabele, (we własnym schemacie) o nazwie EMPLOYEES z kolumnami
employee_id, first_name, last_name, department_id tych samych typów co odpowiadajace
kolumny w tabeli HR.EMPLOYEES. EMPLOYEE_ID po,
winien być PRIMARY KEY.
Rozwiazanie
,
CREATE TABLE "EMPLOYEES" (
"EMPLOYEE_ID" NUMBER(6,0) PRIMARY KEY,
"FIRST_NAME" VARCHAR2(20 BYTE),
"LAST_NAME" VARCHAR2(25 BYTE) NOT NULL,
"DEPARTMENT_ID" NUMBER(4,0)
);
2. Skopiować dane do tabeli EMPLOYEES z tabeli HR.EMPLOYEES.
Rozwiazanie
,
insert into employees(employee_id, first_name, last_name,
department_id)
select employee_id, first_name, last_name, department_id
from hr.employees;
3. Dodać do tabeli EMPLOYEES kolumne, SALARY o tym samym typie co odpowiadajaca
kolumna w tabeli HR.EMPLOYEES.
,
Rozwiazanie
,
alter table Bartek.employees add (salary NUMBER(8,2));
4. Uzupełnić dane w nowoutworzonej kolumnie danymi z tabeli HR.EMPLOYEES.
Rozwiazanie
,
update employees p
set salary=(
select q.salary
from hr.employees q
where q.employee_id= p.employee_id
);
9
Rozdział
2
Zadania z podstaw PL/SQL
2.1 Bloki i instrukcje warunkowe
2.1.1 Ocena średniej płacy
Napisać blok anonimowy który wypisuje na dbms_output napis ’Niezla srednia’ lub ’Kiepska srednia’ zależnie od tego czy średnia płaca pracowników
(w tabeli HR.EMPLOYEES) jest wieksza
czy mniejsza od 5000 oraz poda sama,
,
średnia.
,
Rozwiazanie
,
declare
x number;
begin
select avg(salary) into x from hr.employees;
if x>5000 then
dbms_output.put_line(’Niezla srednia’);
else
dbms_output.put_line(’Kiepska srednia’);
end if;
dbms_output.put_line(’srednia=’||to_char(x));
end;
10
R OZDZIAŁ 2 Z ADANIA
Z PODSTAW
PL/SQL
2.2 Petle
,
2.2.1 Prosta iteracja
1. Napisać blok PL/SQL który wypisuje na dbms_output liczby od 0 do 10.
Rozwiazanie
,
declare
begin
for i in 0..10 loop
dbms_output.put_line(i);
end loop;
end;
2. Napisać blok PL/SQL który wypisuje na dbms_output imie,
, nazwisko i
płace, każdego z pracowników z tabeli HR.EMPLOYEES.
Rozwiazanie
,
declare
begin
for x in (
select first_name,last_name,salary from hr.employees
) loop
dbms_output.put_line(x.first_name||’ ’||x.last_name
||’ ’||to_char(x.salary));
end loop;
end;
2.2.2 Ciag
, Fibonacciego
Napisać blok PL/SQL który wypisuje na dbms_output wszystkie liczby z ciagu
,
Fibonacciego aż do pierwszej wiekszej
od
1000.
Skorzystać
z
nieograniczonej
ite,
racji LOOP.
Rozwiazanie
,
declare
a integer:=0;
b integer:=1;
buf integer;
begin
loop
dbms_output.put_line(a);
exit when a>1000;
11
R OZDZIAŁ 2 Z ADANIA
buf:=a;
a:=b;
b:=buf+b;
end loop;
end;
12
Z PODSTAW
PL/SQL
Rozdział
3
Zadania z obiektów
3.1 Proste typy obiektowe i tabele obiektowe
3.1.1 Typ Employee Type
1. Stworzyć typ obiektowy o nazwie Employee_Type z atrybutami
EMPLOYEE_ID, FIRST_NAME, LAST_NAME,
EMAIL, PHONE_NUMBER, SALARY
o typach identycznych z typami kolumn o odpowiadajacych
nazwach w tabeli
,
HR.EMPLOYEES.
Rozwiazanie
,
create or replace type employee_type as object (
EMPLOYEE_ID NUMBER(6, 0),
FIRST_NAME VARCHAR2(20 BYTE),
LAST_NAME VARCHAR2(25 BYTE),
EMAIL VARCHAR2(25 BYTE),
PHONE_NUMBER VARCHAR2(20 BYTE),
SALARY NUMBER(8, 2)
);
2. Stworzyć tabele, obiektowa, o nazwie Employee_Objects dla obiektów typu
Employee_Type. Ustanowić wiaz
, klucza głównego na atrybucie o nazwie
EMPLOYEE_ID.
13
R OZDZIAŁ 3 Z ADANIA
Z OBIEKT ÓW
Rozwiazanie
,
create table employee_objects of employee_type (
employee_id PRIMARY KEY
);
3. Stworzyć tabele, relacyjna, Employees_Departments z dwiema kolumnami:
• EMPL typu Employee_Type,
• DEPARTMENT_ID o takim samym typie jak odpowiadajaca
kolumna w
,
tabeli HR.EMPLOYEES.
Rozwiazanie
,
create table employees_departments (
EMPL employee_type,
DEPARTMENT_ID NUMBER(4, 0)
);
4. Wypełnić tabele Employee_Objects i Employees_Departments danymi
z tabeli HR.EMPLOYEES.
Rozwiazanie
,
insert into employee_objects
select employee_type(employee_id, first_name, last_name, email,
phone_number, salary)
from hr.employees;
insert into employees_departments
select employee_type(employee_id, first_name, last_name, email,
phone_number, salary), department_id
from hr.employees;
5. Wypisać zawartość tabel Employee_Objects i Employees_Departments
przy pomocy polecenia SELECT.
Rozwiazanie
,
select * from employee_objects;
select * from employees_departments;
6. Wypisać zawartość tabeli Employee_Objects jako tabeli obiektowej z pojedyńcza, anonimowa, kolumna, korzystajac
, z funkcji VALUE().
14
R OZDZIAŁ 3 Z ADANIA
Z OBIEKT ÓW
Rozwiazanie
,
select value(p) from employee_objects p;
7. Wypisać przy pomocy SELECT tylko wartości atrybutu EMPLOYEE_ID kolumny EMPL w tabeli Employees_Departments.
Rozwiazanie
,
select p.empl.salary from employees_departments p;
3.1.2 Typ Department Type i referencje do obiektów wierszowych
1. Stworzyć typ obiektowy o nazwie Department_Type i atrybutach
DEPARTMENT_ID, DEPARTMENT_NAME, MANAGER
gdzie pierwsze dwa atrybuty maja, takie same typy jak odpowiadajace
ko,
lumny w tabeli HR.DEPARTMENTS, natomiast atrybut MANAGER jest referencja, do obiektów typu Employee_Type.
Rozwiazanie
,
create type department_type as object (
DEPARTMENT_ID NUMBER(4, 0),
DEPARTMENT_NAME VARCHAR2(30 BYTE),
MANAGER REF employee_type
);
2. Stworzyć tabele, obiektowa, o nazwie Department_Objects dla obiektów
typu Department_Type z ograniczeniem PRIMARY KEY na atrybucie o nazwie DEPARTMENT_ID.
Rozwiazanie
,
create table department_objects of department_type (
department_id PRIMARY KEY
);
3. Wypełnić tabele, Department_Objects danymi z tabeli HR.DEPARTMENTS:
• W każdym wierszu atrybut MANAGER powinien być referencja, do wiersza w tabeli EMPLOYEE_OBJECTS opisujacego
managera odpowiedniego
,
departamentu.
15
R OZDZIAŁ 3 Z ADANIA
Z OBIEKT ÓW
– W tabeli HR.DEPARTMENTS znajduje sie, kolumna MANAGER_ID be,
daca
kluczem obcym odnoszacym
sie, do kolumny EMPLOYEE_ID z
,
,
tabeli EMPLOYEES (lub EMPLOYEE_OBJECTS).
• W tabeli DEPARTMENT_OBJECTS powinny znaleźć sie, dane wszystkich
departamentów, także tych dla których nie określono managera.
Rozwiazanie
,
insert into department_objects
select p.department_id,p.department_name,ref(q)
from hr.departments p left outer join employee_objects q
on p.manager_id= q.employee_id;
4. Korzystajac
, z operatora deref() wypisać dla każdego departamentu
• nazwe, departamentu,
• imie, i nazwisko managera.
Rozwiazanie
,
select p.department_name,deref(p.manager).first_name,
deref(p.manager).last_name
from department_objects p;
3.2 Ewolucja typów
3.2.1 Dodatkowe kolumny w Employee Type
1. Korzystajac
, z instrukcji ALTER TYPE dodać do typu Employee_Type dwa
nowe atrybuty:
• MANAGER typu referencja na Employee_Type,
• DEPARTMENT typu referencja na Department_Type.
Rozwiazanie
,
alter type Employee_Type add attribute(
manager ref employee_type,
department ref department_type
) cascade including table data;
2. Zweryfikować że do tabeli Employee_Objects zostały dodane nowe atrybuty.
16
R OZDZIAŁ 3 Z ADANIA
Z OBIEKT ÓW
Rozwiazanie
,
select * from employee_objects
3. Korzystajac
, z tabeli HR.EMPLOYEES i instrukcji UPDATE uzupełnić dane w
nowoutworzonych kolumnach tabeli Employee_Objects.
Rozwiazanie
,
update employee_objects p
set p.department=(
select ref(d)
from department_objects d, hr.employees e
where e.employee_id = p.employee_id
and d.department_id = e.department_id
),p.manager=(
select ref(ee)
from employee_objects ee, hr.employees f
where f.employee_id = p.employee_id
and ee.employee_id = f.manager_id
);
3.2.2 Dodawanie metod do typów
1. Używajac
, ALTER TYPE dodać metode
, MAP do typu Employee_Type o nazwie
name i typie zwracanym VARCHAR2.
Rozwiazanie
,
alter type employee_type
add map member function name return varchar2 cascade;
2. Utworzyć ciało typu Employee_Type z definicja, metody name.
• Metoda name powinna zwracać konkatenacje, nazwiska i imienia (w tej
kolejności).
Rozwiazanie
,
create or replace type body employee_type as
map member function name return varchar2 is
begin
return last_name||’ ’||first_name;
end;
end;
3. Wypróbować zdefiniowana, metode, map:
17
R OZDZIAŁ 3 Z ADANIA
Z OBIEKT ÓW
select * from Employee_Objects p order by Value(p);
4. Używajac
, ALTER TYPE dodać do typu Department_Type
• metode, MAP o nazwie name i typie zwracanym VARCHAR2,
• zwykła, bezargumentowa, metode, avg_salary zwracajac
, a, wartość typu
NUMBER.
Rozwiazanie
,
alter type department_type
add map member function name return varchar2 cascade;
alter type department_type
add member function avg_salary return number cascade;
5. Zdefiniować ciało typu Department_Type zawierajace
definicje metod name
,
i avg_salary:
• Metoda name powinna zwracać nazwe, departamentu.
• Metoda avg_salary powinna zwracać średnia, płace, dla departamentu
korzystajac
, z danych w tabeli Employee_Objects.
Rozwiazanie
,
create or replace
type body department_type as
map member function name return varchar2 is
begin
return department_name;
end;
member function avg_salary return number is
average number;
begin
select avg(p.salary)
into average
from employee_objects p
where p.department=(
select ref(q) from department_objects q
where q.department_id=self.department_id);
return average;
end;
end;
18
R OZDZIAŁ 3 Z ADANIA
Z OBIEKT ÓW
6. Wypróbować zdefiniowane metody:
• Wypisać wiersze tabeli Department_Objects posortowane według wartości funkcji Value() na zmiennej krotkowej.
Rozwiazanie
,
select * from Department_Objects p
order by value(p);
• Wypisać zestawienie Department_Name, Srednia Placa korzystajac
,
z funkcji avg_salary.
Rozwiazanie
,
select p.department_name,p.avg_salary()
from department_objects p;
7. Używajac
, ALTER TYPE dodać do typu Employee_Type:
• metode, (procedure)
, o nazwie increase_salary i pojedyńczym argumencie o nazwie amount i typie NUMBER przekazywanym w trybie IN,
Rozwiazanie
,
alter type employee_type add member procedure
increase_salary(amount in number) cascade;
• procedure, statyczna, o nazwie increase_salary i dwóch argumentach
typu number przekazywanych w trybie IN o nazwach emplid i amount.
Rozwiazanie
,
alter type employee_type add static procedure
increase_salary(employee_id in number,amount in number)
cascade;
8. Uzupełnić ciało typu employee_type o definicje procedur (metody i statycznej) increase_salary:
• Metoda increase_salary powinna dodawać wartość amount do atrybutu salary obiektu na rzecz którego została wywołana.
• Procedura statyczna increase_salary powinna zwiekszać
o amount
,
wartość atrybutu salary instancji employee_type przechowywanej w
tabeli employee_objects o atrybucie employee_id równym emplid
używajac
, metody increase_salary z poprzedniego punktu.
19
R OZDZIAŁ 3 Z ADANIA
Z OBIEKT ÓW
Rozwiazanie
,
create or replace type body employee_type as
map member function name return varchar2 is
begin
return last_name||’ ’||first_name;
end;
member procedure increase_salary(amount in number) is
begin
salary:=salary + amount;
end;
static procedure increase_salary(employee_id in number,
amount in number) is
x employee_type;
y number:=employee_id;
begin
select value(p) into x from employee_objects p
where p.employee_id=y;
x.increase_salary(amount);
update employee_objects p
set value(p)=x
where p.employee_id=y;
end;
end;
9. Wypróbować statyczna, metode, increase_salary().
Rozwiazanie
,
declare
begin
employee_type.increase_salary(100,1000);
end;
3.3 Dziedziczenie
3.3.1 Podtyp typu Employee Type
1. Używajac
, ALTER TYPE uczynić typ Employee_Type niefinalnym. Pamietać
,
o klauzuli cascade convert to substitutable w ALTER TYPE.
Rozwiazanie
,
alter type employee_type not final
cascade convert to substitutable;
20
R OZDZIAŁ 3 Z ADANIA
Z OBIEKT ÓW
2. Stworzyć podtyp Employee_Type o nazwie Employee_Ext_Type majacy
,
jeden dodatkowy atrybut o nazwie HIRE_DATE typu DATE.
3. Zmodyfikować wiersze w Employee_Objects o employee_id>179 tak aby
zawierały obiekty Employee_Ext_Type. Dane do ostatniej kolumny pobrać
z HR.EMPLOYEES.
4. Użyć TREAT aby wyświetlić kolumne, HIRE_DATE dla tych z obiektów wierszowych przechowywanych w tabeli Employee_Objects których faktycznym typem jest Employee_Ext_Type. Wykorzystać predykat IS OF w warunku WHERE.
21
Rozdział
4
Zadania z kolekcji
4.1 Funkcje i typy pomocnicze
Zdefniniować
• typ tablicowy INT_SEQ_TYPE:
create type INT_SEQ_TYPE as table of integer;
• i funkcje, tablicowa, INT_SEQUENCE:
create function
INT_SEQUENCE(a in integer,b in integer,
step in integer default 1)
return INT_SEQ_TYPE pipelined as
i integer:=a;
begin
loop
pipe row(i);
i:=i+step;
exit when i>b;
end loop;
end;
a nastepnie
wypróbować jej działanie:
,
22
R OZDZIAŁ 4 Z ADANIA
Z KOLEKCJI
select value(p)
from table(int_sequence(4,1000,42)) p;
4.2 Zadania z tabel zagnieżdżonych jednopoziomowo
4.2.1 Tablica ciag
, ów liczbowych
1. Utworzyć tablice, o nazwie tbl_test z dwiema kolumnami:
• nazwa – typu VARCHAR(20) i z wiezem
PRIMARY KEY,
,
• liczby – typu INT_SEQ_TYPE.
Nie zapomnieć o klauzuli STORE AS. Jako nazwe, tablicy pomocniczej do
przechowywania wartości z kolumny liczby podać liczby_tbl.
Rozwiazanie
,
create table tbl_test (
nazwa varchar(20) primary key,
liczby INT_SEQ_TYPE
) nested table liczby store as liczby_tbl;
2. Wstawić do tbl_test wiersz z nazwa=’a’ i polem liczby zawierajacym
,
trzy liczby: 3, 2 i 9 korzystajac
z
notacji
konstruktorowej.
,
Rozwiazanie
,
insert into tbl_test values(’recznie’, int_seq_type(3,2,9));
3. Wstawić do tbl_test wiersz (’b’,null).
Rozwiazanie
,
insert into tbl_test values(’b’,null);
4. Spróbować wstawić do tabeli zagnieżdżonej w kolumnie liczby w wierszu
z nazwa=’b’ liczby od 5 do 12 korzystajac
, z insert...select i zdefiniowanej wcześniej funkcji tablicowej int_sequence():
insert into table(select liczby from tbl_test
where nazwa=’b’)
23
R OZDZIAŁ 4 Z ADANIA
Z KOLEKCJI
select p.column_value
from table(int_sequence(5,12,1)) p;
Zweryfikować że operacja kończy sie, błedem
z powodu niemożliwości wyko,
nania insert na tabeli atomowo null.
5. Zmienić wartość kolumny liczby w wierszu z nazwa=’b’ na tablice, pusta,
przy pomocy instrukcji update i powtórzyć próbe, wstawienia wartości z poprzedniego punktu.
Rozwiazanie
,
update tbl_test
set liczby=int_seq_type()
where nazwa=’b’;
insert into table(select liczby from tbl_test where nazwa=’b’)
select p.column_value from TABLE(int_sequence(5,12,1)) p;
6. Wstawić wiersz z nazwa=’c’ i kolumna, liczby zawierajac
, a, wartości 2 oraz
9, 11, . . ., 19 (co 2).
• Najpierw wstawić wiersz (’c’,int_seq_type(2)) a potem dostawić
reszte, wartości korzystajac
, z funkcji int_sequence().
Rozwiazanie
,
insert into tbl_test values(’c’,int_seq_type(2));
insert into table(select liczby from tbl_test where nazwa=’c’)
select p.column_value from TABLE(int_sequence(9,20,2)) p;
7. Wstawić wartość 7 do tabeli zagnieżdżonej w wierszu z name=’b’.
Rozwiazanie
,
insert into table(
select liczby from tbl_test where nazwa=’b’
) values(7);
8. Wyświetlić zawartość tabeli tbl_test.
Rozwiazanie
,
select * from tbl_test;
9. Wyświetlić spłaszczona, zawartość tabeli tbl_test:
24
R OZDZIAŁ 4 Z ADANIA
Z KOLEKCJI
select p.nazwa,q.column_value
from tbl_test p,table(p.liczby) q;
10. Wyświetlić MULTISTET UNION, MULTISET INTERSECT, MULTISET EXCEPT
dla tabel zagnieżdżonych w kolumnie liczby dla name=’a’ i ’b’. Przykład:
select (select p.liczby from tbl_test p
where nazwa=’a’) multiset union
(select p.liczby from tbl_test p
where nazwa=’b’)
from dual;
11. Wypróbować operator SET:
select p.nazwa, set(p.liczby),p.liczby
from tbl_test p;
12. Wyświetlić wszystkie liczby przechowywane w tabeli w postaci pojedyńczej
kolekcji. Wykorzystać operator CAST( MULTISET . . . ):
select cast(multiset(
select q.column_value
from tbl_test p,table(p.liczby) q
) as int_seq_type) from dual;
13. Wyświetlić ilości elementów w każdej z tabel zagnieżdżonych korzystajac
, z
funkcji CARDINALITY():
select p.nazwa, cardinality(p.liczby)
from tbl_test p;
14. Stworzyć typ o nazwie int_tab_tab tablic zagnieżdżonych elementów typu
int_seq_type.
Rozwiazanie
,
create type int_tab_tab as table of int_seq_type;
25
R OZDZIAŁ 4 Z ADANIA
Z KOLEKCJI
15. Wypróbować funkcje, POWERMULTISET():
select p.nazwa, cast(powermultiset(p.liczby)
as int_tab_tab)
from tbl_test p;
4.3 Tabele wielokrotnie zagnieżdżone
4.3.1 Kraje, regiony, lokalizacje
1. Zdefiniować typ obiektowy locations_type z atrybutami
LOCATION_ID, STREET_ADDRESS, POSTAL_CODE,
CITY, STATE_PROVINCE
o tych samych typach co odpowiadajace
kolumny w tabeli hr.locations.
,
Rozwiazanie
,
create type locations_type as object (
LOCATION_ID NUMBER(4, 0),
STREET_ADDRESS VARCHAR2(40 BYTE),
POSTAL_CODE VARCHAR2(12 BYTE),
CITY VARCHAR2(30 BYTE),
STATE_PROVINCE VARCHAR2(25 BYTE)
);
2. Stworzyć typ o nazwie locations_table tablic zagnieżdżonych o elementach typu locations_type.
Rozwiazanie
,
create type locations_table as table of locations_type;
3. Zdefiniować typ obiektowy countries_type o atrybutach:
• COUNTRY_ID, COUNTRY_NAME – typy takie same jak typy odpowiadaja,
cych kolumn z tabeli hr.countries,
• LOCATIONS – typu locations_table.
Rozwiazanie
,
create type countries_type as object (
COUNTRY_ID CHAR(2 BYTE),
26
R OZDZIAŁ 4 Z ADANIA
Z KOLEKCJI
COUNTRY_NAME VARCHAR2(40 BYTE),
locations locations_table
);
4. Zdefiniować typ o nazwie countries_table tabel zagnieżdżonych o elementach typu countries_type.
Rozwiazanie
,
create type countries_table as table of countries_type;
5. Zdefiniować typ obiektowy region_type o atrybutach:
• REGION_ID, REGION_NAME – typy takie same jak typy odpowiadajacych
,
kolumn z tabeli hr.regions,
• COUNTRIES – typu countries_table.
Rozwiazanie
,
create type region_type as object (
REGION_ID NUMBER,
REGION_NAME VARCHAR2(25 BYTE),
COUNTRIES COUNTRIES_TABLE
);
6. Stworzyć tabele, obiektowa, region_objects obiektów region_type. Pomocnicze tabele do przechowywania tabel zagnieżdżonych nazwać odpowiednio locations_aux_tbl i countries_aux_tbl.
• Kolumny REGION_ID, COUNTRY_ID i LOCATION_ID powinny być kluczami głównymi odpowiednio zewnetrznej
tabeli i zagnieżdżonych pod,
tabel.
Rozwiazanie
,
create table region_objects of region_type (
region_id PRIMARY KEY
) nested table countries store as countries_aux_tbl (
(country_id PRIMARY KEY)
nested table locations store as locations_aux_tbl (
(location_id PRIMARY KEY)
)
);
7. Wypełnić tabele, region_objects danymi z tabel ze schematu HR korzystajac
, z podzapytań skorelowanych i CAST(MULTISET...).
27
R OZDZIAŁ 4 Z ADANIA
Z KOLEKCJI
Rozwiazanie
,
insert into region_objects
select r.region_id,r.region_name,cast(multiset(
select countries_type(q.country_id,q.country_name, cast(multiset(
select locations_type(p.location_id,p.street_address,
p.postal_code,p.city,
p.state_province)
from hr.locations p
where p.country_id= q.country_id
) as locations_table)) from hr.countries q
where q.region_id=r.region_id
) as countries_table)
from hr.regions r;
8. Wypisać całkowicie spłaszczona, zawartość tabeli region_objects.
Rozwiazanie
,
select r.region_name,q.country_name,p.*
from region_objects r,table(r.countries) q,table(q.locations) p;
4.3.2 Ewolucja typów i tabele wielokrotnie zagnieżdżone
1. Stworzyć typ obiektowy o nazwie dept_t i atrybutach DEPARTMENT_ID i
DEPARTMENT_NAME których typy powinny być takie same jak typy odpowiadajacych
kolumn z tabeli hr.departments.
,
Rozwiazanie
,
create type dept_t as object (
"DEPARTMENT_ID" NUMBER(4,0),
"DEPARTMENT_NAME" VARCHAR2(30 BYTE)
);
2. Stworzyć typ tabela zagnieżdżona o nazwie dept_t_table elementów typu
dept_t.
Rozwiazanie
,
create type dept_t_table as table of dept_t;
3. Dodać do typu locations_type nowy atrybut typu dept_t_table o nazwie dept. Użyć klauzuli invalidate zamiast cascade.
Rozwiazanie
,
alter type locations_type add attribute(dept dept_t_table)
invalidate;
28
R OZDZIAŁ 4 Z ADANIA
Z KOLEKCJI
4. Używajac
, komendy alter type ... upgrade zadeklarować tabele
, o nazwie depts_aux_tbl jako przechowujac
, a, elementy w kolumnie dept w tabeli locations_aux_tbl.
alter table locations_aux_tbl
upgrade nested table dept store as depts_aux_table;
5. Używajac
, kursorów i bloku PL/SQL wykonać update nowej kolumny dept
we wszystkich tabelach zagnieżdżonych w kolumnie locations do zagnieżdżonej tabeli pustej typu dept_t_table (dept_t_table()).
Rozwiazanie
,
declare
cursor c1 is
select value(c)
from region_objects r,table(r.countries) c
for update;
x countries_type;
begin
open c1;
loop
fetch c1 into x;
exit when c1%notfound;
update table(
select cc.locations
from region_objects r,table(r.countries) cc
where cc.country_id=x.country_id
) p
set p.dept=dept_t_table();
end loop;
close c1;
commit;
end;
6. Używajac
, kursorów i bloku PL/SQL wstawić do tabel zagnieżdżonych w kolumnie dept odpowiednie dane z tabeli hr.departments.
• Dla każdej lokalizacji wstawiamy do kolumny dept tylko te departamenty które znajduja, sie, w tej lokalizacji.
Rozwiazanie
,
29
R OZDZIAŁ 4 Z ADANIA
Z KOLEKCJI
declare
cursor c2 is
select value(l)
from region_objects r,table(r.countries) c,
table(c.locations) l
for update;
y locations_type;
begin
open c2;
loop
fetch c2 into y;
exit when c2%notfound;
insert into table(
select l.dept
from region_objects r,table(r.countries) c,
table(c.locations) l
where l.location_id=y.location_id
) select dept_t(p.department_id,p.department_name)
from hr.departments p
where p.location_id=y.location_id;
end loop;
close c2;
commit;
end;
30
Rozdział
5
Zadania z XML Schema
5.1 Instalacja EditiX
Ściagn
ać
,
, i zainstalować darmowa, wersje
, edytora XML o nazwie EditiX.
5.2 Tworzenie przykładowego schematu.
Napisać schemat XML opisujacy
typ dokumentu XML zawierajacego
informacje
,
,
o pracownikach w departamentach, np:
<hr:departments
xmlns:hr="http://www.wfis.uni.lodz.pl/imie">
<hr:department id="1">
<hr:name>Finance</hr:name>
<hr:employee id="1">
<hr:first_name>Donnie</hr:first_name>
<hr:last_name>Darko</hr:last_name>
<hr:email>ddarko@ii</hr:email>
<hr:phone>0121212121</hr:phone>
<hr:salary>20000</hr:salary>
</hr:employee>
</hr:department>
</hr:departments>
31
R OZDZIAŁ 5 Z ADANIA
Z
XML S CHEMA
zgodnie z nastepuj
acymi
regułami:
,
,
1. Element departments może zawierać dowolna, ilość elementów department.
2. Element department może zawierać dowolna, ilość elementów employee.
Zwiazać
przykładowy dokument XML ze schematem.
,
5.3 Przechowywanie XML w repozytorium XML DB
1. W folderze public repozytorium XML DB utworzyć podfolder o nazwie be,
dacej
konkatenacj
a
imienia
i
nazwiska
studenta.
Do
tego
folderu
b
edziemy
,
,
,
sie, odwoływać dalej pod nazwa, student.
DECLARE
res BOOLEAN;
BEGIN
res:=dbms_xdb.createfolder(’/public/your_name’);
IF res THEN
dbms_output.put_line(’Success!!!’);
ELSE
dbms_output.put_line(’Failure....’);
END IF;
END;
2. W stworzonym w poprzednim zadaniu schemacie departments.xsd dodać:
• Deklaracje, przestrzeni nazw http://xmlns.oracle.com/xdb (z prefiksem xdb) w elemencie <xs:schema>.
• Adnotacje, Oracla
xdb:defaultTable="DepartmentsXMLTable"
w definicji elementu korzeniowego departments.
3. Wysłać zmodyfikowany schemat departments.xsd do repozytorium do folderu student przy pomocy ftp (port 2100). Logować sie, jak do bazy.
4. Obejrzeć zawartość pliku /public/student/departments.xsd w repozytorium XML DB przy pomocy przegladarki
(port 8080).
,
32
R OZDZIAŁ 5 Z ADANIA
Z
XML S CHEMA
5. Obejrzeć zawartość widoku resource_view.
6. Wyświetlić (korzystajac
, z metody getClobVal() zawartość kolumny res w
formie tekstu, dla pliku departments.xsd.
select r.res.getClobVal() from resource_view r
where any_path=’/public/your_name/departments.xsd’;
7. Wyświetlić zawartość pliku departments.xsd korzystajac
, z xdburitype().
select xdburitype(’/public/your_name
/departments.xsd’).getClob()
from dual;
8. Zarejestrować schemat departments.xsd pod nazwa,
http://www.wfis.uni.lodz.pl/kft2/student/Departments.xsd
gdzie student należy zastapić
przez imie, i nazwisko studenta. Użyć opcji
,
gentables=>false.
DECLARE
BEGIN
dbms_xmlschema.registerSchema(
’http://www.wfis.uni.lodz.pl/
kft2/student/Departments.xsd’,
XDBURIType(’/public/your_name/departments.xsd’),
gentables=>false);
END;
9. W folderze /sys/schemas/studxx odnaleźć zarejestrowany schemat i obejrzeć dodatkowe adnotacje. Użyć przegladarki.
,
10. Zmodyfikować utworzony wcześniej przykładowy plik departments.xml
zmieniajac
, lokalizacje
, schematu na
http://www.wfis.uni.lodz.pl/kft2/student/Departments.xsd
33
R OZDZIAŁ 5 Z ADANIA
Z
XML S CHEMA
11. Zweryfikować że próba umieszczenia pliku w repozytorium przy pomocy ftp
kończy sie, niepowodzeniem.
12. Utworzyć tabele, DepartmentsXMLTable ograniczona, do schematu
http://www.wfis.uni.lodz.pl/kft2/student/Departments.xsd
i do dokumentów XML których korzeniem jest element <departments>:
CREATE TABLE "DepartmentsXMLTable" OF XMLType
XMLSCHEMA "http://www.wfis.uni.lodz.pl/
kft2/studentxx/Departments.xsd"
element "departments";
13. Ponowić próbe, umieszczenia pliku departments.xml w repozytorium.
14. Zweryfikować że plik znajduje sie, w repozytorium XMLDB oraz we wcześniej
utworzonej tabeli DepartmentsXMLTable.
5.4 Generowanie dokumentów XML z danych
relacyjnych
1. Wykonać nastepuj
ace
zapytania:
,
,
•
select XMLElement(name "department",
xmlattributes(d.department_id as "id"),
d.department_name)
from HR.departments d;
•
select XMLElement(name "department",
xmlelement(name "id",d.department_id),
xmlelement(name "name",d.department_name))
from HR.departments d;
•
select XMLAgg(XMLElement(name "department",
xmlattributes(d.department_id as "id"),
34
R OZDZIAŁ 5 Z ADANIA
Z
XML S CHEMA
d.department_name)
order by d.department_name)
from HR.departments d;
•
select XMLElement(name "departments",
XMLAgg(XMLElement(name "department",
xmlattributes(d.department_id as "id"),
d.department_name)
order by d.department_name))
from HR.departments d
group by location_id;
2. Stworzyć tabele, xml-owa, o nazwie xmltest:
create table xmltest of xmltype;
3. Stworzyć tabele, relacyjna, o nazwie xmlemployees o dwóch kolumnach:
• employee_id o tym samym typie co typ kolumny o tej samej nazwie w
tabeli hr.employees.
• empl_data typu xmltype.
4. Wypełnić tabele xmltest i xmlemployees danymi korzystajac
, z danych
w tabelach hr.employees i hr.jobs. Dla każdego pracownika powinien
zostać utworzony dokument XML z elementami takimi jak w poniższym
przykładzie:
<employee id="190" manager_id="122">
<first_name>Timothy</first_name>
<last_name>Gates</last_name>
<email>TGATES</email>
<phone_number>650.505.3876</phone_number>
<hire_date>1998-07-11</hire_date>
<job id="SH_CLERK">Shipping Clerk</job>
<salary>2900</salary>
</employee>
5. Stworzyć plik XHTML z danych w tabelach HR.Employees i HR.Departments:
35
R OZDZIAŁ 5 Z ADANIA
Z
XML S CHEMA
• Plik powinien zawierać tabele, z dwiema kolumnami:
– Nazwy dapartament\’ow z nazwami departamentów,
– Pracownicy z tabelami zawierajacymi
imiona i nazwiska pracow,
ników dla każdego departamentu.
6. Stworzyć plik XML zawierajacy
dane z tabel schematu HR który spełnia
,
nastepuj
acy
schemat:
,
,
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="unqualified"
targetNamespace="www.wfis.uni.lodz.pl/kft2"
xmlns="www.wfis.uni.lodz.pl/kft2">
<xs:complexType name="employee_type">
<xs:sequence>
<xs:element name="first_name" type="xs:string"/>
<xs:element name="last_name" type="xs:string"/>
<xs:element name="email" type="xs:string"/>
<xs:element name="phone_number" type="xs:string"/>
<xs:element name="hire_date" type="xs:date"/>
<xs:element name="job">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="salary" type="xs:decimal"/>
</xs:sequence>
<xs:attribute name="id" type="xs:decimal"/>
<xs:attribute name="manager_id" type="xs:decimal"/>
</xs:complexType>
36
R OZDZIAŁ 5 Z ADANIA
Z
XML S CHEMA
<xs:complexType name="department_type">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="employee" type="employee_type"
maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="id" type="xs:decimal"/>
<xs:attribute name="manager_id" type="xs:decimal"/>
</xs:complexType>
<xs:complexType name="location_type">
<xs:sequence>
<xs:element name="street_address" type="xs:string"/>
<xs:element name="postal_code" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="state_province" type="xs:string"/>
<xs:element name="department" type="department_type"
minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:decimal"/>
</xs:complexType>
<xs:complexType name="country_type">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="location" type="location_type"
minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string"/>
</xs:complexType>
<xs:complexType name="region_type">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="country" type="country_type"
minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string"/>
37
R OZDZIAŁ 5 Z ADANIA
Z
XML S CHEMA
</xs:complexType>
<xs:element name="hr">
<xs:complexType>
<xs:sequence>
<xs:element name="REGION" type="region_type"
minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="unassigned">
<xs:complexType>
<xs:sequence>
<xs:element name="employee" type="employee_type"
minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
i umieścić go pod nazwa, hr.xml w utworzonym poprzednio podkatalogu folderu public w repozytorium XMLDB.
5.5 XMLPath w Oraclu
1. Porównać i zrozumieć działanie nastepuj
acych
poleceń:
,
,
•
SELECT Extract(
xdburitype(’/public/YourName/hr.xml’).getxml(),
’//employee’) "A"
FROM DUAL;
•
SELECT p.COLUMN_VALUE
FROM TABLE(
XMLSequence(
Extract(
38
R OZDZIAŁ 5 Z ADANIA
Z
XML S CHEMA
xdburitype(’/public/YourName/hr.xml’).getxml(),
’//employee’)
)) p;
•
SELECT e.employee_id,p.*
FROM xmlemployees e, TABLE(
XMLSequence(Extract(e.empl,’//*’))
) p;
2. Wypróbować nastepuj
ace
polecenia wykorzystujace
typy uritype:
,
,
,
•
select httpuritype(
’http://www.wfis.uni.lodz.pl/kft2’
).getXML()
from dual;
•
select dburitype(’/HR/EMPLOYEES’).getXML()
from dual;
3. Wypróbować w przegladarce
nastepuj
ace
URL-e wykorzystujace
serwlet Oracla
,
,
,
,
DbUriServlet i wyrażenia XPath, gdzie za server należy podstawić adres
serwera:
•
http://server:8080/oradb/HR/EMPLOYEES
•
http://server:8080/oradb/HR/EMPLOYEES
?rowsettag=employees
•
http://server:8080/oradb/HR/EMPLOYEES
/ROW/SALARY?rowsettag=employees
•
http://server:8080/oradb/HR/EMPLOYEES
/ROW[SALARY>7000]?rowsettag=employees
39
R OZDZIAŁ 5 Z ADANIA
Z
XML S CHEMA
5.6 XQuery – jezyk
zapytań do dokumentów XML
,
We wszystkich poniższych przykładach skrypt XQuery powinien być poprzedzany
deklaracja, domyślnej przestrzeni nazw:
declare default element namespace
"http://www.wfis.uni.lodz.pl/kft2/nsbooks";
Korzystamy z pliku books.xml jako pliku do którego bed
, a, wykonywane zapytania.
1. Wypróbować i zrozumieć nastepuj
ace
wyrażenia XPATH:
,
,
<results>
{//book}
</results>
<results>
{//book[@series_id="1"]}
</results>
<results>
{//book[not(@series_id)]}
</results>
<results>
{//book[@href]}
</results>
<results>
{//book[not(@series_id) or @href]}
</results>
<result>
{//book/element()}
</result>
40
R OZDZIAŁ 5 Z ADANIA
Z
XML S CHEMA
<result>
{//book[count(genre)>1]/title}
</result>
<result>
{//book/genre[position() =1]}
</result>
<result>
{//book[genre/last()>1]}
</result>
<result>
{distinct-values(//book/genre)}
</result>
2. Przykład prostej iteracji po liczbach:
<iteration>
{
for $i in 0 to 10
return <b>{$i}</b>
}
</iteration>
3. Przykład iteracji po wyrażeniach zwróconych przez XPATH:
<ol>{
for $i in //book[@series_id="1"]/title
return <li>{$i/text()}</li>
}</ol>
4. Klauzula at pozwala na uzyskanie pozycji bieżacego
elementu na liście po
,
której iterujemy:
<basic>
{
41
R OZDZIAŁ 5 Z ADANIA
Z
XML S CHEMA
for $i at $pos in (0,1,2,3,4,5,6)
return
<pair>
<value>{$i}</value>
<position>{$pos}</position>
</pair>
}
</basic>
5. Bardziej złożony przykład wykorzystania at:
<FLWOR>{
for $title at $pos in //title
return
<title pos="{$pos}">{xs:string($title)}</title>
}</FLWOR>
6. Wyrażenie warunkowe:
if(true) then "a" else "b"
7. Rozsadny
przykład zastosowania wyrażenia warunkowego:
,
<books>{
for $book in //book
return (
$book/author,
$book/title,
<genres>{
$book/genre[1]/text(),
if(count($book/genre)>1)
then ",..."
else ()
}</genres>
)
}
</books>
42
R OZDZIAŁ 5 Z ADANIA
Z
XML S CHEMA
8. Przygotować przy pomocy XQuery, na podstawie pliku books.xml raport w
XHTML taki jak w pliku przykładowym books.html.
43

Podobne dokumenty