ПБД (9) - Лекция №8 - OQL: различия между версиями
ILobster (обсуждение | вклад) (Новая страница: «== SQL == === Пользовательские типы данных === User Defined Types - UDT. Создаём свой тип: <syntaxhighlight lang="sql">...») |
|||
(не показаны 4 промежуточные версии 2 участников) | |||
Строка 1: | Строка 1: | ||
{{Tabli4ka warning undone summary|text= - [[#Запросы на OQL | примеров запросов на языке OQL]].}} | |||
<br> | |||
__TOC__ | |||
== SQL == | == SQL == | ||
Строка 79: | Строка 82: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== Запросы ==== | ==== Запросы к UDT ==== | ||
<syntaxhighlight lang="sql"> | <syntaxhighlight lang="sql"> | ||
Строка 206: | Строка 209: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Запросы === | === Запросы на OQL === | ||
Связь М-М, все актеры, которые снимались в фильме: | |||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT | SELECT a.fio | ||
FROM EF f, f.acts a | FROM EF f, f.acts a | ||
WHERE | WHERE f.title="Иванов" AND f.year < 1950 | ||
</syntaxhighlight> | |||
<syntaxhighlight lang="mysql"> | |||
SELECT a.fio, a.addr | SELECT a.fio, a.addr | ||
FROM EA a | FROM EA a | ||
Строка 218: | Строка 222: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
и | Коллекция - элемент, множество связанных объектов и вложенный подзапрос. | ||
Пример с группировкой: | |||
<syntaxhighlight lang="mysql"> | |||
4 SELECT st, y , sumlen: sum(SELECT P.f.len FROM PARTITION P) | |||
1 FROM ES st, st.fms F | |||
2 WHERE f.year>2000 | |||
3 GROUP BY st:st.name, y:f.year | |||
</syntaxhighlight> | |||
PARTITION - результат группировки, коллекция всех объектов, которые попали в отдельную группу. | |||
Здесь st и f. | |||
WHERE работает до группировки. | |||
HAVING накладывает ограничения на группы. Если он есть, то выполняется 4-ым шагом ( до SELECT'а). | |||
<syntaxhighlight lang="mysql"> | |||
HAVING MIN(SELECT p.f.len FROM PARTITION P)>60. | |||
</syntaxhighlight> | |||
Сортировка: | |||
<syntaxhighlight lang="mysql"> | |||
ORDER BY ASC st, year | |||
</syntaxhighlight> | |||
==== Агрегаты ==== | |||
<syntaxhighlight lang="mysql"> | |||
COUNT() - Для любых | |||
MIN() - для подлежащих сортировке | |||
SUM() - только для числовых | |||
AVG() - только для числовых | |||
MAX() - для подлежащих сортировке | |||
</syntaxhighlight> | |||
Можно применять к коллекции: | |||
<syntaxhighlight lang="mysql"> | |||
COUNT(EF) - кол-во элементов в экстенте. | |||
</syntaxhighlight> | |||
Поддерживаются кванторы: | |||
<syntaxhighlight lang="mysql"> | |||
SELECT a | |||
FROM EA a | |||
WHERE FOR ALL F IN a.films:F.st.name="ЛенФильм" AND f.year=2016 | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="mysql"> | |||
FOR ALL IN - квантор всеобщности | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="mysql"> | |||
SELECT a | |||
FROM EA a | |||
WHERE EXISTS f1 IN a.films:f.yaer<2000 | |||
</syntaxhighlight> | |||
Запрос на единственность: | |||
<syntaxhighlight lang="mysql"> | |||
SELECT s | |||
FROM ES s | |||
WHERE COUNT(s.fms)=1 | |||
Те студии, которые сняли только один фильм. | |||
</syntaxhighlight> | |||
По умолчанию возвращается мультимножество структур. | |||
<syntaxhighlight lang="mysql"> | |||
SELECT a.fio, f.year | |||
Bag<struct{struct{f, i, o}, integer year}> | |||
</syntaxhighlight> | |||
Если хочется SET: | |||
<syntaxhighlight lang="mysql"> | |||
SELECT DISTINCT | |||
</syntaxhighlight> | |||
Если хочется LIST: | |||
<syntaxhighlight lang="mysql"> | |||
ORDER BY | |||
</syntaxhighlight> | |||
Можно и свою коллекцию: | |||
<syntaxhighlight lang="mysql"> | |||
SELECT struct(fam:a.fio.f, yearMade:f.year) | |||
Если поле одно, то структура не формируется. | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="mysql"> | |||
(SELECT a | |||
FROM EA a, a.films f | |||
WHERE f.stud.name="МосФильм") | |||
EXCEPT | |||
(SELECT a | |||
FROM EA a, EF f | |||
WHERE f.stud.name="Экран") | |||
Аналогично можно с UNION и INTERSECT | |||
</syntaxhighlight> | |||
[[Категория:Постреляционные базы данных (9 семестр)]] | [[Категория:Постреляционные базы данных (9 семестр)]] | ||
[[Категория:Конспекты лекций и семинаров]] | [[Категория:Конспекты лекций и семинаров]] |
Текущая версия от 14:12, 2 ноября 2016
Этот конспект ещё не дописан. Здесь не хватает: - примеров запросов на языке OQL. |
SQL
Пользовательские типы данных
User Defined Types - UDT.
Создаём свой тип:
CREATE TYPE Addr as
(
city char(20),
street varchar(100)
)
-- объявление метода
method fullad() returns varchar(130);
-- определение метода
CREATE method fullad() returns varchar(130)
for Addr
begin
return self.city || self.street
end;
Используем его при описании других:
CREATE TYPE Studia as
(
sname varchar(50),
addr Addr
);
CREATE TYPE Actor as
(
inn int,
fio varchar(50),
addr Addr
);
Создаём таблицы со ссылками:
CREATE TABLE Tact of Actor
(
primary key (inn),
ref is Ida system generated
);
CREATE TABLE TSt
(
ref is Ids system generated
)
Создаём тип со ссылками:
CREATE TYPE Film as
(
title varchar(80),
year unt,
len int,
type char(2),
st REF(Studia) [SCOPE TSt] -- SCOPE показывает, что это на конкретную талицу
);
Ещё таблицы:
CREATE TABLE FA
(
act REF(Actor) SCOPE TAct,
film REF(Film) SCOPE TF
);
CREATE TABLE TF of Film
(
ref is Idf system generated
);
Запросы к UDT
-- один ко многим
SELECT year, len st->sname, st->addr.city, st->addr.fullad()
FROM TF
WHERE title = 'The Matrix'
-- многие ко многим (обращение к одной таблице, которая её реализует)
SELECT film->title, film->year, film->st->name
FROM FA
WHERE act->fio='Иванов'
-- разыменование ссылок
SELECT deref(act)
FROM FA
WHERE film->title='The Matrix' -- выведет всех актёров этого фильма
Методы
Создаются системой автоматически.
Методы обозреватели
Они же getter
. Совпадают с названием поля, не имеют параметров. Нужны для получения значений полей.
SELECT f.title(), f.len()
FROM TF
WHERE f.type='BW'
Методы модификаторы
Они же setter
. Для изменения значения полей.
Методы генераторы
Они же конструкторы.
DECLARE newA Addr;
DECLARE newS Stud;
set newA = Addr(); -- вызов конструктора
newA.city('Москва');
newA.street('Ленина, 2');
set newS = Studia(); -- вызов конструктора
newS.sname('Мосфильм');
news.addr(newA);
INSERT INTO TSt VALUES(newS);
Сравнение типов
CREATE ORDERING for Addr
<EQUALS ONLY | ORDER FULL | RELATIVE WITH f> BY STATE
-- f - это функция, выполняющая сравнение двух параметров
-- она не стандартная, её надо создать
CREATE FUNCTION f(x1 Addr, x2 Addr) returns int
IF x1.city > x2.city TNEN return 1;
ELSE IF x1.city < x2.city TNEN return -1;
ELSE IF x1.street > x2.street TNEN return 1;
ELSE IF x1.street < x2.street TNEN return -1;
ELSE return 0;
END IF;
Производные типы
CREATE TYPE имя UNDER базовый тип as
(
поле тип,
...
[[not] instantiable] -- можно ли на его основе создать ещё тип
[not] final -- можно ли его переопределять
<ref is system generated | ref using тип | ref using (атрибут)>
);
[overriding]
[<instance | static | constructor>]
method название(параметры) returns тип
[self as <result | locator>]
[parameter style <SQL | Java | ...>]
[[not] deteministic]
[no SQL | contains SQL | ...]
[return <NULL on NULL input | called on NULL input>]
OQL
Object Query Language.
class Film(extent EF)
{
attribute string title;
attribute string year;
attribute string len;
attribute string type;
relationship Stud st inverse Stud::fl;
relationship set <Actor> acts inverse Actor::films;
set <Stud> StofFl();
-- метод
int firstFilm();
}
class Actor(extent EA)
{
attribute string fio;
attribute int inn;
relationship set <Film> films inverse ... ;
-- атрибут-структура
attribute Struct{string city, string street} addr;
}
Запросы на OQL
Связь М-М, все актеры, которые снимались в фильме:
SELECT a.fio
FROM EF f, f.acts a
WHERE f.title="Иванов" AND f.year < 1950
SELECT a.fio, a.addr
FROM EA a
WHERE for all f in a.films : f.st.sname="Мосфильм"
Коллекция - элемент, множество связанных объектов и вложенный подзапрос. Пример с группировкой:
4 SELECT st, y , sumlen: sum(SELECT P.f.len FROM PARTITION P)
1 FROM ES st, st.fms F
2 WHERE f.year>2000
3 GROUP BY st:st.name, y:f.year
PARTITION - результат группировки, коллекция всех объектов, которые попали в отдельную группу. Здесь st и f. WHERE работает до группировки. HAVING накладывает ограничения на группы. Если он есть, то выполняется 4-ым шагом ( до SELECT'а).
HAVING MIN(SELECT p.f.len FROM PARTITION P)>60.
Сортировка:
ORDER BY ASC st, year
Агрегаты
COUNT() - Для любых
MIN() - для подлежащих сортировке
SUM() - только для числовых
AVG() - только для числовых
MAX() - для подлежащих сортировке
Можно применять к коллекции:
COUNT(EF) - кол-во элементов в экстенте.
Поддерживаются кванторы:
SELECT a
FROM EA a
WHERE FOR ALL F IN a.films:F.st.name="ЛенФильм" AND f.year=2016
FOR ALL IN - квантор всеобщности
SELECT a
FROM EA a
WHERE EXISTS f1 IN a.films:f.yaer<2000
Запрос на единственность:
SELECT s
FROM ES s
WHERE COUNT(s.fms)=1
Те студии, которые сняли только один фильм.
По умолчанию возвращается мультимножество структур.
SELECT a.fio, f.year
Bag<struct{struct{f, i, o}, integer year}>
Если хочется SET:
SELECT DISTINCT
Если хочется LIST:
ORDER BY
Можно и свою коллекцию:
SELECT struct(fam:a.fio.f, yearMade:f.year)
Если поле одно, то структура не формируется.
(SELECT a
FROM EA a, a.films f
WHERE f.stud.name="МосФильм")
EXCEPT
(SELECT a
FROM EA a, EF f
WHERE f.stud.name="Экран")
Аналогично можно с UNION и INTERSECT