Оновлення даних. Оператор UPDATE

Визначення запиту

Запит– це засіб відшукання записів, перетворення таблиць і створення на їхній основі нових таблиць. На відміну від фільтра запит поміщається на закладку Запитиголовного вікна БД. Інструментарієм для створення запиту є конструктор запитів. В вікні конструктора запитів можна створити запит і модифікувати існуючий.

2. Типи запитів

Розрізняють декілька типів запитів:

1. Запит на вибірку. Цей тип запиту здійснює вибірку даних, які задовольняють певним умовам і відображає на екрані вибрані з БД записи. Цей запит не змінюють таблиці БД.

2. Запит на зміну. Запити призначені для доповнення, оновлення, вилучення записів, а також для створення нової таблиці, що міситиме вибрані записи, внесення змін у таблиці. Є 4 підтипів запитів на зміну:

Запит на обновлення. Дозволяє обновити записи для групи однієї або кількох таблиць, наприклад поміняти ціни на певні товари.

Запит на додавання. Результати виконання запиту додаються в кінець однієї, або кількох таблиць. Наприклад, прийняті студенти додаються до загального списку всіх студентів.

Запит на видалення. Викидаються записи по певному критерію з однієї, або декількох таблиць. Можна викинути товари постачальника, з яким розірвано контракт на поставку.

Запит на створення таблиці. Запити результатуючого набору стають основою для створення нової таблиці, структуру якої визначає структура запиту. Такі запити використовуються для резервного копіювання таблиць і експорту даних в інші бази.

3. Запити з параметрами:Це інтерактивний тип запиту, який виводить на екран інформацію про введення ряду параметрів, наприклад умову відбору записів по певному полю. Тому запит допускає модифікацію при кожному запуску, що дає змогу міняти умови звітів так т.д. Запити з параметрами використовуються для запитів на вибірку і запитів на зміну.

Є ще перехресний запит, :результат роботи якого нагадує зведену електронну таблицю; на виявлення записів, що повторюються; на виявлення записів, що не мають підпорядкованих записів у деякій іншій таблиці

3. Створення запитів

Запит створюють вручну в режимі конструктора або за допомогою майстра запиту на базі деякої таблиці чи декількох таблиць , яку/які додають до запиту. Щоб створити запит вручну, треба виконати таку послідовність команд, стартуючи з головного вікна бази даних:

Вікно БД→ Запит → Створити → Конструктор → ОК → Додають таблицю, наприклад, Оцінки → Закривають вікно Додати таблицю.

Отримують вікно (бланк) конструктора запитів, яке потрібно буде заповнити Конструювання запитів складається з декількох етапів.

1. Рядок Поле міситиме назву полів, які користувач хоче відобразити у запиті. Щоб заповнити цей рядок, у вікні таблиці Оцінки вибирають усі чи потрібні поля і перетягують їх у рядок ПОЛЕ. Інший спосіб: рядок ПОЛЕ заповнюють, клацнувши у ньому і вибравши назву кожного поля з запропонованого списку.

2. Задають, якщо потрібно, режим упорядкування записів (методом вибору режиму і запису) і режим відображення полів на екранів.

3. Вводять умови пошуку в рядок умов.

4. Щоб записати запит на виконання, виконують команди Запит → Запуск чи натискають на кнопку запуск, (знак оклику (!)).

5. Для редагування запиту треба повернути в режим конструктора.

6. У разі потреби змінюють тип запиту командою з меню Запит → Вибирають потрібний тип з запропонованого списку.

7. Готовий запит зберігають з деякою назвою у файлі БД.

Загальна схема роботи з запитами на внесення змін:

- виконують звичайний запит на вибірку записів;

- змінюють тип запиту, наприклад, на створення нової таблиці;

- запускають запит на виконання –створення нової таблиці з відібраними

записами.

У конструкторах запитів умови вводять у рядок умов. Умови, які стосується різних полів і мають сполучник (логічну операцію) "і", записують в одному рядку конструктора умов. Умови, які стосуються одного поля і мають сполучник “або”, розташовують одну під одною.

Контрольні запитання

1. Що таке запит?

2. Як в базі даних відшукати потрібні записи?

3. Які засоби створення запитів ви знаєте?

4. Що таке простий запит на вибірку?

5. Чи можна модифікувати раніше створені запити?

6. Назвіть типи запитів?

7. Чи змінює таблицю запит на вибірку?

8. Перерахуйте запити призначені для зміни таблиць?

9. Як створити запит в режимі конструктора запитів?

Лекція № 5

Тема 5.1.Елементи мови структурованих запитів SQL

План:

1. Історія мови SQL та огляд її можливостей

2. Засоби пошуку даних

3. Умови вибирання даних

4. Вирази, умови та оператори

1. Історія мови SQL та огляд її можливостей

Історія SQL починається з 70-х років XX століття, коли в дослідницькій лабораторії IBM у штаті Каліфорнія було розроблено першу версію цієї мови. Назва SQL є абревіатурою від Structured Query Language (структурована мова запитів), й іноді її вимовляють як «sequel» (первісна назва). Спочатку ця мова була реалізована в реляційній СУБД DB2 виробництва IBM. На відміну від мов третього покоління (COBOL, С), які з'явилися в той самий час, мова SQL не є процедурною. Непроцедурна мова — це мова, в якій описується, що потрібно одержати, а не як це зробити.

Особливість реляційних СУБД полягає у тому, що вони надають множинно-орієнтовану мову маніпулювання базами даних, тобто результатом дії мовного оператора є таблиця, яка містить множину даних. Більшість сучасних реляційних СУБД використовують саме мову SQL.

Американський інститут національних стандартів (American National Standards Institute - ANSI) та Міжнародна організація стандартів (International Standards Organization — ISO) займаються описом і підтримкою стандартів цієї мови. Усі сучасні СУБД підтримують певний стандарт, проте є й відхилення, які в кожному конкретному випадку специфікуються в документації програмного продукту.

SQL надає такі можливості:

- створювати й видаляти таблиці бази даних, а також змінювати заголовки таблиць;

- вставляти, змінювати й видаляти рядки в таблицях;

- виконувати пошук даних у багатьох таблицях та впорядковувати результати цього пошуку;

- описувати процедури підтримки цілісності;

- визначати та змінювати інформацію про захист даних.

Керуючись стандартами ANSI-92 та ANSI-99, розглянемо можливості SQL на прикладах. Усі запити конструюються для бази даних:

ФАКУЛЬТЕТ(#F, Назва. Декан, Корпус, Фонд)

КАФЕДРА(#D, #F. Назва, ЗАВІДУВАЧ. Корпус, Фонд)

ВИКЛАДАЧ(#Т, # D, Прізвище, Посада. Тел)

ГРУПА(#G, #D, Курс, Номер, Кількість, #КУРАТ0Р)

ПРЕДМЕТ(#$, Назва)

АУДИТОРІЯ(#R, Номер, Корпус, Місткість)

ЛЕКЦІЯ (#Т, #G. #$, #R, Тип, День. Тиждень)

Для введення SQL-запиту необхідно:

1. Запусттити програму для опрацювання бази даних Access.

2. Виконати команду: Вікно БД → Запит → Створити → Конструктор → ОК → Додати потрібні таблиці Закрити вікно Додати таблицю.

3. Виконати команду Вид-Режим SQL. В вікно ввести запит на мові SQL.

4. Виконати команду Запит-Запуск запиту.

2. Засоби пошуку даних

Вибирання даних. Основна конструкція для вибирання даних, складається з фраз SELECT і FROM. Фраза FROM вказує, з якої таблиці потрібно вибрати дані, а фраза SELECT - які саме атрибути (стовпці) з цієї таблиці мають бути вибрані. Запит

SELECT Назва (поле)

FROM ФАКУЛЬТЕТ (таблиця)

здійснює виведення назв факультетів. Ці дві фрази обов'язково мають бути в будь-якому запиті.

Виведення окремих стовпців. У фразі SELECT можна зазначати список імен стовпців. Передбачається, що результат виведення буде впорядкований за стовпцями відповідно до того, як розташовані імена у фразі:

SELECT Номер, Курс, Кількість

FROM ГРУПА

Виведення всіх стовпців.Якщо необхідно вивести всі стовпці таблиці, то у фразі SELECT використовується символ *:

SELECT *

FROM КАФЕДРА

Неповторювані рядки. У SQL за замовчуванням встановлено, що всі дублікати рядків у таблиці-результаті виводяться. Щоб внаслідок виконання запиту одержати унікальні (неповторювані) значення, потрібно використовувати модифікатор DISTINCT (за замовчуванням застосовується модифікатор ALL). Наприклад, щоб отримати список усіх типів лекцій, і щоб кожен тип виводився лише один раз, потрібно записати:

SELECT DISTINCT Тип(лекції)

FROM ЛЕКЦІЯ

Без модифікатора DISTINCT ми одержали б список із кількох сотень рядків (його довжина дорівнювала б кількості всіх лекцій). Весь запит можна розмістити в одному рядку.

Перевизначення імен стовпців. Фраза SELECT надає можливість перевизначити імена стовпців кінцевої таблиці. Для цього після імені стовпця вихідної таблиці необхідно зазначити ім'я стовпця кінцевої таблиці (з використанням необов'язкової фрази AS). Наприклад, у наведеному запиті перевизначаються імена обох стовпців:

SELECT Назва AS Назва_факультету, Декан AS Декан_факультету

FROM ФАКУЛЬТЕТ

3. Умови вибирання даних

Умова вибирання. Для умови вибирання запису використовується фраза WHERE. У ній зазначено, якій умові мають відповідати вихідні дані. Алгоритм обробки запиту з фразою WHERE:

- вибрати рядок із таблиці;

- перевірити його відповідність вказаній умові;

- якщо рядок відповідає умові, то вивести значення стовпців, вказаних у фразі SELECT.

Цей запит виводить список усіх професорів вузу:

SELECT Прізвище

FROM ВИКЛАДАЧ

WHERE Посада = "професор"

4. Вирази,умови та оператори

У мові SQL існує багато різновидів виразів, у яких використовуються дані різних типів — рядки, числа, логічні значення.

Умова — це вираз, що повертає логічне значення — TRUE чи FALSE. Умовні вирази обов'язково використовуються у фразі WHERE. Прикладом умовного виразу є конструкція Посада = <професор>.

Оператори — це конструкції, що використовуються у виразах для означення певних дій над даними. Є кілька типів операторів:

- арифметичні, +, -,*,/.

- оператори над рядками, Оператор зчеплення рядків ||.

- логічні, AND, OR, NOT

- теоретико-множинні, UNION, INTERSECT, EXCEPT (або MINUS).

- оператори порівняння, >, <, =, <>, >=, <=.

Оператори порівняння, їхнє призначення та приклади використання наведені в табл. 1.

Таблиця 1.Оператори порівняння

оператор призначення Приклад
= Перевірка на рівність SELECT * FROM КАФЕДРА WHERE Фонд = 1500
!=, <> Перевірка на нерівність SELECT * FROM КАФЕДРА WHERE Фонд != 1500
>, < Перевірка, чи одне значення більше або менше іншого SELECT * FROM КАФЕДРА WHERE Фонд > 1500 SELECT * FROM КАФЕДРА WHERE Фонд < 1500
>=, <= Перевірка, чи одне значення не менше або не більше іншого SELECT * FROM ФАКУЛЬТЕТ WHERE Фонд >= 1500 SELECT * FROM ФАКУЛЬТЕТ WHERE Фонд <= 1500
IN Перевірка на належність множині 1. SELECT * FROM ВИКЛАДАЧ WHERE Посада IN ("професор","доцент") 2. SELECT * FROM ВИКЛАДАЧ WHERE ПосадаIN (SELECT ПосадаFROM ВИКЛАДАЧWHERE Тел ="5261815")
NOT IN Еквівалентний !=ALL. Перевірка на неналежність елементу множині 1. SELECT * FROM ВИКЛАДАЧ WHERE ПосадаNOT IN (SELECT ПосадаFROM ВИКЛАДАЧWHERE Тел =”23456”)
ANY,SOME Використовуються разом із предикатом =, !=, >,<,>=<<= Перевіряють, чи істинний цей предикат хоча б для одного елементу множини, заданої у правій частині оператора, відносно елементу, заданого в лівій частині SELECT * FROM ФАКУЛЬТЕТ WHERE Фонд =ANY (SELECT Фонд FROM ФАКУЛЬТЕТ WHERE Корпус = 7)
ALL Використовується разом з предикатом =, ! ~ >, <, <= або >=. Перевіряє, чи істинний цей Предикат для всіх елементів МНОЖИНИ, заданої у правій частиш оператора, відносно елементу заданого в лівій частині SELECT * FROM ФАКУЛЬТЕТ WHERE Фонд >= ALL(1400,3000)
EXISTS Повертає TRUE, якщо підзапит, до якого застосовується оператор, містить хоча б один рядок SELECT Назва FROM Факультет WHERE EXISTS (SELECT * FROM Кафедра WHERE Кафедра.#F = Факультет. #F)
IS Перевірка на рівність значенню NULL SELECT Назва FROM Кафедра WHERE Фонд IS NULL

Розглянемо на прикладах використання цих операторів.

Запит . 1. Визначити назву групи, де кількість студентів становить від 20 до 25 осіб, а також прізвища кураторів, які їм відповідають.

Таблиця ГРУПА

Кодгрупи НаваГрупи ЧислоСтудентів Куратор
Лічильник Текстовий, 5 Числовий Текстовий, 30

SELECT НазваГрупи, Куратор

FROM

WHERE ЧислоСтудентів >= 20 AND ЧислоСтудентів <= 25

Запит 2. Визначити прізвища викладачів математики або фізики

Таблиця Дисципліни

КодДисципліни НазваДисципліни ПрізВикладача ІмяПобатькові
Лічильник Текстовий, 10 Текстовий, 15 Текстовий, 20

SELECT ПрізВикладача

FROM Дисципліни

WHERE НазваДисципліни= “математика” OR НазваДисципліни= “фізика”

Тема 5.2.Засоби маніпулювання даними

Розглянемо, в який спосіб дані можна вводити до БД,редагувати та видаляти. Мова йтиме про оператори SQL, що дають змогу маніпулювати даними: INSERT, UPDATEі DELETE.

5.1 Додавання рядків до таблиці. Оператор INSERT

Оператор INSERT дає змогу вводити дані до БД. Є два різновиди цього оператора:

- INSERT. INTO..VALUES

- INSERT.. INTO ….SELECT

Оператор INSERT...VALUESдає можливість додати до таблиці один рядок і має формат:

INSERT INTO <ім'я таблиці> (<поле 1> [, <поле 2>]...) VALUES (<значення 1> [, <значення 2>]....)

Виконання цього оператора потребує дотримання певних правил:

- типи даних, що вставляються, мають узгоджуватися з типами даних відповідних стовпців;

- розміри даних мають відповідати розмірам стовпців;

- порядок даних у фразі VALUES має відповідати порядку стовпців у фразі INSERT INTO.

Запит 37. Додати рядок до таблиці ФАКУЛЬТЕТ.

INSERT INTO ФАКУЛЬТЕТ (#F. Назва. Декан, Корпус, Фонд)

VALUES (15, "інформатики", "Сидоров", 5, 25000)

Список імен стовпців не є обов'язковим, якщо вставляються значення всіх стовпців. У цьому випадку порядок запису значень має збігатися з порядком стовпців у таблиці.

Запит 39. Додати рядок до таблиці ВИКЛАДАЧ.

INSERT INTO ВИКЛАДАЧ

VALUES (173, 13, "Резніченко", NULL, "526-18-15")

Оператор INSERT.. .SELECT

Оператор INSERT.. .SELECT дає змогу додати до таблиці множину рядків (результат виконання запиту) і, таким чином, дозволяє копіювати інформацію з однієї чи кількох таблиць до іншої. Часто за, допомогою оператора INSЕRT-.SELЕСТ дані копіюються до похідних таблиць, що створюються з метою підвищення продуктивності виконання тих чи інших операцій над базою даних. Оператор має формат:

INSERT INTO <ім'я таблиці> (<список полів>)

SELECT <список полів>

FROМ <ім'я таблиці>

WHERE <умова пошуку>

Вихідні результати стандартного оператора SELECT є вхідними даними для оператора INSERT.

Запит 40 Додати до таблиці ТИМЧАСОВА, що має стовпці Назва_факультету, Назва_кафедри, Прізвище__викладача, наявні в базі даних відомості про викладачів, а також про кафедри та факультети, де вони працюють.

INSERT INTO ТИМЧАСОВА (Назва^факультету, Назва_кафедри, Прізаище_викладача)

SELECT ФАКУЛЬТЕТ.Назва, КАФЕДРА.Назва, ВИКЛАДАЧ.Прізвище

FROМ ФАКУЛЬТЕТ, КАФЕДРА, ВИКЛАДАЧ

WHERE ФАКУЛЬТЕТ.#F = КАФЕДРА.#F AND

КАФЕДРА.#D = ВИКЛАДАЧ.#D

Для оператора INSERT...SELECT мають виконуватися правила:

- оператор SELECT не може вибирати рядок із таблиці, до якої здійснюється додавання;

- кількість стовпців у фразі INSERT INTO має збігатися з кількістю стовпців у фразі SELECT;

- типи даних стовпців у фразі INSERT INTO мають збігатися з типами даних стовпців у фразі SELECT.

Оновлення даних. Оператор UPDATE

Оператор UPDATE змінює значення у наявних рядках. Його синтаксис:

UPDATE <і м'я таблиці>

SET <поле 1> = <вираз 1>

[. <поле 2> = <вираз 2>]...

[WHERE <умова пошуку>]

Оновлення за умовою.Усі рядки таблиці, які задовольняють задану у фразі WHERE умову, змінюються згідно з фразою SET.

Запит 41. Встановити фонд факультету інформатики рівним 250 300.

UPDATE ФАКУЛЬТЕТ

.SET.. : Фонд = 250300

WHERE Назва ="інформатики"

Запит 41. Встановити оцінку з фізики 5 студенту з кодом 10

UPDATE Успішність

.SET.. : Фізика = 5, хімія =4

WHERE Код студента =10

Безумовне оновлення.Якщо фразу WHERE не задано, то оновлюються всі рядки.

Запит 42. Встановити фонд усіх факультетів рівним 260 500.

UPDATE ФАКУЛЬТЕТ

SET Фонд =26050

Запит 41. Встановити оцінку з фізики 5 всім студентам

UPDATE Успішність

.SET.. : Фізика = 5, хімія =4

WHERE Код студента =10

Неконстантне оновлення.Стовпцю може присвоюватися не константа, а вираз, що обчислюється на поточному рядку.

Запит 43. Збільшити всім студентам оцінку на 1 бал

UPDATE ФАКУЛЬТЕТ

SET хімія = хімія+1

Запит 44. Збільшити кафедрам факультету інформатики фонд на 5 %.

UPDATE КАФЕДРА

SET Фонд = Фонд + Фонд/20

WHERE #F IN (SELECT #F

FROM ФАКУЛЬТЕТ

WHERE . ФАКУЛЬТЕТ.Назва - "інформатики")

5.4 Видалення рядків таблиці. Оператор DELETE

Оператор DELETE дає змогу видаляти рядки таблиці й має синтаксис:

DELETE FROM <ім'я таблиці> [WHERE умова]

Залежно від наявності та змісту фрази WHERE можна видалити

- один рядок,

- множину рядків,

- усі рядки

- не видалити жодного.

Особливості використання оператора DELETE.

Оператор не дає змоги видаляти окремі поля а видаляє рядок повністю.

Застосування оператора DELETE, як і INSERT та UPDATE, може призвести до порушення цілісності бази даних.

Якщо у фразі WHERE використовується вкладений підзапит, то у фразі FROM цього підзапиту не можна зазначати таблицю, з якої видаляються рядки. Це стосується також операторів INSERT та UPDATE.

Оператор видаляє лише рядки таблиці, а не саму таблицю. Для видалення всієї таблиці слід застосувати оператор DROP TABLE. Наведемо приклади.

Запит 45 Видалити відомості про лекції, що читаються в суботу та неділю.

DELETE FROM ЛЕКЦІЯ

WHERE День IN ("субота"."неділя")

Запит 46 Видалити всі рядки з реляційного відношення ПРЕДМЕТ,

DELETE FROM ПРЕДМЕТ

Запит 47. Видалити з таблиці ПРЕДМЕТ ті предмети, з яких не читається лекцій.

DELETE FROM ПРЕДМЕТ

WHERE #S !=ALL (SELECT #S

FROM ЛЕКЦІЯ)

Створення бази даних.

Для створення бази даних використовується оператор CREATE DATABASE

Універсальним способом створення бази даних є застосування операторів SQL. Синтаксис типового оператора створення бази даних:

CREATE DATABASE <ім'я бази даних >

Оператор CREATE DATABASE дає змогу виконати такі дії:

- делегувати повноваження на створення бази даних тому чи іншому користувачу;

- визначити місце (диск, каталог), де розташовуватиметься база даних;

- зарезервувати певний обсяг дискового простору для подальшого зберігання рядків таблиць та іншої інформації.

5.6 Створення таблиці. Оператор CREATE TABLE.

Синтаксис оператора:

CREATE TABLE <ім'я таблиці >

(<поле 1> <тип даних 1> [ NOT NULL ]

[, <поле 2> <тип даних 2> [ NOT NULL]]...)

Після ключових слів CREATE TABLE задаються ім'я таблиці та імена стовпців з типами даних і деякими іншими характеристиками. Специфікатор NOT NULL забороняє введення у стовпець NULL- значень і застосовується зокрема до ключових полів.

Запит 43.Створити таблицю ФАКУЛЬТЕТ

CREATE TABLE ФАКУЛЬТЕТ (#F NUMBER (10),

Назва CHAR(50) NOT NULL,

Декан CHAR(25).

Корпус CHAR(5),

Фонд NUMBER(6.2))

Створення таблиці на базі існуючої.Для створення таблиць використовують команду CREATE TABLE. Синтаксис команди:

CREATE TABLE <нова таблиця>(<список полі в>)

AS (SELECT <список полі в>

FROM <стара таблиця >

[WHERE...])

Ця команда дає змогу створити нову таблицю з типами даних полів наявної таблиці та за необхідності перейменувати поля.

5.7 Типи полів

Byte числовий 1 байт

Integer довге ціле

Single одиничне з плаваючою комою

NUMBER Двойное с плавающей точкой

Double Двойное с плавающей точкой

Date дата час

Currency грошовий

Memo

5.8 Модифікація таблиці. ОператорALTER TABLE.

Можливі ситуації, коли вже створена таблиця не відповідає зміненим вимогам до бази даних. Команда ALTER TABLE дає змогу змінити структуру таблиці після її створення: додати до вже визначеної таблиці стовпець або змінити наявний.

Синтаксис команди:

ALTER TABLE <ім'я таблиці>

[ADD <поле> <означення поля>|

ALTER <поле> <параметри>|

DROP <поле> <параметри>]

5.9 . Видалення таблиці. ОператорDROP TABLE

У SQL є команда, призначена для видалення з бази даних усієї таблиці. Оператор DROP TABLE видаляє таблицю з усіма зв'язаними з нею віртуальними таблицями й індексами. Найчастіше він застосовується до тимчасових таблиць, які видаляються через певний час після створення. Синтаксис команди:

DROP TABLE <ім'я таблиці>

Видалення бази даних. ОператорDROP DATABASE. Команда DROP DATABASE застосовується для видалення всієї бази даних і має синтаксис:

DROP DATABASE <ім'я бази даних>

Контрольні запитання та завдання

1. Які можливості надає мова SQL?

2. Як можна вивести всі стовпці таблиці?

3. Що вказує фраза SELECT?

4. Що вказує фраза FROM?

5. Наявність яких фраз обов’язкові в SQL-запиті?

6. Для чого використовується модифікатор DISTINCT у фразі SELECT?

Список рекомендованої літератури

1. Вербовецкий А.А. Основы проектирования баз даннях. М. Радио и Свіязь, 2000. – 88 с.

2. Вудкок Дж., Янг М. Ефективна робота з Microsoft Office 95. - М.: Microsoft Access, 2002. - 1000с.

3. Горєв А., Макашарипов С., Ахаян Р. Ефективна робота із СУБД. - Спб.: Питер, 1997. - 704с.

4. Гофман В. Э., Хоменко А.Д. Работа с базами данных в Delphi 5 – СПб.: БХВ – Петербург, 2000. – 656 с

5. Дженнингс Р.: - MS ACCESS 97. - Спб.: Петер, 1998. - 232с.

6. Курносов А.С., Мироненко В.Л. Робота в СУБД MS ACCESS. - Краснодар: Кубгау, 2003. - 46с.

7. Томас Коннолли, Каролин Бегг, Анна Страчан, Базы данных: проектирование, реализация и сопровождение, издательский дом "Вильямс", 2001.-1120 с.

8. . Хоменко А.Д. и др. Базы данных. Учебник для ВУЗов. Под редакцией А.Д.Хоменко. Санкт-Петербург, изд. Корона Принт. 2002, 666с.

Наши рекомендации