Вы находитесь на странице: 1из 142

«АВТОМАТИЗАЦИЯ

ПРОЕКТИРОВАНИЯ БД.
СОЗДАНИЕ БАЗЫ
ДАННЫХ В СУБД MS SQL
SERVER
ПРАКТИКУМ для лабораторных
работ по дисциплине «Системы баз
данных»
Оглавление

Лабораторная работа № 1. Проектирование базы данных в CASE- средстве


ERWin .......................................................................................................................... 5
Теоретические сведения ............................................................................................. 5
Переход от логической модели данных к физической модели .............................. 8
Практические задания ................................................................................................. 9
Задание 1. Создание сущностей в ERwin.................................................................. 9
Задание 2. Создание связей между сущностями. Переход к физической модели
данных ........................................................................................................................ 12
Задание 3. Выполнение операции прямого проектирования ................................ 22
Задание 4. Выполнение операции обратного проектирования ............................ 23
Задания для самостоятельного выполнения ........................................................... 25
Задание 1. Операция прямого проектирования ...................................................... 25
Задание 2. Операция обратного проектирования .................................................. 26

Лабораторная работа № 2. Создание БД в среде СУБД MS SQL Server ..... 28


Теоретические сведения ........................................................................................... 28
Практические задания ............................................................................................... 31
Задание 1. Запуск утилиты SQL Server Management Studio.................................. 31
Задание 2. Создание базы данных ........................................................................... 32
Задание 3. Создание таблиц базы данных .............................................................. 34
Задание 4. Создание связей между таблицами базы данных ................................ 41
Задание 5. Заполнение таблиц базы данных и создание представлений............. 43
Задание 6. Отсоединение от сервера и подключение базы данных ..................... 44

Лабораторная работа № 3. Создание базы данных и ее объектов с помощью


команд языка Transact-SQL.................................................................................. 46
Теоретические сведения ........................................................................................... 46
Создание базы данных и ее объектов с помощью команд языка Transact-SQL . 46
Практические задания ............................................................................................... 47
Задание 1. Создание новой базы данных с помощью команд языка Transact-SQL

1
..................................................................................................................................... 47
Задание 2. Создание таблиц и индексов базы данных с помощью команд языка
Transact-SQL .............................................................................................................. 47
Задание 3. Сохранение сценария. Создание базы данных с помощью сценария49
Задание 4. Подготовка базы данных для ввода данных ........................................ 50
Задание 5. Ввод данных в таблицы базы данных посредством запросов на языке
SQL.............................................................................................................................. 50
Задание 6. Создание представления базы данных ................................................. 53
Задание 7. Анализ полученных результатов .......................................................... 54

Лабораторная работа № 4. Выборка и манипулирование данными с


помощью команд языка SQL ................................................................................ 56
Подготовительные действия .................................................................................... 56
Практические задания ............................................................................................... 56
Задание 1. Выборка данных из таблиц и представлений. Оператор SELECT .... 56
Задание 2. Выборка системных данных .................................................................. 61
Задание 3. Обновление данных в таблицах и представлениях ............................. 62
Задание 4. Удаление данных из таблиц и представлений ..................................... 62
Задание 5. Изменение структуры таблицы ............................................................. 62
Задание 6. Удаление таблицы из базы данных ...................................................... 64
Задания для самостоятельного выполнения ........................................................... 64
Задание 7. Создание новых таблиц.......................................................................... 65
Задание 8. Выборка данных из таблиц и представлений ...................................... 68
Задание 9. Обновление данных в таблицах ............................................................ 70
Задание10. Удаление данных из таблиц ................................................................. 70
Задание 11. Изменение структуры таблиц и представлений ................................ 71
Задание 12. Удаления таблиц из базы данных ....................................................... 71

Лабораторная работа № 5. Разработка запросов с подзапросами, Case-


выражения, табличные выражения .................................................................... 73
Подготовительные действия .................................................................................... 73
Практические задания ............................................................................................... 73
Задание 1. Разработка запросов с подзапросами ................................................... 73
2
Задание 2. Разработка запросов с выражением CASE........................................... 77
Задание 3. Разработка запросов с табличными выражениями ............................. 79
Задания для самостоятельного выполнения ........................................................... 80
Задание 4. Разработка запросов с подзапросами ................................................... 80
Задание 5. Разработка запросов с выражением CASE ............................................ 81
Задание 6. Разработка запросов с табличными выражениями ......................... 81

Лабораторная работа № 6. Программирование на языке Transact-SQL..... 82


Подготовительные действия .................................................................................... 82

Основы программирования на языке Transact-SQL ....................................... 82


Задание 1. Работа с переменные в языке Transact-SQL......................................... 82
Задание 2. Работа с временными таблицами в языке Transact-SQL .................... 86
Задание 3. Создание и работа с хранимыми (на сервере) процедурами ............. 87
Задание 4. Изменение существующей хранимой процедуры ............................... 94
Задание 5. Удаление хранимой процедуры ............................................................ 95
Создание и работа с определяемыми пользователем функциями ....................... 95
Задание 6. Создание функции типа Scalar .............................................................. 96
Задание 7. Создание функции типа Inline Table-valued......................................... 97
Задание 8. Создание функции типа Multi-statement Table-valued ........................ 98
Задания для самостоятельного выполнения ......................................................... 101
Задание 9. Разработка хранимой процедуры pr_GreatestDemandProduct .......... 101
Задание 10. Разработка хранимой процедуры pr_ClientsSuppliers_CountryInterval
................................................................................................................................... 101
Задание 11. Разработка пользовательской функции fn_getOnlyDate ................. 101
Задание 12. Разработка пользовательской функции fn_getFullName ................ 101
Задание 13. Разработка пользовательской функции
fn_getGroup_ProductNameCurrency........................................................................ 102
Задание 14. Разработка пользовательской функции fn_getCost_BYN .............. 102

Лабораторная работа № 7. Разработка курсоров и триггеров ..................... 104


Подготовительные действия .................................................................................. 104
Теоретические сведения ......................................................................................... 104

3
Использование курсоров и триггеров в языке Transact-SQL.............................. 104
Задание 1. Работа с курсорами в языке Transact-SQL ......................................... 107
Задание 2. Разработка триггеров в языке Transact-SQL ...................................... 109
Задания для самостоятельного выполнения ......................................................... 118
Задание 3. Разработка хранимой процедуры pr_Cost_CurrencyInterval............. 118
Задание 4. Разработка хранимой процедуры pr_Country_Clients_Suppliers ...... 119
Задание 5. Создание таблицы Protocol .................................................................. 119
Задание 6. Доработка триггера tr_ProductsPrice_AllGoods ................................. 120

Лабораторная работа № 8. Администрирование БД в MS SQL Server ...... 121


Управление пользователями базы данных ........................................................... 121
Теоретические сведения ......................................................................................... 121
Управление пользователями в среде MS SQL Server .......................................... 121
Управление пользователями и правами доступа к данным инструментальными
средствами................................................................................................................ 122
Управление пользователями и правами доступа к данным с помощью команд
языка Transact-SQL ................................................................................................. 133
Задание 1. Создание имени входа на основе учетной записи домена Windows133
Задание 2. Добавление учетной записи в фиксированную роль сервера .......... 134
Задание 3. Добавление нового пользователя в текущую базу данных .............. 134
Задание 4. Создание пользовательской роли ....................................................... 135
Задание 5. Добавление нового члена в роль (как фиксированную, так и
пользовательскую) базы данных ........................................................................... 136
Задание 6. Предоставление прав доступа к объектам базы данных .................. 136
Задание 7. Запрещение доступа к объектам базы данных .................................. 137

Литература.............................................................................................................. 139

4
Лабораторная работа № 1.
Проектирование базы данных в CASE- средстве ERWin

Теоретические сведения
Реляционная модель данных была предложена в 1979 году Эдгаром
Коддом и вскоре получила самое широкое распространение.
Формальный математический аппарат, моделирующий табличное
представление данных, получил название реляционной алгебры, в которой
используются следующие основные понятия (Таблица 1. Основные понятия
реляционной алгебры.Таблица 1).
Таблица 1. Основные понятия реляционной алгебры.
Реляционная алгебра Реляционная база данных
(логическая модель) (физическая модель)
Сущность Таблица
Кортеж Строка (Запись)
Атрибут Столбец (Поле)
Домен Тип данных

Сущность - это объект предметной области, которая исследуется и


моделируется.
Кортеж - это экземпляр объекта предметной области (экземпляр
сущности).
Атрибут отражает определенное свойство, качество, признак сущности.
Домен задает множество допустимых значений атрибута.
Смысл доменов состоит в том, что они определяют набор значений,
допустимых для атрибута, и позволяют правильно моделировать предметную
область. Если атрибуты связаны с одним и тем же доменом, то сравнение
значений этих атрибутов имеет смысл (например, минимальные, средние и
максимальные температуры можно сравнивать между собой; аналогично,
можно сравнивать даты и т д.). Если же атрибуты связаны с различными
доменами, то сравнение значений таких атрибутов чаще всего лишено смысла,
даже если эти значения выбираются из одного и того же множества значений
(имеет ли смысл сравнивать, например, № паспорта с № телефона?).
Моделирование структур данных в рамках реляционной модели
осложняется невозможностью сразу определить полный список сущностей,
связей, атрибутов и определяющих их доменов, а также оптимальный набор
атрибутов и сущностей, поскольку эти структуры в процессе проектирования
могут многократно уточняться и изменяться. Поэтому различают три уровня

5
логической модели, отличающиеся глубиной представления информации о
структуре данных:
• Модель уровня сущностей.
• Модель данных, основанная на ключах.
• Полная атрибутивная модель.
Модель уровня сущностей представляет собой модель данных верхнего
уровня, которая отражает основные бизнес-правила предметной области.
Бизнес-правила - это принятые в организации ограничения, спецификации,
критерии, соглашения по ведению учета и отчетности. Модель этого уровня не
слишком подробна и включает в себя лишь основные сущности и связи между
ними. Как правило, модель уровня сущностей используется для презентаций и
обсуждения структуры данных с экспертами предметной области.
Модель данных, основанная на ключах, является более подробной и
включает в себя все сущности, их первичные ключи, а также связи между
сущностями.
Полная атрибутивная модель дает наиболее детальное представление о
структуре данных и включает все сущности, атрибуты, домены и связи.
Сущности, как правило, приведены к третьей нормальной форме.
Эти разновидности моделей, представленные в графической форме,
называются диаграммами «сущность-связь» или ER-диаграммами (Entity -
сущность, Relationship - связь). Существуют различные варианты ER-
диаграмм, отличающиеся способами графического изображения сущностей и
связей. Первый вариант был предложен Питером Ченом в 1976 г. (нотация
Чена). Затем появились другие варианты (нотация Мартина, нотация IDEF1X,
нотация Баркера и др.).
Впоследствии был создан целый ряд программных средств для
автоматизированного построения ER-диаграмм, например, ERwin, SilverRun,
Design/IDEF, Power Designer и др. Все они относятся к классу CASE-
технологий (Computer-Aided Software Engineering - набор инструментов и
методов программной инженерии для проектирования программного
обеспечения).
Эти CASE-средства удобны тем, что в них процесс выделения сущностей,
связей, а затем и атрибутов, является итерационным (повторяющимся).
Разработав первый приближенный вариант ER-диаграммы, далее его уточняют,
опрашивая экспертов предметной области, после чего все повторяется. При
этом документацией, в которой фиксируются результаты опросов, являются
сами ER-диаграммы. Попутно выполняется нормализация данных. Процесс
заканчивается получением ER-диаграммы, соответствующей полной

6
атрибутивной модели.
Рассмотрим работу с ER-диаграммами в нотации IDEF1X, используемой в
CASE-средстве ERwin. Изучив конкретную предметную область, строим
исходную ER-диаграмму, соответствующую модели уровня сущностей
(Рисунок 1).

Рисунок 1. ER-диаграмма модели уровня сущностей


На Рисунок 1 связи между сущностями обозначены следующим образом:
сильная или идентифицирующая связь типа 1:М;
слабая или неидентифицирующая связь типа 1:М;
связь типа М:М.
В случае связи 1:М (один ко многим) одна из связываемых сущностей
выступает в роли родительской или главной, а другая - в роли дочерней или
подчиненной. Эта связь каждому кортежу родительской сущности ставит в
соответствие любое (в том числе нулевое) число кортежей дочерней сущности,
однако каждый кортеж дочерней сущности может быть связан только с одним
кортежем родительской сущности.
Механизм реализации связи «один ко многим» состоит в том, что в
дочернюю сущность добавляются атрибуты, дублирующие ключевые атрибуты
родительской сущности (т.е. атрибуты, входящие в первичный или
альтернативный ключ). Эти атрибуты получают название внешнего ключа
(Foreign Key, сокращенно FK) и с их помощью устанавливается связь между
кортежами родительской сущности - с одной стороны - и подмножествами
кортежей дочерней сущности - с другой. Еще такие атрибуты называют
мигрирующими из родительской сущности. Если дочерняя сущность является
зависимой от родительской сущности, то мигрирующие атрибуты включаются
в состав первичного ключа дочерней сущности, в противном случае - в состав
ее не ключевых атрибутов.
На уровне логической модели возможны также связи типа М:М (многие ко
многим), которые используются тогда, когда между атрибутами сущностей
существуют многозначные зависимости. Связь такого типа каждому кортежу
одной сущности ставит в соответствие любое (в том числе нулевое) число
кортежей другой сущности и наоборот.

7
Возвращаясь к рассмотрению примера, строим на следующем
итерационном шаге ER-диаграмму, соответствующую модели данных,
основанной на ключах (Рисунок 2).

Клиент размещает Заказ выполняется Сотрудник

Рисунок 2. ER-диаграмма модели, основанной на ключах


Далее, на очередном итерационном шаге, получаем ER-диаграмму,
соответствующую полной атрибутивной модели данных (Рисунок 3).
Клиент Заказ Сотрудник

Рисунок 3. ER-диаграмма полной атрибутивной модели

Переход от логической модели данных к физической модели


Переход от логической модели данных к физической заключается в том,
что сущности преобразуются в таблицы, атрибуты и кортежи становятся
соответственно столбцами и строками таблиц, домены отображаются в типы
данных, принятые в конкретной СУБД. Таблицы, как и сущности, снабжаются
первичными и внешними ключами и связываются между собой с помощью
связей типа 1:1 и 1:М. Связи типа М:М при переходе к физической модели
преобразуются в пары связей типа 1:М и связующие таблицы.
Если логическая модель представлена в виде ER-диаграммы, то переход к
физической модели значительно упрощается. В этом случае с помощью CASE-

8
средства, например, ERWin можно выбрать нужную СУБД и автоматически
создать соответствующую физическую модель данных. Затем на ее основе
ERWin может сгенерировать системный каталог базы данных или
соответствующий SQL-скрипт. Этот процесс называется прямым
проектированием.
Тем самым достигается масштабируемость - создав один раз логическую
модель данных, можно генерировать физические модели данных под любую
СУБД, которую поддерживает ERwin. С другой стороны, ERwin способен по
содержимому системного каталога базы данных или SQL-скрипту воссоздать
физическую и логическую модели данных. Этот процесс называется обратным
проектированием. На основе логической модели, полученной в процессе
обратного проектирования, можно сгенерировать физическую модель и
системный каталог базы данных для другой СУБД. Тем самым решается задача
по переносу структуры базы данных с одной СУБД на другую, например, с SQL
Server на Oracle или с Access на Sybase и т.д.

Практические задания

Задание 1. Создание сущностей в ERwin


Создайте в ERwin новую модель данных с именем Trade. Для этого
выполните команду File – New, откроется окно Create Model – Select Template
(Рисунок 4). Выберите тип модели в группе радиокнопок New Model Type –
Logical/Phisical, целевая база данных Target Database – Access.

Рисунок 4. Создание новой модели в ERWin

9
В качестве шрифта по умолчанию установите любой кириллический
шрифт, например, Arial CYR (команда меню Format - Default Fonts & Colors,
далее вкладки: General и Drawing Object Text).
Логическая модель должна включать в себя шесть приведенных ниже
сущностей.
ПЕРВЫЙ АТРИБУТ В КАЖДОЙ СУЩНОСТИ СДЕЛАЙТЕ
ПЕРВИЧНЫМ КЛЮЧОМ; АТРИБУТЫ, ОТМЕЧЕННЫЕ ОДНОЙ ИЛИ
ДВУМЯ ЗВЕЗДОЧКАМИ, - НЕ СОЗДАВАЙТЕ, ТАК КАК В ДАЛЬНЕЙШЕМ
ОНИ БУДУТ СОЗДАНЫ АВТОМАТИЧЕСКИ В ПРОЦЕССЕ
УСТАНОВЛЕНИЯ СВЯЗЕЙ МЕЖДУ СУЩНОСТЯМИ.
Для новой создания сущности нужно в окне Model Explorer (по умолчанию
справа в окне ERWin) выделить в дереве модели ветвь Сущность (Entity) и
правой кнопкой мыши вызвать пункт контекстного меню New или
воспользоваться кнопкой на панели инструментов Erwin Toolbox (Рисунок 5).
Дайте сущности имя Поставщики (Suppliers).

Кнопка Новая
сущность

Создание новой
сущности через окно
Model Exproler

Рисунок 5. Создание новой сущности в ERWin


После создания сущности добавьте атрибуты, вызвав через контекстное
меню окно Attribute (Рисунок 6).

10
Рисунок 6. Добавление атрибутов в сущность Поставщики (Suppliers)
1. Сущность Поставщики (Suppliers)
Атрибут (Attribute) Домен (Domain) Первичный ключ (Primary Key)
SupplierID Number Да
SupplierName String
PaymentTerms String
Location** Number
Заметки Blob
2. Сущность Товары (Products)
Атрибут (Attribute) Домен (Domain) Первичный ключ (Primary Key)
ProductID Number Да
ProductName String
Measure String
Price Number
Currency** String

3. Сущность Клиенты (Clients)


Атрибут (Attribute) Домен (Domain) Первичный ключ (Primary Key)
ClientID Number Да
ClientName String
HeadFullName String
Location** Number
4. Сущность Заказы (Orders)
Атрибут (Attribute) Домен (Domain) Первичный ключ (Primary Key)
OrderID Number Да

11
ClientID* Number
ProductID* Number
Quantity Number
OrderDate Datetime
DeliveryDate Datetime
Supplier** Number

5. Сущность Регионы (Locations)


Атрибут (Attribute) Домен (Domain) Первичный ключ (Primary Key)
LocationID Number Да
Country String
Region String
City String
Address String
Phone String

6. Сущность Валюта (Currency)


Атрибут (Attribute) Домен (Domain) Первичный ключ (Primary Key)
CurrencyID String Да
CurrencyName String
Rate Number

Каждую сущность снабдите кратким описанием ее назначения (Definition).


Например, для первой сущности это может быть «Список поставщиков
товаров», для второй - «Перечень предлагаемых товаров» и т.д.

Задание 2. Создание связей между сущностями. Переход к


физической модели данных

1. Создайте между сущностями связи типа 1:М (один ко многим) таким


образом, чтобы в результате сущности оказались дополнены атрибутами,
отмеченными выше звездочками.
Связь 1:М между парой сущностей, одна из которых рассматривается как
родительская, а другая - как дочерняя, создается следующим образом: на
панели инструментов нужно нажать одну из двух кнопок создания связи 1:М
(идентифицирующей - Identifying relationship или неидентифицирующей - Non-
identifying relationship), после чего щелкнуть мышью на родительской
сущности, а затем - на дочерней. При этом между сущностями появляется связь
и в дочернюю сущность будет автоматически добавлены атрибуты,
дублирующие ключевые атрибуты родительской сущности.
Эти атрибуты получают название внешнего ключа (FK) и будут включены
в состав ключевых (идентифицирующая связь) или неключевых

12
(неидентифицируюшая связь) атрибутов дочерней сущности. ВЫШЕ В
СУЩНОСТЯХ АТРИБУТЫ ВНЕШНИХ КЛЮЧЕЙ ОТМЕЧЕНЫ
ЗВЕЗДОЧКАМИ, ПРИЧЕМ ОДНА ЗВЕЗДОЧКА УКАЗЫВАЕТ НА
ИДЕНТИФИЦИРУЮЩУЮ СВЯЗЬ 1:М, А ДВЕ - НА
НЕИДЕНТИФИЦИРУЮЩУЮ СВЯЗЬ 1:М.
Например, чтобы в сущности Поставщик (Suppliers) появился атрибут
Location нужно создать неиндефицирующую связь 1:М между родительской
сущностью Регионы (Locations) и дочерней сущностью Поставщик (Suppliers).
2. Создайте между сущностями Поставщик (Suppliers) и Товар (Products)
связь типа М:М (многие ко многим). Эта связь создается следующим образом: на
панели инструментов нужно нажать кнопку создания связи М:М (Many-to-many
relationship), после чего щелкнуть мышью на одной сущности, а затем - на
другой.
3. С помощью команды меню Model - Relationships откройте окно
Relationships и дайте имена связям, используя для этого подходящие глаголы
или глагольные формы. Для связей 1:М достаточно указать имя,
характеризующее отношение или от родительской сущности к дочерней
(Parent-to-Child) или от дочерней сущности к родительской (Child-to-Parent).
Для связи М:М следует указывать имена как Parent-to-Child так и Child-to-Parent.
Например, для связи типа М:М между сущностями Поставщик (Suppliers) и
Товар (Products) можно дать такие имена: Поставляет (Delivers) для отношения
родительской сущности к дочерней (Parent-to-Child) и Поставляется (Is
Delivered) для отношения дочерней сущности к родительской (Child-to-Parent)
(Рисунок 7).

Рисунок 7. Определение имен для связи типа многие-ко-многим.

13
4. Измените заданное по умолчанию правило ссылочной целостности
RESTRICT (Ограничить) на правило CASCADE (Каскадировать) для двух
связей: связи между сущностями Клиент (Clients) и Заказ (Orders) и связи
между сущностями Товар (Products) и Заказ (Orders). Для этого в окне
Relationships перейдите на вкладку RI Actions (Referential Integrity), выберите
вверху с помощью выпадающего списка Relationship нужную связь и далее
поменяйте правило RESTRICT на правило CASCADE в каждом из списков:
Parent Insert и Parent Update (Рисунок 8).

Рисунок 8. Создание правил ссылочной целостности


5. С помощью команды меню Models - Subject Areas… откройте окно
Subject Areas (Рисунок 9) и создайте помимо существующего основного
множества Main Subject Area еще два подмножества модели: SubjectArea1 и
SubjectArea2, включив (вкладка Members) в первое из них сущности Клиент
(Clients), Поставщик (Suppliers), Регион (Locations), а во второе – сущность
Товар (Products) со всеми непосредственно связанными с ней (Level = 1)
сущностями. Просмотрите поочередно все три модели, используя для
переключения между ними кнопку с выпадающим списком Create Subject Area,
расположенную вверху окна Subject Area (обычно наложено на окно Model
Explorer).

14
Рисунок 9. Создание предметных областей
6. С помощью команды меню Formats - Stored Display Settings…
откройте окно Stored Displays и создайте для каждого из подмножеств модели
SubjectArea1 и Subject Area2 по два новых хранимых отображения (Display2 и
Display3), отличающиеся друг от друга и от исходного отображения Display1
расположением частей модели на экране, масштабом, уровнями просмотра
модели, видимостью отдельных компонентов сущностей и связей, а также
другими характеристиками (Рисунок 10).

15
Переключение
между Subject Areas

Рисунок 10. Окна хранимых отображений

7. Переключитесь на Main Subject Area / Display 1, а затем с помощью


команды меню Model - Relationships откройте окно Relationships и опробуйте
настройку характеристик связей между сущностями (Рисунок 11), таких как
имя связи Verb Phrase, мощность Cardinality, имя роли RoleName, правила
ссылочной целостности RI Actions. Опробуйте режимы показа на диаграмме
указанных выше характеристик связей с помощью команд меню: Formats -
Relationship Display -... В конце восстановите первоначальные настройки
характеристик связей между сущностями.

Рисунок 11. Типы связей

16
8. С помощью команды меню Model - Domain Dictionary откройте окно
Domain Dictionary (Рисунок 12) и создайте на основе домена Number новый
домен Денежный. Далее свяжите атрибут Price с новым доменом Денежный.

Рисунок 12. Настройка доменов

17
9. С помощью команды меню Model - Attributes откройте окно Attributes,
перейдите на вкладку Key Group и, используя кнопку с тремя точками, а затем
кнопку New, создайте для сущностей возможные альтернативные ключи
Alternate Key и возможные инверсионные входы Inversion Entry. Включите
режим их отображения на диаграмме Format – Entity Display – Alternative Key
Designation...(Рисунок 13)

Рисунок 13. Создание альтернативного ключа для сущности Валюта


(Currency)
После выполнения всех заданий должна получиться следующая логическая
схема данных – полная атрибутивная модель (Рисунок 14).

18
Рисунок 14. Полная атрибутивная модель БД Trade
10. Переключившись в режим показа физической модели, уберите
пробелы в наименованиях полей (сделав первую букву второго слова
прописной), а также проверьте и, в случае необходимости, скорректируйте их
типы и длины, ориентируясь на специфику типов данных СУБД Access
(Рисунок 15). В частности, поле Price должно иметь тип Currency.

Рисунок 15. Настройка типов данных целевой СУБД

19
11. В физической модели с помощью команды меню Model -Columns
откройте окно Columns, перейдите на вкладку Constraint и задайте для полей
условия на значения Validation Constraint и/или значения по умолчанию Default,
давая им соответствующие имена. Например, для полей Price, Quantity и Rate
условие на значение заключается в выборе только неотрицательных значений,
что обеспечивается вводом выражения: >= 0. Значением по умолчанию для
поля Country будет "Беларусь"; для поля PaymentTerms - "Предоплата"; для
поля Measure - "штука"; для поля Currency (из таблицы Product) - "BYR"; для
поля OrderDate - Date(), т.е. текущая дата; для поля DeliveryDate - Date() + 14,
т.е. через две недели от текущей даты (Рисунок 16).

Рисунок 16. Создание значений по умолчанию


12. В физической модели (окно Model - Columns, вкладка ...Access)
настроите свойство Формат (Format), установив его для поля Quatity равным
#,##0.000 и для поля Rate - равным #,##0 (Рисунок 17). Настройте также
свойство Маска ввода (Mask) для поля Phone, установив его равным (999)
999-99-99.

Рисунок 17. Определение формата данных

20
13. В физической модели выделите мышью связь М:М между таблицами
Поставщик (Suppliers) и Товар (Products), после чего нажмите кнопку Many to
Many Transform на панели инструментов (с помощью команды меню Edit -
Many to Many Transform) и запустите мастер преобразования связи М:М (на всех
шагах работы мастера нажимайте кнопку Далее). В результате эта связь будет
преобразована в две связи 1:М путем создания дополнительной связующей
таблицы (Рисунок 18).

Рисунок 18. Преобразование связи М:М в физической модели


Примечание. Если установить флажок Many-to-Many Relationships with
Association Table на вкладке General в окне Model Properties, которое
вызывается командой меню Model - Model Properties, то Erwin будет
автоматически выполнять упомянутую выше трансформу связи М:М при
переключении с логической модели на физическую ( Рисунок 19).

Параметры для автоматического


преобразования связи типа М:М

Рисунок 19. Настройка свойств для автоматического преобразования связи


М:М
Сохраните модель данных на жестком диске в файле Trade.erwin.
21
Задание 3. Выполнение операции прямого проектирования

1. Запустите СУБД Access и создайте новую пустую базу данных с


именем Shop.mdb (версия созданной СУБД должна совпадать с выбранной при
создании модели: у нас MS Access 2000-2003), после чего закройте СУБД MS
Access.
2. В ERwin с помощью команды меню Tools - Forward Engineer - Schema
Generation (или соответствующей кнопки на панели инструментов) откройте
окно Access Schema Generation и нажмите кнопку Generate. В появившемся
окне Access Connection задайте имя пользователя (User Name) равным Admin, а
также с помощью кнопки Browse (первой сверху) задайте полное имя
созданной базы данных Trade.mdb.
3. Далее нажмите кнопку Connect и выполните процесс прямого
проектирования (Forward Engineer) с наполнением файла базы данных
Trade.mdb метаданными согласно созданной физической модели данных.
4. После завершения процесса прямого проектирования с помощью
команды меню Database - Database Connection откройте окно Access
Connection и разорвите соединение с базой данных Trade.mdb путем нажатия
кнопки Disconnect (Рисунок 20).
Если в процессе генерации будут ошибки, процесс остановиться и по
тексту сообщения об ошибке нужно исправить ее, и провести генерацию снова.

Рисунок 20. Окно прямого проектирования для MS Access


5. Запустите СУБД Access, откройте базу данных Trade.mdb и
просмотрите структуры полученных таблиц и наличие в них первичных
ключей.

22
Откройте окно Схема данных и проанализируйте структуру связей между
таблицами. В частности, используя контекстное меню связи, убедитесь, что
связи имеют определенные на этапе разработки модели в ERWin свойства.
В итоге схема данных должна выглядеть так, как показано на
рисунке Рисунок 21.

Рисунок 21. Схема данных базы данных MS Access Trade.mdb


6. Убедитесь, что для полей Price, Quatity, Rate установлено свойство
Условие на значение, а для полей Country, Measure, Currency (из таблицы
Products), OrderDate и DeliveryDate - установлено свойство Значение по
умолчанию, которые соответствуют правилам валидации (Valid) и значениям по
умолчанию (Default) в физической модели данных.
7. Убедитесь, что для поля Quantity (таблица Orders) и для поля Rate
(таблица Curreency) установлено свойство Формат. Убедитесь, что в таблице
Locations для поля Phone установлено свойство Маска ввода. Эти свойства
должны соответствовать аналогичным свойствам в физической модели данных.
8. Путем ввода данных в таблицы убедитесь, что таблицы снабжены
уникальными индексами, соответствующими альтернативным ключам в
логической модели данных (или соответствующие индексам в физической
модели данных).

Задание 4. Выполнение операции обратного проектирования

1. Закройте СУБД Access, после чего в ERwin закройте текущую модель


данных с помощью команды меню File - Close.

23
2. В ERwin с помощью команды меню Tools - Reverse Engineer
запустите мастер выполнения процесса обратного проектирования. На его
странице Reverse Engineer - Select Template задайте тип новой модели -
Логическая/Физическая, целевую базу данных - Access. Нажмите кнопку Next
(Рисунок 22).

Рисунок 22. Окно Reverse Engineer –Select Template


3. На следующей странице Reverse Engineer - Set Options в древовидной
структуре Items to Reverse Engineer найдите объект View и отключите его
(сбросьте флажок) вместе со всеми подчиненными ему элементами. Нажмите
кнопку Next.
4. В появившемся окне Access Connection задайте имя пользователя
User Name равным Admin, а также с помощью кнопки Browse (первой сверху)
задайте полное имя созданной ранее в Access базы данных Trade.mdb. При
проведении операции обратного проектирования, обратите внимание на
версию файла БД для которого выполняется операция. Версия должна
поддерживаться ErWin.
5. Далее нажмите кнопку Connect и выполните процесс обратного
проектирования (Reverse Engineer), в результате чего будет создана
физическая модель данных, соответствующая системному каталогу базы
данных Trade.mdb (Рисунок 23).

24
Рисунок 23. Физическая модель данных после операции обратного
проектирования.
6. После завершения процесса обратного проектирования с помощью
команды меню Database - Database Connection откройте окно Access
Connection и разорвите соединение с базой данных путем нажатия кнопки
Disconnect.
7. С помощью команды меню Format - Default Fonts & Colors откройте
окно Default Fonts & Colors, выберите вкладку General и установите в качестве
шрифта по умолчанию любой кириллический шрифт, например, Arial CYR.
Внизу, в группе переключателей Apply To, выберите переключатель All Objects,
после чего нажмите кнопку OK.
8. Убедитесь, что полученная модель данных соответствует схеме
данных созданной ранее базы данных Trade.mdb.
Сохраните модель данных на жестком диске в файле Trade_reverse.erwin.
Кроме прямого и обратного проектирования ERwin поддерживает
синхронизацию между логической моделью и системным каталогом СУБД на
протяжении всего жизненного цикла создания информационной системы. Как в
логическую модель, так и в объекты базы данных можно вносить изменения,
после чего ERwin позволяет выполнить синхронизацию объектов модели и
базы данных (то есть привести их в соответствие друг с другом).

Задания для самостоятельного выполнения

Задание 1. Операция прямого проектирования

1. Проведите операцию прямого проектирования для физической модели


данных Trade.erwin, выбрав в качестве целевой СУБД MS SQL Server.
Предварительно сделайте копию файла Trade.erwin.
Если есть возможность подключиться к СУБД MS SQL Server версии,

25
которую поддерживает ErWin, то проведите операцию прямого проектирования
с генерацией таблиц и схемы данных в СУБД MS SQL Server.
Если нет, то в окне прямого проектирования БД для целевой СУБД MS
SQL Server (Рисунок 24) нажмите кнопку Preview, скопируйте
сгенерированный сценарий на языке Transact-SQL и попробуйте развернуть БД
в СУБД MS SQL Server путем выполнения файла сценария.

Кнопка
Preview

Рисунок 24. Окно прямого проектирования БД для целевой СУБД MS SQL


Server

Задание 2. Операция обратного проектирования

1. Выполните операцию обратного проектирования для БД,


разработанной в СУБД MS Access УчебныйПроцесс.accdb. Для этого сохраните
БД в формате, поддерживаемом Erwin.
Если нужно сохранить БД в формате СУБД MS Access 2000/2002/2003, то
необходимо удалить или изменить тип данных для всех полей, имеющих тип
данных Вложение.
После этого проведите операцию обратного проектирования, следуя
инструкциям, описанным в задании 4 лабораторной работы № 1.
В результате должна получиться физическая модель БД
УчебныйПроцесс.mdb (Рисунок 25). Эту физическую модель можно
преобразовать в логическую модель, провести анализ структуры данных,
провести доработку существующих и разработку новых объектов средствами
проектирования Erwin.
Для полученной физической модели БД можно выбрать другую целевую
26
СУБД (например, MS SQL Server). Далее выполнить операцию прямого
проектирования и развернуть схему данных существующей БД в новой другой
СУБД. Таким образом возможна миграция схемы данных между разными
СУБД.
Полученную физическую модель можно также конвертировать в другие
среды проектирования БД.

Рисунок 25. Результат выполнения команды обратного проектирования БД


для файла БД MS Access УчебныйПроцесс.mdb.

27
Лабораторная работа № 2.
Создание БД в среде СУБД MS SQL Server

Теоретические сведения
Основным инструментом для конфигурирования, управления и
администрирования всех компонентов Microsoft SQL Server является
интегрированная среда SQL Server Management Studio (SSMS) (Рисунок 26),
которая мжет быть использована для доступа, настройки, администрирования и
разработки всех компонентов SQL Server, базы данных SQL Azure и хранилища
данных SQL, а также управления ими. Среда SSMS предоставляет единую
полнофункциональную служебную программу, которая сочетает в себе
обширную группу графических инструментов с рядом редакторов сценариев
для доступа к службе SQL Server для разработчиков и администраторов баз
данных всех профессиональных уровней.

Рисунок 26. Окно утилиты SQL Server Management Studio.


Среда SSMS позволяет получить доступ практически ко всем функциям
управления MS SQL Server с помощью унифицированного интерфейса. Через

28
интерфейс Management Studio можно управлять службами оповещений,
репликации, отчетности, более ранними версиями и др. В SQL Server
Management Studio используются следующие основные окна:
• окно Зарегистрированные Серверы (Registered Servers) позволяет
выбрать сервер SQL, работа с которым будет выполняться;
• окно Обозреватель объектов (Object Explorer) позволяет выполнять
работу с объектами выбранного сервера, просматривать и изменять их
свойства;
• окно Обозреватель решений (Solutions Explorer) реализует для
разработчика возможность просматривать исходный код и группировать его в
виде логической коллекции, которая при необходимости может быть
перенесена на другую базу данных;
Окно Обозреватель решений (Object Explorer) (Рисунок 27) отображается
в левой части окна утилиты SQL Server Management Studio и позволяет
выполнять запуск и остановку сервера, создание баз данных, их соединение и
отключение, а также настройку свойств сервера, создание объектов баз данных
(таких как таблицы, представления и хранимые процедуры), генерацию
сценариев на языке Transact-SQL, управление правами доступа к объектам,
мониторинг работы сервера, просмотр системных журналов, настройку
механизма репликации и многое другое.
Для работы с объектами, которые отображаются в окне Object Explorer,
необходимо щелкнуть на выбранном объекте правой кнопкой мыши и выбрать
в контекстном меню требуемый пункт. В контекстном меню отображается
уникальный набор свойств для каждого объекта. Также контекстное меню
позволяет выполнить такие действия с объектом как удаление, переименование,
создание новой таблицы, подключение, просмотр зависимостей таблицы,
отключение, настройка свойств объекта, удаление, изменение таблицы,
резервное копирование базы данных, восстановление базы данных из резервной
копии, а также другие действия. Состав контекстного меню и набор доступных
действий зависит от типа выбранного объекта.
Главным преимуществом окна Обозреватель объектов является
возможность генерировать сценарии создания отображаемых в нем объектов.
Это упрощает и ускоряет процесс создания приложений. Для автоматизации
этой операции предусмотрено использование мастера сценариев. Это средство
автоматизации позволяет создавать резервную копию базы данных, создавать
тестовую базу данных или необходимый объект. Используя мастер сценариев
для нескольких объектов, можно разработать или отдельный сценарий для
создания каждого объекта, либо общий сценарий для создания нескольких

29
объектов одновременно. При этом реализующий сценарий может быть выведен
в отдельный файл, в буфер обмена или в редактор запросов SQL Server
Management Studio.

Рисунок 27. Окно Обозреватель объектов (Object Explorer).


Окно Обозреватель решений (Solutions Explorer). Это основное окно для
работы с отдельными компонентами создаваемого приложения. Оно по
умолчанию отображается в правой части окна SQL Server Management Studio. В
окне Solutions Explorer отображается в виде древовидной структуры набор
используемых объектов, соединений и запросов к базе данных. Все это
составляет проект, над которым ведется работа. Корневой элемент дерева
носит название решения. По умолчанию ему присваивается значение Solution
1, однако разработчик может изменить это имя на любое другое, используя
окно свойств решения.
Далее в виде ветвей дерева отображаются текущие проекты. Решение
может включать в свой состав один или несколько проектов. При этом объекты,

30
выступающие в качестве листьев дерева, могут быть связаны с одним из
проектов или напрямую с решением. Листья обычно представляют собой
файлы, которые могут содержать информацию не только об определенном
объекте, но и о целом классе подобных объектов. Эти классы могут создаваться
разработчиками на одном из следующих языков запросов: Transact-SQL,
Analysis Server и XMLA.
Утилита SQL Server Management Studio поддерживает несколько
различных типов проектов: SQL Server Scripts, SQL Mobile Script,
Analysis Server Scripts.

Практические задания

Задание 1. Запуск утилиты SQL Server Management Studio

1. Создайте на любом локальном диске новую папку с Вашей фамилией.


Далее в окне выбора папки для сохранения файлов БД создать новую папку
НЕВОЗМОЖНО.
2. При помощи пользовательского меню Windows запустите утилиту SQL
Server Management Studio. При этом Вам предложат подключиться к серверу
баз данных SQL Server. В качестве имени сервера укажите имя своего
локального компьютера (оставьте значение по умолчанию) (Рисунок 28).
3. В окне Обозреватель объектов (Object Explorer) в дереве структуры
раскройте папку Базы данных (Databases) и далее папку System Databases. В
результате будут видны 4 системные базы данных (master, model, msdb,
tempdb), предназначенные для хранения метаданных и временных объектов.

Рисунок 28. Окно Соединение с сервером.

31
Задание 2. Создание базы данных

1. Создайте новую базу данных. Для этого выберите в контекстном (т.е.


вызываемом правой кнопкой мыши) меню папки Базы данных (Databases)
команду Создать базу данных (New Database). Откроется окно Создание базы
данных (New Database) (Рисунок 29).

Рисунок 29. Окно Создание базы данных.


2. На странице Общие (General) введите Имя базы данных (Database
name) как TRADE_ХХХ_1, где ХХХ - цифры, первая из которых есть последняя
цифра в номере вашей группы, а следующие две цифры - ваш номер в списке
группы или дайте базе данных другое уникальное имя (желательно включить в
имя БД личный идентификатор).
3. Значение в поле Владелец (Owner) оставьте без изменений.

32
4. В таблице Файлы базы данных (Database files) в столбце Логическое
имя (File Name) в первой строке появится введенное имя БД. Это файл,
который будет хранить данные БД. Файловая группа по умолчанию PRIMARY.
Во второй строке к имени БД будет добавлен постфикс _log. Этот файл будет
хранить журнал транзакций БД. В столбце Начальный размер (Initial Size) и в
столбце Автоувеличение/Максимальный размер (Autogrowth) оставим значения
без изменений. При необходимости их можно настроить, нажав на кнопку с
тремя точками. В столбце Путь (Path) нажмите справа кнопку с тремя точками
и выберите созданную папку, например, D:\TRADE_Ivanov для обоих файлов
(Рисунок 30).

Рисунок 30. Окно Создание базы данных с заполненными значениями.


5. Закройте окно Создание базы данных (New Database), нажав кнопку
ОК. Убедитесь, что созданная база данных появилась в папке Базы данных
(Databases) окна Обозреватель объектов (Object Explorer), нажав на кнопку
Обновить (Update) во второй строке окна Обозреватель объектов.
Примечание 1. Можно создавать несколько файлов в одной файловой
группе и дополнительные файловые группы и размещать их на различных
носителях информации.
Примечание 2. По умолчанию файлы данных и журнала транзакций
размещаются в папках, указанных в полях Default data directory и Default
log directory соответственно, которые расположены на странице Параметры
базы данных (Database Settings) окна свойств сервера (Рисунок 31).

33
Рисунок 31. Окно Параметры базы данных, в котором можно указать
имена папок, в которые по умолчанию будут сохраняться файлы создаваемых
БД.

Задание 3. Создание таблиц базы данных

1. Создайте в базе данных TRADE_XXX 5 таблиц, описание которых


приведено ниже (Рисунок 34 – 32).
Для создания таблицы нужно в окне Обозреватель объектов (Object
Explorer) открыть папку TRADE_XXX и затем в контекстном меню появившейся
папки Таблицы (Tables) выберите команду Создать > Таблицу (New > Table),
открывая конструктор таблиц (Рисунок 32).

34
Рисунок 32. Таблица Locations в режиме Конструктора.
Первичный ключ задать через контекстное меню или нажатием
соответствующей кнопки при выделенном столбце.
Примечание. Для корректировки таблиц (изменения данных и/или
структуры) необходимо снять флажок в параметре Запретить сохранение
изменений, требующих повторного создания таблицы меню Сервис –
Параметры – Конструкторы – Конструкторы таблиц и баз Источник данных
(Рисунок 33. Настройка возможности корректировки таблиц.Рисунок 33).

35
Рисунок 33. Настройка возможности корректировки таблиц.
После создания таблиц сохраните их. Чтобы открыть конструктор
таблицы: выделите ее имя в Обозревателе объектов и через вызов
контекстного меню выберите команду Проект.
Создайте приведенные ниже таблицы (Рисунок 34 – 32):

Рисунок 34. Таблица Locations (Расположение) в режиме Конструктора.

Рисунок 35. Таблица Clients (Клиенты) в режиме Конструктора.

36
Рисунок 36. Таблица Currency (Валюта) в режиме Конструктора.

Рисунок 37. Таблица Products (Товары) в режиме Конструктора.

Рисунок 38. Таблица Orders (Заказы) в режиме Конструктора.


Примечание. Для задания первичного ключа по нескольким столбцам
сначала выделить их, удерживая клавишу CTRL или SHIFT и щелкая по полю
слева от имени, затем задать первичный ключ через вызов контекстного меню
или нажатием соответствующей кнопки.
2. В таблице Clients столбец ClientID и в таблице Orders столбец
OrderID сделайте автоинкрементными столбцами, т.е. при добавлении новой
строки значения этих столбцов будут устанавливаться автоматически
наращиванием (обычно на единицу) предыдущих значений. Соответствующее
свойство столбца называется Спецификация идентификатора (Identity
Specification) (окно Свойства столбца (Column Properties) в нижней части
экрана); здесь же можно указать начальное значение идентификатора и шаг его
приращения (Рисунок 39).

37
Рисунок 39. Задание свойств для создания автоинкрементируемого
столбца.
3. Задайте для столбцов значения по умолчанию с помощью свойства
Значение по умолчанию или привязка (Default Value or Binding) (окно
Свойства столбца (Column Properties) в нижней части экрана).
Значения по умолчанию:
• для столбца Country таблицы Locations будет ’Беларусь’ (одинарные

38
кавычки можно не набирать);
• для столбца Measure таблицы Products – ’штука’;
• для столбца CurrencyID (из таблицы Products) – ’BYN’;
• для столбца OrderDate таблицы Orders - getdate() текущая дата;
• для столбца DeliveryDate таблицы Orders getdate() + 14, т.е. через
две недели от текущей даты.
4. Создайте уникальные (unique) индексы:
Таблица 2. Уникальные индексы БД TRADE_XXX (Рисунок 40).
Имя таблицы Имя индекса Имена столбцов индекса
Clients UIX_ClientName ClientName
Currency UIX_CurrencyName CurrencyName
Products UIX_ProductName ProductName
Locations UIX_Four Country, Region, City, Address

Рисунок 40. Создание уникального индекса по полю ClientName таблицы


Clients.
Для создания индекса нужно в окне Конструктора таблицы через
контекстное меню и выбрать команду Индексы и ключи (Indexes and Keys). В
левом окне будет отображено имя уже созданного первичного ключа. Нажмите
кнопку Добавить внизу окна, появится имя нового индекса, выделите его и
настроите свойства создаваемого индекса. Измените имя индекса и имя поля,
по которому создается ключ: в Разделе Общие в свойстве Столбцы нажмите
справа на кнопку с тремя точками и выберите имя столбца (столбцов), по

39
которому создается индекс. Далее нажмите кнопку Закрыть.
5. Создайте неуникальные (non unique) индексы:

Имя таблицы Имя индекса Имена столбцов индекса


Locations IХ_CountryCity Country, City
Products IХ_ProductNameMeasur ProductName, Measure
e
Orders IХ_OrderDate OrderDate

Рисунок 41. Создание неуникального индекса


6. Установите для столбцов проверочные ограничения на значения:
• Для столбцов Price таблицы Products, Quantity таблицы Orders и
Rate таблицы Currency ограничение на значения заключается в выборе только
неотрицательных значений (Имя_поля >= 0).
Для создания проверочных ограничений нужно раскройте папку
соответствующей таблицы и в контекстном меню появившейся папки
Ограничение (Constraints) выберите команду Создать ограничение (New
Constraint). Для каждого поля создайте отдельное ограничение и дайте ему
соответствующее имя (Рисунок 42).

40
Рисунок 42. Создание ограничения на значение поля Quantity таблицы
Orders.

Задание 4. Создание связей между таблицами базы данных

1. Установите между таблицами связи типа 1:М, которые задаются


следующими строками:

Имя связи Родительская таблица/ Дочерняя таблица/ Внешний


Первичный ключ ключ
FK_Clients_Locations Locations/ LocationID Clients/ Location
FK_Products_Currency Currency/ CurrencyID Products/ Currency
FK_Orders_Products Products/ ProductID Orders/ Product
FK_Orders_Clients Clients/ ClientID Orders/ Client

Для установления связи между родительской и дочерней таблицами


нужно раскрыть элемент дочерней таблицы папку Ключи (Keys) и в его
контекстном меню выберите команду Создать внешний ключ (New Key).
Добавить новую связь и установить значения в разделе Спецификация таблиц
и столбцов, нажав на кнопку с тремя точками (Рисунок 43). Обратите внимание
на значения в свойствах Спецификация UPDATE и DELETE.
Создайте две связи таким способом.

41
Рисунок 43. Создание связей между таблицами Products и Currency.
2. Остальные связи создайте в окне диаграммы БД. Создайте диаграмму
для базы данных. Для этого раскройте папку БД TRADE_ХХХ_1, через
контекстное меню папки Диаграммы баз данных (Database Diagrams) выберите
команду Создать диаграмму базы данных (New Database Diagram). При
первом запуске может быть задан вопрос о подключении необходимых
компонентов. Ответьте Да.
В диаграмму включите все 5 таблиц, входящие в базу данных
TRADE_ХХХ_1.
После добавления всех таблиц создайте недостающие связи, перетащив
при нажатой левой клавише мыши поле внешнего ключа дочерней таблицы
(поставить указатель мыши на прямоугольник слева от имени поля) на поле
первичного ключа родительской таблицы или наоборот.
Обратите внимание на установку свойств связи Правило обновления и
Правило удаления в разделе Спецификация UPDATE и DELETE.
После появления на экране окна с диаграммой установите оптимальный

42
масштаб изображения и расположите элементы диаграммы наиболее удобным
образом, а также включите режим показа названий связей между таблицами.
Для этого щелкните мышью на свободном месте диаграммы и, вызвав далее
контекстное меню, выберите команду Показать подписи отношений (Show
Relationship Labels). Сохраните диаграмму под именем Diagram_Start после
чего закройте ее (Рисунок 44).

Рисунок 44. Диаграмма данных Diagram_Start БД TRADE_XXX.

Задание 5. Заполнение таблиц базы данных и создание


представлений.

1. Введите по 3-4 строки данных сначала в таблицы Currency и


Locations, а затем в таблицы Products и Clients. После этого введите не
менее 10 строк данных в таблицу Orders. При вводе данных обратите внимание
на ограничения данных для внешнего ключа дочерней таблицы.
Для ввода данных в таблицу выберите в ее контекстном меню команду
Изменить первые 200 записей.

2. Создайте представление (View) на основе Рисунок 45:


Для создания представления выберите в контекстном меню папки
Представления (Views) БД TRADE_ХХХ_1 команду Создать представление (New
View). Указажите нужные таблицы и затем в появившемся окне конструктора
представлений, путем расстановки флажков в выбранных таблицах, отобразите
нужные поля. Укажите тип сортировки. Столбец COST создаваемого
представления является вычисляемым.
Сохраните созданное представление под именем OrdersCost, нажав на
кнопку Сохранить, после чего закройте окно конструктора.
Обратите внимание на текст запроса на языке SQL, который формируется
автоматически при заполнении бланка представления. В этом же окне можно

43
получить результат выполнения запроса.

Рисунок 45. Окно создания представления OrdersCost.


3. Откройте и просмотрите на экране данные, выбираемые посредством
представления OrdersCost. Для этого в контекстном меню папки
Представления (Views) выберите команду Изменить первые 200 строк (Update
top 200).

Задание 6. Отсоединение от сервера и подключение базы


данных

Отсоедините базу данных TRADE_ХХХ_1 от сервера, выбрав в ее


контекстном меню команду Задачи (Tasks) - Отсоединить (Detach Database).
Убедитесь, что база данных TRADE_ХХХ_1 исчезла из папки Базы данных
(Databases). Теперь файлы этой базы данных можно, пр и необходимости,
переместить в другую папку на жестком диске или скопировать на другой

44
носитель данных.
Чтобы снова начать работать с базой данных TRADE_ХХХ_1, нужно
выполнить операцию ее присоединения. Для этого выберите в контекстном
меню папки Базы данных (Databases) команду Atach Database (Присоединить),
затем в появившемся окне нажмите кнопку Добавить (Append) и далее укажите
местоположение первичного файла БД (т.е. файла данных с расширением
.mdf).
4. Закройте утилиту SQL Server Management Studio.

45
Лабораторная работа № 3.
Создание базы данных и ее объектов с
помощью команд языка Transact-SQL

Теоретические сведения

Создание базы данных и ее объектов с помощью команд языка


Transact-SQL

1. Запустите утилиту SQL Server Management Studio, после чего


раскройте на панели Обозреватель объектов (Object Explorer) в древовидной
структуре папку Базы данных (Databases).
На панели инструментов нажмите кнопку Создать запрос (New Query), что
вызовет появление на экране Окна запросов к базе данных. Это окно можно
использовать для последовательного формирования в нем сценария (скрипта),
который является тестовым файлом с расширением .sql и сохраняется на
диске. Сценарий представляет собой последовательность команд языка
Transact-SQL, с помощью которых можно будет впоследствии автоматически
сгенерировать базу данных со всеми ее объектами, а также наполнить ее
таблицы данными и выполнить ряд других действий. С помощью сценария
можно создать такую же базу данных, что была создана средствами
графического интерфейса утилиты в преыдущей лабораторной работе.
Создание сценария заключается в том, что каждый раз мы будем добавлять
в Окно запросов очередную команду языка Transact-SQL (или группу команд,
образующих пакет), проверять ее синтаксис и затем выполнять, нажимая на
панели инструментов кнопку Выполнить (Execute) (или клавишу F5). При этом
необходимо, чтобы данная команда (или пакет) была выделена подсветкой,
иначе будут выполнены все без исключения команды, содержащиеся в Окне
запросов.
Если очередная команда (или пакет) будет успешно выполнена, то в окно
Query можно дописать новую команду (или пакет), выделить подсветкой и
далее повторить процесс, описанный выше. В конечном итоге, путем
поочередного выполнения команд, будет создана база данных со всеми ее
объектами и параллельно в Окне запросов будет сформирован сценарий,
который можно сохранить в файле на диске. Теперь с помощью этого сценария
можно на любом компьютере, где установлен MS SQL Server, выполнить
процедуру создания разработанной базы данных.
Полный синтаксис команд языка Transact-SQL занимает вместе с
описанием всех аргументов не один десяток страниц. Его можно изучить в
литературе или библиотеке MSDN (например, https://msdn.microsoft.com/ru-
ru/library/bb545450.aspx).

46
Практические задания

Задание 1. Создание новой базы данных с помощью команд языка


Transact-SQL

1. Создание базы данных. Команда создания базы данных TRADE_ХХХ,


которую нужно вставить в Окно запросов, имеет следующий вид:
CREATE DATABASE TRADE_ХХХ -- Вместо ХХХ поставьте свою комбинацию
цифр
ON PRIMARY -- Путь к файлам БД уже должен существовать
(NAME = TRADE_ХХХ,
FILENAME = 'D:\TRADE__Ivanov\TRADE_ХХХ.mdf',
SIZE = 5120KB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 1024KB)
LOG ON
(NAME = TRADE_ХХХ_log,
FILENAME = 'D:\TRADE_Ivanov\TRADE_ХХХ_log.ldf',
SIZE = 2048KB,
MAXSIZE = 2048GB,
FILEGROWTH = 10%)
GO
Примечание. Команда GO используется для указания конца пакета.
Команды, образующие пакет, обрабатываются сервером за один раз, после чего
он возвращает клиенту (в нашем случае - пользователю SQL Server
Management Studio) результат. После этого клиент может отправить
следующий пакет и т.д. В данном случае пакет содержит всего одну команду,
предназначенную для создания базы данных.
2. Подключение к базе данных.
USE TRADE_ХХХ
GO
Примечание. При обращении к объектам текущей базы данных (т.е.
выбранной с помощью команды USE) не требуется указание ее имени. Но когда
работа ведется в контексте иной базы данных, то необходимо указывать также
имя базы данных.

Задание 2. Создание таблиц и индексов базы данных с помощью


команд языка Transact-SQL

1. Создание таблиц базы данных


Создайте таблицу Locations:
CREATE TABLE Locations(
LocationID int NOT NULL PRIMARY KEY,

47
Country varchar(20) NOT NULL DEFAULT ('Беларусь'),
Region varchar(20) NOT NULL,
City varchar(20) NOT NULL,
Address varchar(50) NOT NULL,
Phone char(15) NULL,
-- создание уникального индекса по четырем полям
constraint IX_Four unique(Country, Region, City, Address)
)
Создайте таблицу Clients:
CREATE TABLE Clients(
ClientID int PRIMARY KEY IDENTITY(1,1) NOT NULL,
ClientName varchar (40) NOT NULL,
HeadFullName varchar (60) NULL,
Location int NULL,
-- создание ограничения по внешнему ключу
CONSTRAINT FK_Clients_Locations FOREIGN KEY (Location)
REFERENCES Locations(LocationID)
ON UPDATE CASCADE
)
GO
Создайте таблицу Currency:
CREATE TABLE Currency(
CurrencyID char(3) PRIMARY KEY NOT NULL,
CurrencyName varchar(30) NOT NULL,
Rate smallmoney NOT NULL CHECK (Rate>0)
)
Создайте таблицу Products:
CREATE TABLE Products(
ProductID int PRIMARY KEY NOT NULL,
ProductName varchar(50) NOT NULL,
Measure char(10) NULL,
Price money NULL CHECK (Price>=0),
Currency char(3) NULL,
CONSTRAINT FK_Products_Currency FOREIGN KEY(Currency)
REFERENCES dbo.Currency (CurrencyID)
)
GO
Создайте таблицу Orders:
CREATE TABLE Orders(
OrderID int IDENTITY(1,1) NOT NULL,
Client int NOT NULL,
Product int NOT NULL,
Quantity numeric(12,3) NULL,

48
OrderDate date NULL DEFAULT getdate(),
DeliveryDate date NULL DEFAULT getdate()+14,
PRIMARY KEY ( -- составной первичный ключ
OrderID ASC,
Client ASC,
Product ASC
),
CONSTRAINT FK_Orders_Clients FOREIGN KEY(Client)
REFERENCES dbo.Clients (ClientID)
ON UPDATE CASCADE,
CONSTRAINT FK_Orders_Products FOREIGN KEY(Product)
REFERENCES dbo.Products (ProductID)
ON UPDATE CASCADE
)
GO
2. Создание уникальных и неуникальных индексов таблицы
CREATE UNIQUE INDEX UIX_Clients ON Clients(ClientName)
CREATE UNIQUE INDEX UIX_Currency ON Currency(CurrencyName)
CREATE UNIQUE INDEX UIX_Products ON Products(ProductName)
CREATE INDEX IX_Locations ON Locations (Country, City)
CREATE INDEX IX_Products ON Products(ProductName, Measure)
CREATE INDEX IX_Orders ON Orders(OrderDate)
3. Создайте диаграмму данных для созданной БД
Диаграмму данных создайте также, как в задании 3.2 лабораторной работы
номер 2. Проверьте правильность установленных при создании таблиц связей.
Созданная диаграмма должна точно соответствовать Рисунок 44.

Задание 3. Сохранение сценария. Создание базы данных с


помощью сценария

1. Сохраните текущий сценарий в файле


D:\FIO\TRADE_XXX\CreateDB_Tables.sql помощью команды меню Файл –
Сохранить (File - Save as)...
2. Обновите данные в окне Обозреватель решений (Object Explorer).
Для этого в ней нужно выделить папку Базы данных (Databases) и в ее
контекстном меню выберите команду Обновить (Refresh) (или нажать
соответствующую кнопку в верхней части этой панели). В результате база
данных TRADE_ХХХ станет видимой в окне Обозреватель решений (Object
Explorer).
3. Переключитесь на другую базу данных, например, Master. Для этого
выберите базу данных Master в выпадающем списке, расположенном на панели
инструментов. Другой вариант - набрать в Окне запросов (Query) две команды
(USE Master и GO), выделить их и выполнить.

49
4. Удалите созданную базу данных TRADE_ХХХ, поскольку теперь мы ее
всегда можем сгенерировать с помощью сценария CreateDB_Tables.sql. Для
этого в окне Обозреватель решений (Object Explorer) выберите базу данных
TRADE_ХХХ и в ее контекстном меню выполните команду Удалить (Delete).
Замечание. Базу данных невозможно удалить, если предварительно не
закрыть существующее соединение или не переключиться на другую базу
данных, что и было сделано в предыдущем пункте. Можно обойтись без
выполнения предыдущего пункта и сразу удалить текущую базу данных
TRADE_ХХХ, но в этом случае после появления на экране окна Удаление объекта
(Delete Object) нужно в нижней его части установить флажок Закрыть
существующие соединения (Close Existing Connections).
5. Закройте утилиту SQL Server Management Studio.

Задание 4. Подготовка базы данных для ввода данных

1. Запустите утилиту SQL Server Management Studio, в окне


Обозреватель решений (Object Explorer) в древовидной структуре раскройте
папку Базы данных (Databases).
2. С помощью команды меню Файл – Открыть – Файл (File - Open – File)
загрузите сценарий из файла D:\FIO\TRADE_XXX\CreateDB_Tables.sql в Окно
запросов (Query).
Выполните сценарий, нажав на панели инструментов кнопку Выполнить
(Execute) (или клавишу F5). В результате будет создана база данных TRADE_ХХХ.
3. Обновите данные в окне Обозреватель решений (Object Explorer).
Для этого используйте команду Обновить (Refresh) в контекстном меню папки
Базы данных (Databases) или соответствующую кнопку в верхней части
панели. В результате база данных TRADE_ХХХ станет видимой в окне
Обозреватель решений (Object Explorer).
Далее продолжите работу с базой данных TRADE_ХХХ, последовательно
добавляя в сценарий, выделяя подсветкой и выполняя приведенные ниже
команды или пакеты языка Transact-SQL.

Задание 5. Ввод данных в таблицы базы данных посредством


запросов на языке SQL

1. Вставьте данные в таблицу Locations (Рисунок 46):

50
Рисунок 46. Таблица Locations.

INSERT INTO Locations


(LocationID, Country, Region, City, Address, Phone)
VALUES
(101,'Беларусь','Витебская','Полоцк','ул.Лесная, 6',
'+375172691376')

INSERT INTO Locations


(LocationID, Region, City, Address)
VALUES
(103,'','Минск','ул.Маркса, 24')

INSERT INTO Locations


(LocationID, Region, Address, City)
VALUES
(103, 'Гродненская', 'ул.Моховая, 12', 'Лида')

INSERT INTO Locations


VALUES
(301, 'Украина','', 'Киев', 'ул. Крещатик, 14', NULL),
(302, 'Украина','Львовская','Моршин','ул.Франко, 24', NULL)

Замечание. Здесь приведены различные способы использования команды


INSERT, которые учитывают следующие особенности.
• Если в строке INSERT INTO список имен столбцов опущен, то в строке
VALUES необходимо указывать значения для всех столбцов, которые имеет
таблица. В противном случае значения указываются только для тех столбцов,
наименование которых фигурируют в строке INSERT INTO.
• Несмотря на то, что значение в столбце Страна является
обязательным (определен как NOT NULL), его имя можно не указывать в списке
имен столбцов, поскольку для этого столбца определено значение по
умолчанию ('Беларусь').
• Если значение поля Область не заполняется, то нельзя использовать
NULL, а нужно задать пустую строку (''), поскольку поле Область является

51
обязательным и значение NULL в нем недопустимо.
• Возможно введение данных в несколько строк с помощью одной
команды INSERT INTO.
• Все типы текстовые данных должны быть заключены в одиночные
кавычки.
2. Вставьте данные в таблицу Clients (Рисунок 47), используя
различные варианты команды INSERT INTO:

Рисунок 47. Таблица Clients.


Замечание. В таблице Clients столбец ClientID является
автоинкрементным и, поэтому, его значения не приведены и задавать их в
запросах не нужно.

3. Вставьте данные в таблицу Currency (Рисунок 48):

Рисунок 48. Таблица Currency.


Вставьте данные в таблицу Products (Рисунок 49). Обратите внимание
на то, что поле Currency таблицы Products является внешним ключом.

Рисунок 49. Таблица Products


4. Вставьте данные в таблицу Orders ().

52
Рисунок 50. Таблица Orders.
Замечание. В таблице Orders столбец OrderID является
автоинкрементным и, поэтому, его значения не приведены.

SET DATEFORMAT dmy -- задаем привычный формат даты день.месяц.год, т.к.


--по умолчанию установлен формат год.месяц.день
INSERT INTO Orders -- год можно задавать как 2-мя, так и 4-мя цифрами
VALUES (2, 111, 14, ’12.04.17’, ’05.03.17’)

Задание 6. Создание представления базы данных

1. Создание представления базы данных.


Создайте представление с имеем OrdersCost.
CREATE VIEW OrdersCost AS
SELECT dbo.Clients.ClientName, dbo.Products.ProductName,
dbo.Orders.OrderDate, dbo.Orders.DeliveryDate,
dbo.Products.Price * dbo.Orders.Quantity AS COST
FROM dbo.Clients INNER JOIN
dbo.Locations ON dbo.Clients.Location =
dbo.Locations.LocationID
INNER JOIN
dbo.Orders ON dbo.Clients.ClientID = dbo.Orders.Client
INNER JOIN
dbo.Products ON dbo.Orders.Product = dbo.Products.ProductID
ORDER BY dbo.Clients.ClientName, dbo.Products.ProductName DESC
Результат выполнения представления OrdersCost показан на Рисунок 51.

53
Рисунок 51. Результат выполнения представления OrdersCost.

Задание 7. Анализ полученных результатов

1. Сохраните созданный итоговый сценарий в файле


D:\FIO\TRADE_XXX\CreateDB_Insert_Data.sql с помощью команды меню
Файл – Сохранить (File - Save) (или соответствующей кнопки на панели
инструментов). Далее закройте Окно запросов (Query), содержащее сценарий
CreateDB_Insert_Data.sql.
2. Удалите базу данных TRADE_ХХХ. Для этого в ее контекстном меню
выберите команду Удалить (Delete) и затем в появившемся окне Удаление
объекта (Delete Object) установите флажок Закрыть существующие
соединения (Close Existing Connections).
3. С помощью команды меню Файл – Открыть – Файл (File - Open –File)
загрузите сценарий из файла CreateDB_Insert_Data.sql, после чего, нажав на
панели инструментов кнопку Выполнить (Execute), создайте базу данных
TRADE_ХХХ заново.
4. Обновите данные в окне Обозреватель объектов и сделайте базу
данных TRADE_ХХХ видимой.
5. Убедитесь, что с помощью сценария получена база данных
TRADE__ХХХ с требуемыми объектами и свойствами.
6. Проведите сравнительный анализ лабораторных работ 1 и 2, т.к. их
выполнение привело к получению одного и того же результата - баз данных
TRADE_ХХХ_1 и TRADE_ХХХ соответственно. Укажите для каждого пункта,
связанного с созданием объектов базы данных с помощью графического
интерфейса (база данных TRADE_ХХХ_1), соответствующую ему команду языка
Transact-SQL и, в частности, какие ее фрагменты связаны с установкой тех или
иных свойств конкретного объекта базы данных.

54
7. Удалите созданную базу данных TRADE_ХХХ.

55
Лабораторная работа № 4.
Выборка и манипулирование данными с помощью команд
языка SQL

Подготовительные действия
1. Запуститеутилиту SQL Server Management Studio, в окне
Обозреватель объектов (Object Explorer) в древовидной структуре раскройте
папку Базы данных (Databases).
2. С помощью команды меню File - Open - File загрузите сценарий из
файла D:\FIO\TRADE_XXX\CreateDB_Insert_Data.sql в Окно запросов
(Query).
3. Выполните сценарий, нажав на панели инструментов кнопку
Выполнить (Execute) (или клавишу F5). В результате будет создана база данных
TRADE_ХХХ.
4. Обновите данные в окне Обозреватель объектов (Object Explorer).
Для этого используйте команду Обновить (Refresh) в контекстном меню папки
Базы данных (Databases) или соответствующую кнопку в верхней части окна. В
результате база данных TRADE_ХХХ станет видимой в окне Обозреватель
объектов (Object Explorer).
5. Закройте Окно запросов (Query), содержащее сценарий
CreateDB_Insert_Data.sql. Затем на панели инструментов нажмите кнопку
Новый запрос (New Query), и откройте новое пустое Окно запросов (Query),
предназначенное для формирования нового сценария DataManipulation.sql.
Сделайте активной созданную базу данных TRADE_ХХХ:
USE TRADE_ХХХ
GO

Практические задания

Задание 1. Выборка данных из таблиц и представлений.


Оператор SELECT

Выполните различные варианты команды выборки данных SELECT:


1. Выборка всех столбцов и всех строк одной таблицы Locations
(Рисунок 52).

56
Рисунок 52. Выборка данных из одной таблицы.
2. Выборка некоторых столбцов и всех строк (вертикальный фильтр) из
одной таблицы (Рисунок 53).

Рисунок 53. Вертикальный фильтр.


3. Выборка всех столбцов и некоторых строк (горизонтальный фильтр)
из одной таблицы (Рисунок 54).

Рисунок 54. Горизонтальный фильтр.


4. Выборка некоторых столбцов и некоторых строк (вертикальный и
горизонтальный фильтры) из одной таблицы (Рисунок 55).

57
Рисунок 55. Вертикальный и горизонтальный фильтры.
5. Выборка с сортировкой строк по столбцу Country, а при совпадении
городов - по столбцу City (Рисунок 56).

Рисунок 56. Выборка с сортировкой по двум полям.


6. Выборка из двух таблиц путем их внутреннего соединения по
столбцам Locations.LocationID и Clients.Location с сортировкой по
имени клиента (Рисунок 57).

Рисунок 57. Выборка из двух таблиц путем их внутреннего соединения.

58
7. Выборка данных из трех таблиц. Выбираются данные только тех
заказов, в которых количество заказанных товаров Qauntaty больше или равно 2
(Рисунок 58).

Рисунок 58. Выборка данных из трех таблиц.


8. Выборка данных с формированием вычисляемого столбца COST
(Рисунок 59).

Рисунок 59. Запрос с вычисляемым полем.


9. Подсчет итоговых данных для столбца Количество в таблице Orders
().

59
Рисунок 60. Запрос с агрегирующими функциями.
10. Выборка данных из таблицы Orders с группировкой по столбцу
ProductID и подсчетом для каждой группы итоговых данных (Рисунок 61).

Рисунок 61. Выборка данных с их группировкой и подсчетом для каждой


группы итоговых данных.
11. Выборка данных из таблицы Orders с группировкой по столбцу
ProductID и отбором групп, удовлетворяющих условию: общее количество
товаров больше 80 (Рисунок 62).

60
Рисунок 62. Запрос с отбором групп, удовлетворяющих условию.
12. Выборка данных из представления OrdersCost (Рисунок 63).

Рисунок 63. Выборка данных из представления.


Примечание. При выборке данных из представления можно использовать
все предложения команды SELECT.
13. Создание новой таблицы путем отбора данных из другой таблицы.
Следующая команда создаст копию таблицы Orders с данными. При создании
новой таблицы таким способом копируется только структура таблицы и
данные. Ограничения нужно задавать заново.
SELECT * INTO Orders1 FROM Orders
Следующая команда создаст копию таблицы Products.
SELECT * INTO Products1 FROM Products
Примечание. При создании новой таблицы можно использовать все
предложения команды SELECT.

Задание 2. Выборка системных данных

1. Список учетных записей, которым разрешен доступ к серверу


USE master -- переключаемся на системную базу данных master
SELECT name, dbname, password, language FROM syslogins

USE TRADE_ХХХ -- переключаемся обратно на базу данных


-- TRADE_ХХХ
2. Список учетных записей, включенных в фиксированные роли сервера
EXEC sp_helpsrvrolemember
3. Список пользователей базы данных TRADE_ХХХ

61
EXEC sp_helpuser
4. Список ролей (как фиксированных, так и пользовательских) базы
данных TRADE_ХХХ
EXEC sp_helprole
5. Членство ролей и пользователей в ролях базы данных TRADE_ХХХ
EXEC sp_helprolemember

Задание 3. Обновление данных в таблицах и представлениях

1. В таблице Clients заменить все значения NULL в столбце Location на


значение 103 с помощью следующей команды:
USE TRADE__BD
SELECT * FROM Clients
--------------
UPDATE Clients
SET Location = 103
WHERE Location IS NULL
---------------
SELECT * FROM Clients

Задание 4. Удаление данных из таблиц и представлений

1. В таблице Orders1 удалить все строки, в которых значение поля


DeliveryDate не относится к текущему году, следующим образом:
SET DATEFORMAT dmy -- задаем привычный формат даты:
-- день.месяц.год
DELETE FROM Orders1
WHERE DeliveryDate < '01.01.2017'
GO

Задание 5. Изменение структуры таблицы

Примеры использования команды изменения структуры таблицы:


1. Добавление нового поля Weight в таблицу Products1.
ALTER TABLE Products ADD Weight INT NULL
GO
2. Изменение типа данных поля Weight в таблице Products с INT на
FLOAT.
ALTER TABLE Products

62
ALTER COLUMN Weight FLOAT NULL
GO
3. Установка проверочного ограничения для поля Weight в таблице
Products.
ALTER TABLE Products
ADD CONSTRAINT СК_Products_Weight
CHECK (Weight BETWEEN 10 AND 100)
GO
4. Удаление поля Weight из таблицы Products (сначала удаляется
проверочное ограничение).
ALTER TABLE Products
DROP CONSTRAINT СК_Products_Weight

ALTER TABLE Products DROP COLUMN Weight


GO
5. Удаление ограничения внешнего ключа FК_Products_Currency из
таблицы Products.
ALTER TABLE dbo.Products
DROP CONSTRAINT FK_Products_Currency
6. Добавление ограничения внешнего ключа FК_Products_Currency в
таблицу Products.
ALTER TABLE Products
ADD CONSTRAINT FК_Products_Currency
FOREIGN KEY (Currency) REFERENCES Currency
ON UPDATE CASCADE
7. Добавим ограничение по первичному ключу для таблицы Products1.
ALTER TABLE Products1
ADD CONSTRAINT PK_Products1
PRIMARY KEY(ProductID)
8. Добавление ограничения внешнего ключа FК_Products1_Order1 в
таблицу Orders1.
ALTER TABLE Orders1
ADD CONSTRAINT FК_Products1_Orders1
FOREIGN KEY (Product) REFERENCES Products1
ON UPDATE CASCADE

63
Задание 6. Удаление таблицы из базы данных

Прежде чем удалить таблицу из базы данных, необходимо разорвать все


связи этой таблицы с ее дочерними таблицами, если такие имеются. В
противном случае удалить таблицу будет невозможно.
Например, требуется удалить таблицу Products. Сначала необходимо
провести анализ, есть ли таблицы, для которых таблица Products является
родительской. Для этого можно, например, использовать системную хранимую
процедуру sp_fkeys, позволяющую получить информации о связях между
таблицами посредством первичных и внешних ключей.
1. Получить информацию о связях родительской таблицы Products с ее
дочерними таблицами
EXEC sp_fkeys ’Products1’
У таблицы Products имеется одна дочерняя таблица - таблица Orders. Та
же информация подтверждается, если проанализировать с помощью процедуры
sp_fkeys, какие родительские таблицы имеются у таблицы Orders.
2. Получить информацию о связях дочерней таблицы Orders с ее
родительскими таблицами
EXEC sp_fkeys @fktable_name = ’Orders1’
3. После этого становится ясно, что для удаления из базы данных
таблицы Products, нужно выполнить следующие две команды:
Удаление из базы данных таблицы Products1 ограничения внешнего
ключа РК_Orders_Products.
-- Первая команда
ALTER TABLE Orders1
DROP CONSTRAINT FК_Products1_Orders1
-- Вторая команда
DROP TABLE Products1
Замечание. Сначала была разорвана связь между таблицами Products1 и
Orders1 путем удаления в таблице Orders1 ограничения внешнего ключа
FК_Products1_Orders1. Только после этого была удалена таблица Products1.

Задания для самостоятельного выполнения


Предварительно выполните следующие действия.
• Закройте (без сохранения данных) текущее Окно запросов (Query) и
удалите базу данных TRADE_ХХХ.

64
• Загрузите сценарий из файла D:\FIO\TRADE_XXX\
CreateDB_Insert_Data.sql и создайте базу данных TRёADE_ХХХ заново.
• Обновите данные в окне Обозреватель объектов (Object Explorer) и
сделайте базу данных TRADE_ХХХ видимой.
• Закройте окно со сценарием CreateDB_Insert_Data.sql и откройте
новое пустое Окно запросов (Query), предназначенное для формирования
сценария выполнения задания к лабораторной работе.
Все задания выполняйте, используя операторы языка SQL.

Задание 7. Создание новых таблиц

1. Создайте новую таблицу Suppliers (Поставщики) (Рисунок 64).

Рисунок 64. Таблица Suppliers (Поставщики).


При создании таблицы обратите внимание на ее связи с другими
таблицами (Рисунок 65). Связи между таблицами Orders и Suppliers и между
таблицами Locations и Suppliers являются неидентифицирующими. Для
создания связи между таблицами Orders и Suppliers необходимо в таблицу
Orders добавить новое поле Supplier.

65
Рисунок 65. Связи таблицы Suppliers с таблицами Orders и Locations.

 Заполните таблицу Suppliers данными (Рисунок 68).

Рисунок 66. Данные таблицы Suppliers.

 Заполните поле Supplier таблицы Orders.

2. Создайте новую таблицу Employees (Сотрудники) (Рисунок 64).

66
Рисунок 67. Таблица Employees (Сотрудники).
При создании таблицы обратите внимание на ее связи с другими
таблицами (Рисунок 65) и с самой собой. Для создания связи между таблицами
Orders и Employees необходимо в таблицу Orders добавить новое поле
Employee.

Рисунок 68. Связи таблицы Employees.

 Заполните таблицу Employees данными (Рисунок 69).

Рисунок 69. Данные таблицы Employees.

 Заполните поле Employee таблицы Orders.

После выполнения задания 7 получится диаграмма данных,


представленная на Рисунок 70.
3. ***Создайте таблицу Supplier-Product, которая реализует на
логическом уровне связь типа многие-ко-многим между таблицами Suppliers и
Products (см. лабораторную работу № 1). Самостоятельно заполните ее
данными.

67
Рисунок 70. Диаграмма данных БД TRADEXXX.

Задание 8. Выборка данных из таблиц и представлений

1. Из таблицы Clients выберите все строки, для которых значение поля


ClientName начинается префиксом «ИП» и значение поля Location лежит в
диапазоне от 100 до 110 или неизвестно.
2. Из таблицы Locations выберите все строки, относящиеся к России
или к Беларуси, но не связанные с городом Минском.
3. Из таблицы Products выберите все строки, связанные с валютами
«Доллары США» или «Евро», для которых значение цены товара лежит в
диапазоне от 100 до 300.
4. В таблице Orders найдите все те строки, для которых значение поля
Quantity превышает 25. Однако на экран вместо полей Client и Product
выведите поля ClientName из таблицы Clients и ProductName из таблицы
Products соответственно, которые заменят малоинформативные коды
содержательными наименованиями.

68
5. В таблице Orders найдите все строки, относящиеся к клиентам из
Беларуси, а из них, в свою очередь, выберите те строки, для которых с момента
заказа прошло не более 60 дней. Кроме того, в полученном наборе строк
замените столбец Product столбцом ProductName из таблицы Products.
Результирующий набор строк отсортируйте по наименованием товаров, далее –
по полю OrderDate и далее – по полю Quantity в порядке убывания.
6. Измените представление OrdersCost, добавив в него поле Quantity
из таблицы Orders. Из представления OrdersCost выберите все строки, в
которых значение поля ProductName содержит в себе подстроку «тер» или
«тор» и значение поля Quantity больше или равно 30.
7. Подсчитайте стоимость заказов в белорусских рублях: произведение
трех величин: количество товаров в заказе (поле Quantity таблицы Orders), цена
товара (поле Price таблицы Products), значение курса белорусского рубля (поле
Rate таблицы Currency). Выведите наименование товара (поле ProductName
таблицы Products) и подсчитанную стоимость. Отсортируйте по стоимости.
8. Измените запрос предыдущего задания так, чтобы выводилась общая
сумма стоимости заказов по каждому товару. Для этого сгруппируйте данные
по полю ProductName таблицы Products. Ограничьте количество знаков после
запятой в поле стоимости заказов двумя цифрами.
9. Измените запрос предыдущего задания так, чтобы выводились
наименование только тех товаров, суммарная стоимость которых больше
заданной величины. Используйте для этого предложение HAVING оператора
SELECT.
10. С помощью команды SELECT … INTO создайте копию таблицы
Clients, обязательно включив в новую таблицу поле ClientName. Дайте имя
новой таблице Clients1. Измените значения в ClientName таблицы Clients1 так,
чтобы часть значений наименований клиентов совпадала со значениями
исходной таблицы Clients. Выполните над таблицами Clients и Clients1
операции объединения UNION, пересечения INTERSECT, разности EXCEPT.
Проанализируйте, как влияют ключевые слова DISINCT и ALL на результат
выполнения оператора UNION.
11. Измените таблицу Clients так, чтобы у нескольких клиентов в поле
Location было значение NULL, и чтобы не все регионы имели клиентов, то есть
чтобы в поле внешнего ключа Location отсутствовали некоторые значения из
поля LocationID таблицы Location. Выполните операции внутреннего INNER
JOIN, левого LEFT JOIN, правого RIGHT JOIN, полного FULL JOIN,
перекрестного CROSS JOIN соединений таблиц Clients и Locations.

69
12. *** Выберите из таблицы Employees имена и фамилии всех
руководителей (EmployeeID, Employee.Name, Employee.Surname). Используйте
операцию соединения таблицы с самой собой (самосоединение) (Рисунок 71).
Обратите внимание на псевдонимы (alias) E1 и E2 таблицы Employees,
которые используются в запросе.

Рисунок 71. Операция самосоединения таблицы Employees.


13. *** Подсчитайте, сколько у каждого руководителя подчиненных на
основе данных таблицы Employees. Примените групповую операцию.

Задание 9. Обновление данных в таблицах

1. В таблице Clients замените имя клиента «ГП ”Верас”» на «ГП


”Верас-М”» и фамилию ее руководителя на «Сурков Владимир Петрович».
2. В таблице Products во всех записях, где поле Price в белорусских
рублях, замените код валюты на «EUR», а цену уменьшите в 2,3 раз.
3. В таблице Orders обновите поле DeliveryDate следующим образом:
если дата заказа раньше 15 апреля текущего года, то срок поставки будет
равен дате заказа, увеличенной на 10 дней, однако, после 15 апреля срок
поставки должен быть больше даты заказа только на неделю.
4. Добавьте в таблицу Locations новый регион, расположенный в
Литовской республике. Дайте ему номер 401. Остальные значения выберите
самостоятельно.

Задание10. Удаление данных из таблиц

1. Добавьте приведенные ниже данные в соответствующие таблицы базы


данных с помощью команды INSERT.
Таблица Currency.

70
CurrencyID CurrencyName Rate
GRV Украинские гривны 0,006

Таблица Products
ProductID ProductName Measure Price Currency
666 ПК-клавиатура штука 780 GRV
777 Разъем USB штука 85 GRV
888 Принтер EPSON штука 11650 GRV

Таблица Orders
Clients Product Quantity OrderDate DeliveryDate
4 666 12 по умолчанию по умолчанию
5 777 15 по умолчанию по умолчанию
3 888 5 по умолчанию по умолчанию
5 666 8 по умолчанию по умолчанию

2. Удалите из таблицы Currency строку с кодом валюты GRV


(Украинские гривны).
Замечание. Предварительно проанализируйте свойства связей между
указанными выше таблицами, в частности, разрешено или запрещено каскадное
(CASCADE) удаление данных в таблицах Products и Orders. Свойства связей
между таблицами задаются в команде CREATE TABLE или в команде ALTER
TABLE.

Задание 11. Изменение структуры таблиц и представлений

1. Внесите такие изменения в таблицу Products, чтобы для выполнения


предыдущего задания, связанного с удалением данных из таблиц, достаточно
было использовать только одну команду удаления данных из таблицы
Currency.
2. Внесите изменения в нужные таблицы так, чтобы для выполнения
задания, связанного с удалением данных из таблиц, требовалось обязательное
удаление данные из всех трех таблиц (Orders, Products, Currency).
3. Создайте копию представления OrdersCost с именем OrdersCost1.

Задание 12. Удаления таблиц из базы данных

1. Удалите из базы данных таблицу Orders1.


2. Изучите самостоятельно команду удаления представления (VIEW) из
базы данных и удалите существующее представление OrdersCost1.

71
Сохраните текущий сценарий в файле
D:\FIO\TRADE_XXX\DataManipulation.sql.
Затем удалите базу данных TRADE_ХХХ. Для этого в ее контекстном меню
выберите команду Удалить (Delete) и затем в появившемся окне Удаление
объекта (Delete Object) установите флажок Закрыть существующие
соединения (Close Existing Connections).

72
Лабораторная работа № 5.
Разработка запросов с подзапросами, Case-выражения,
табличные выражения

Подготовительные действия
1. Запуститеутилиту SQL Server Management Studio, в окне
Обозреватель объектов (Object Explorer) в древовидной структуре раскройте
папку Базы данных (Databases).
2. С помощью команды меню File - Open - File загрузите сценарий из
файла D:\FIO\TRADE_XXX\CreateDB_Insert_Data.sql в Окно запросов
(Query).
3. Выполните сценарий, нажав на панели инструментов кнопку
Выполнить (Execute) (или клавишу F5). В результате будет создана база данных
TRADE_ХХХ.
4. Обновите данные в окне Обозреватель объектов (Object Explorer).
Для этого используйте команду Обновить (Refresh) в контекстном меню папки
Базы данных (Databases) или соответствующую кнопку в верхней части окна. В
результате база данных TRADE_ХХХ станет видимой в окне Обозреватель
объектов (Object Explorer).
5. Закройте Окно запросов (Query), содержащее сценарий
CreateDB_Insert_Data.sql. Затем на панели инструментов нажмите кнопку
Новый запрос (New Query), и откройте новое пустое Окно запросов (Query),
предназначенное для формирования нового сценария SubQuery.sql. Сделайте
активной созданную базу данных TRADE_ХХХ:
USE TRADE_ХХХ
GO

Практические задания

Задание 1. Разработка запросов с подзапросами

1. Выведите названия всех предприятий, расположенных в том же


регионе, что и предприятие господина Васько Г.Т. (Рисунок 1Рисунок 72).

73
Рисунок 72. Запрос с однострочным подзапросом.
2. Выведите коды заказов и наименование товаров, количество которых
в заказе больше среднего.

Рисунок 73. Запрос с групповой функцией в подзапросе.


3. Выведите названия и ФИО руководителей всех предприятий,
расположенных в стране Беларусь (Рисунок 74).

Рисунок 74. Запрос с многострочным подзапросом.

74
4. Выведите код, наименование товара и минимальное количество для
товаров, в которых среднее количество в заказе больше, чем у товара с кодом
111 (Рисунок 75).

Рисунок 75. Предложение HAVING в запросах с подзапросами.


5. Выведите поля имя поставщика, его регион, адрес, если в таблице
Locations существуют записи, в которых название страны Беларусь.
Отсортировать записи по городу поставщика (Рисунок 76).

Рисунок 76. Запрос с ключевым словом EXITS.


6. Определите поставщиков, которые поставляют более одного
наименования товара (Рисунок 77).

75
Рисунок 77. Запрос со сложным условием в предложении WHERE.
7. Определить клиентов, имеющих поставщиков в своем регионе
(Рисунок 78).

Рисунок 78. Запрос с ключевым словом ANY.


8. Определить номера заказов и наименование товаров, у которых
количество товара больше или равно, чем количество товара в любом заказе
поставщика с номером 567 (Рисунок 79).

Рисунок 79. Запрос с ключевым словом ANY.

76
9. Вывести из таблицы Employees: всех руководителей, которые сами
являются подчиненными (Рисунок 80) и всех сотрудников, у которых нет
подчиненных (Рисунок 81).

Рисунок 80. Запрос с самосоединением.

Рисунок 81. Запрос с самосоединением.

Задание 2. Разработка запросов с выражением CASE

1. Определить категорию заказа в зависимости от его стоимости


(Рисунок 82):

 1, если стоимость заказа < 2500 руб.


 2, если стоимость заказа >= 2500 руб. и < 5000 руб.
 3, если стоимость заказа >= 5000 руб. и < 7500 руб.
 4, если стоимость заказа >= 7500 руб.

Используется представление OrdersCOST, для него введен псевдоним OC.


Для вывода двух знаков после запятой для значения стоимости заказов
применяется функция CAST. Сортировка выполняется по полю номер 3 в списке
вывода.

77
Рисунок 82. Запрос с выражением CASE.
2. Определить для каждого заказа: его стоимость больше, равна или
меньше средней стоимости всех заказов.

Рисунок 83. Применение выражения CASE с вложенными запросами.


3. Уменьшить стоимость заказа в зависимости от его стоимости:

78
 на 5 %, если стоимость заказа >= 5000 руб. и < = 7500 руб.
 На 10 %, если стоимость заказа >= 7500 руб.
Создадим новую таблицу T_OrderCOST, в которую поместим все записи из
представления OrderCOST.

Рисунок 84. Использование выражения CASE в инструкции UPDATE.

Задание 3. Разработка запросов с табличными выражениями

1. Выбрать все группы месяцев в столбце DeliveryDate таблицы Orders


(Рисунок 85).

79
Рисунок 85. Запрос с табличным выражением в предложении FROM.
2. Выбрать наименования товаров и название валюты, у которых код
валюты равен EUR или BYN.

Рисунок 86. Табличное выражение в списке выбора.

Задания для самостоятельного выполнения

Задание 4. Разработка запросов с подзапросами

1. Выведите названия всех поставщиков, расположенных в том же


районе, что и предприятие господина Бендера О.
2. Выведите наименования тех поставщиков и их адреса, у которых
стоимость товаров в заказе ниже средней.
3. Выведите наименования поставщиков и их адреса, расположенных в
стране Россия и Беларусь.
4. Выведите фамилию, имя, должность сотрудников и среднее число
товаров в заказе, у которых в среднее число товаров в заказе больше, чем у
сотрудника с кодом 1005.
5. Выведите поля Country, Region, City из таблицы Locations, если
в таблице Locations не существуют записи, в которых название страны
Польша.

80
6. Определите поставщиков, которые поставляют только одно
наименование товара.
7. Определите заказы, у которых количество товара МЕНЬШЕ, чем
количество товара в любом заказе клиента с определенным номером.
8. Измените в таблице Clients поле Location на NULL для регионов
страны Украина. Используйте запрос на обновление с подзапросом с
многострочным подзапросом, который определяет коды регионов страны
Украина.

Задание 5. Разработка запросов с выражением CASE

1. Определите категорию товара в зависимости от его цены. Диапазоны


цен для категорий подберите самостоятельно.
2. Определите для каждого товара: его цена больше, равна или меньше
средней цены всех товаров.
3. Увеличьте цену заказа в зависимости от его цены. Диапазоны цен для
увеличения подберите самостоятельно.

Задание 6. Разработка запросов с табличными выражениями

1. Выберите все группы городов в столбце City таблицы Locations.


2. Выберете клиентов и название городов, которые находятся в регионах
с кодами 101 и 102.
3. Выбрать из таблицы Orders поля OrderID и OrderDate для всех
заказов, у которых дата заказа является минимальной. Используйте подзапрос в
предложении WHERE запроса.
Сохраните все команды, разработанные на языке SQL, в файле сценария с
именем D:\FIO\TRADE_XXX\SubQuery.sql.
Затем удалите базу данных TRADE_ХХХ. Для этого в ее контекстном меню
выберите команду Удалить (Delete) и затем в появившемся окне Удаление
объекта (Delete Object) установите флажок Закрыть существующие
соединения (Close Existing Connections).

81
Лабораторная работа № 6.
Программирование на языке Transact-SQL

Подготовительные действия
1. Запуститеутилиту SQL Server Management Studio, в окне
Обозреватель объектов (Object Explorer) в древовидной структуре раскройте
папку Базы данных (Databases).
2. С помощью команды меню File - Open - File загрузите сценарий из
файла D:\FIO\TRADE_XXX\CreateDB_Insert_Data.sql в Окно запросов
(Query).
3. Выполните сценарий, нажав на панели инструментов кнопку
Выполнить (Execute) (или клавишу F5). В результате будет создана база данных
TRADE_ХХХ.
4. Обновите данные в окне Обозреватель объектов (Object Explorer).
Для этого используйте команду Обновить (Refresh) в контекстном меню папки
Базы данных (Databases) или соответствующую кнопку в верхней части окна. В
результате база данных TRADE_ХХХ станет видимой в окне Обозреватель
объектов (Object Explorer).
5. Закройте Окно запросов (Query), содержащее сценарий
CreateDB_Insert_Data.sql. Затем на панели инструментов нажмите кнопку
Новый запрос (New Query), и откройте новое пустое Окно запросов (Query),
предназначенное для формирования нового сценария
StoredProcedures_Functions.sql. Сделайте активной созданную базу данных
TRADE_ХХХ:
USE TRADE_ХХХ
GO

Основы программирования на языке Transact-SQL

Задание 1. Работа с переменные в языке Transact-SQL

Для работы с переменными в языке Transact-SQL нужно эти переменные


объявить и определить их значения.
DECLARE @Code INT, @Name VARCHAR(50), @Price MONEY
Для присвоения значения переменным можно использовать команды SET и
SELECT:

82
SET @Code = 10
SET @Name = ’MS SQL Server’
SET @Price = 299.99
Команда SELECT отличается от команды SET тем, что позволяет присвоить
значения сразу нескольким переменным:
SELECT @Code = 10, @Name = ’MS SQL Server’, @Price = 299.99
Для вывода (на экран монитора) значений переменных также используется
команда SELECT:
SELECT @Code, @Name, @Price
При выводе значений переменных можно снабдить их содержательными
именами. При этом идентификаторы, содержащие недопустимые символы,
такие как ' ' (пробел), '%', '*' и др., должны быть заключены в квадратные
скобки:
SELECT @Code AS [Product Code], @Name AS ProductName, @Price AS
[Product Price]
Связку AS можно при желании опускать:
SELECT @Code [Product Code], @Name ProductName, @Price [Product
Price]
GO
Замечание. Рассмотренные выше переменные являются локальными, т.е.
существуют внутри текущего пакета команд (заканчивающегося командой GO)
и уничтожаются при выходе из него, поэтому все их нужно выполнять
совместно в рамках единого пакета. В отличие от них, глобальные переменные
существуют в контексте всего соединения и записываются не с одним, а с
двумя лидирующими символами @.
Переменным можно присваивать значения полей из таблиц базы данных.
Например:
DECLARE @Code INT, @Name VARCHAR(50), @Price MONEY
SELECT @Code = ProductID, @Name = ProductName, @Price = Price FROM
Products WHERE Currency IN ('USD', 'EUR')
SELECT @Code AS [Product Code], @Name AS ProductName, @Price AS
[Product Price]
GO
Здесь переменные @Code, @Name, @Price получили значения
соответствующих полей последней строки набора данных, выбираемого
командой SELECT (сам набор данных на экран не выводится).

83
1. Если необходимо сохранить в переменных сначала сведения о
продукте с наибольшей, а затем - с наименьшей ценой применительно к кодам
валют USD и EUR, то необходимо выполнить следующую последовательность
команд:
DECLARE @Code INT, @Name VARCHAR(50), @Price MONEY
-- Выборка данных из таблицы Products с сортировкой строк
-- по столбцу Price в порядке возрастания
SELECT @Code = ProductID, @Name = ProductName, @Price = Price
FROM Products
WHERE Cirrency IN ('USD', 'EUR')
ORDER BY Price
2. Вывод данных о товаре с наибольшей ценой
SELECT @Код AS [Product Code], @Name AS ProductName, @Price AS [MAX
Product Price]
-- Выборка данных из таблицы Products с сортировкой строк по столбцу
-- Price в порядке убывания
SELECT @Код = ProductID, @Name = ProductName, @Price = Price
FROM Products
WHERE КодВалюты IN ('USD', 'EUR')
ORDER BY Price DESC
-- DESC указывает на убывающий порядок сортировки
-- Вывод данных о товаре с наименьшей ценой
SELECT @Код AS [Код Productsа], @Name AS ProductName, @Price AS
[MIN Product Price]
GO
3. Можно определить среднюю цену товаров, которые проданы за евро и
доллары (Рисунок 87):

Рисунок 87. Определение средней цены товаров, которые проданы за евро

84
и доллары.
4. Необходимо определить наименование товара, по которому был
наибольший спрос за последние N дней. Один из вариантов решения этой
задачи заключается в выполнении следующей последовательности шагов.
 Объявляются переменные, требуемые для решения данной задачи:
DECLARE @Name VARCHAR(50), @Code INT
DECLARE @Quantity NUMERIC(12,3), @N INT
 Задается значение интервала в днях:
SET @N = 300
Выполняется выборка данных с группировкой по кодам товаров и
подсчетом для каждой группы суммарного количества заказанного товара (т.е.
величины спроса). При этом результирующий набор данных будет
отсортирован в порядке возрастания величины спроса и, следовательно,
последняя его строка будет отображать товар с наибольшим спросом. Результат
выполнения этой команды на экран не выдается, а вместо этого данные
последней строки сохраняются в переменных @Code, @Name и @Quantity:
SELECT @Code = ProductID, @Name = ProductName,
@Quantity = SUM(Quantity)
FROM Orders
WHERE OrderDate BETWEEN GetDate()-@N AND GetDate()
GROUP BY ProductID, ProductName
ORDER BY SUM(Quantity)
 По найденному в предыдущем пункте коду товара с наибольшим
спросом находится соответствующее ему наименование товара:
SELECT @Name = ProductName FROM Products
WHERE ProductID = @Code
 Выдается найденный результат на экран:
SELECT @Name AS [Наименование товара], @Quantity AS [Итоговое
количество], @N AS [Временной интервал]
GO
Замечание. Все команды, рассмотренные на этих пяти шагах,
выполняются в рамках одного пакета (поясняющий текст нужно удалить или
закомментировать) ().

85
Рисунок 88. Определение наименования товара, по которому был
наибольший спрос за последние N дней.
Программный код на языке Transact-SQL может включать в себя также
битовые и логические операторы, операторы перехода (GOTO) и приостановки
(WAITFOR), команды организации ветвлений (IF, CASE) и циклов (WHILE),
операторные скобки (BEGIN...END) и др.

Задание 2. Работа с временными таблицами в языке Transact-SQL

Временные таблицы. Они создаются в системной базе данных tempdb и


бывают двух типов: локальные и глобальные. Локальные временные таблицы
видны только из того соединения, в котором были созданы, и автоматически
уничтожаются при закрытии этого соединения. Глобальные временные
таблицы также уничтожаются при закрытии соединения, в котором были
созданы, однако, когда они существуют, то видны и из любых других
соединений. Это предоставляет удобный механизм для обмена данными между
различными приложениями, например, между различными копиями хранимых
процедур (одна и та же хранимая процедура, запускаемая различными
пользователями, может обращаться к глобальной временной таблице для
получения информации).
Имена локальных временных таблиц начинаются символом #, а
глобальных - двумя символами #.
Примеры создания и использования локальных временных таблиц:
CREATE TABLE #Goods (
ProductID INT PRIMARY KEY,
ProductName VARCHAR(50) NOT NULL,

86
Measure CHAR(10) NULL
)
INSERT #Goods
SELECT ProductID, ProductName, Measure
FROM Products

SELECT * FROM #Goods


GO

SELECT ProductName, Price, Currency


INTO #Goods_2
FROM Products

SELECT * FROM #Goods_2


GO

Задание 3. Создание и работа с хранимыми (на сервере)


процедурами

Хранимые процедуры - это подпрограммы, хранящиеся в базах данных и


представляющие собой один из видов их общих ресурсов.
Заголовок хранимой процедуры содержит название процедуры и,
возможно, ее идентификационный номер, а также может включать в себя как
входные параметры (передающие значения в процедуру), так и выходные
параметры (завершающиеся служебным словом OUTPUT и возвращающие
результат работы процедуры вызывающему программному объекту). Также
можно использовать параметры, которые являются одновременно и входными
и выходными. Кроме того, параметрам можно присваивать значения по
умолчанию, которые могут быть только константами, но не выражениями,
подлежащими вычислению.
Тело хранимой процедуры представляет собой последовательность SQL-
команд, таких, например, как выборка данных (SELECT), их обновление
(UPDATE) или удаление (DELETE), создание объектов базы данных, управление
транзакциями, операторы цикла, условные операторы, вызовы других
хранимых процедур и ряд других. Локальные переменные и локальные
временные таблицы, которые создаются в теле процедуры, автоматически
уничтожаются при выходе из нее, т.е. время их существования ограничено
периодом исполнения команд, составляющих тело процедуры.

87
Процедуры вызываются командой EXEC[UTE], в том числе из процедур,
функций и других типов программных объектов. При вызове процедуры можно
не указывать значения тех параметров, для которых заданы значения по
умолчанию (можно также использовать зарезервированное слово DEDAULT).
Однако при этом нужно придерживаться следующего правила: если значение
какого-либо параметра не указывается (и нет слова DEDAULT), то значения
последующих параметров нужно обязательно сопровождать указанием имен
этих параметров (@parameter = value или @parameter = @variable). Такие
поименованные параметры можно задавать в произвольном порядке.
Необходимость существования хранимых процедур диктуется тем, что не
всякий результат можно получить с помощью одного запроса. Хранимые
процедуры могут содержать большое число команд, а вызываться из
клиентской программы всего одной строкой, что существенно снижает сетевой
трафик. Кроме того, модификация хранимой процедуры приводит к тому, что
сразу все клиентские приложения будут работать с новой редакцией
процедуры.
Синтаксис команды создания хранимой процедуры:

CREATE PROC[EDURE] procedure_name [;number]


[{@parameter data type} [VARYING] [=default] [OUTPUT]] [,...n]
[WITH {RECOMPILE|ENCRYPTION|RECOMPILE|ENCRYPTION}]
[FOR REPLICATION]
AS
sqlstatement [...n]

1. Выбор всех регионов Беларуси:


CREATE PROCEDURE pr_LocationsData;1
AS
SELECT *
FROM Locations
WHERE Country = 'Беларусь'
GO
Проверка работы хранимой процедуры pr_LocationsData;1
EXEC pr_LocationsData;1
GO

88
2. Выбор всех регионов конкретной страны:
CREATE PROCEDURE pr_LocationsData;2
@Country VARCHAR(20) = 'Беларусь'
AS
SELECT *
FROM Locations
WHERE Country = @Country
GO
Проверка работы хранимой процедуры pr_LocationsData;2
-- выбираются регионы Беларуси
EXEC pr_LocationsData;2
-- выбираются регионы России
EXEC pr_LocationsData;2 'Россия'
-- выбираются регионы Украины
EXEC pr_LocationsData;2 'Украина'
GO
3. Выбор регионов, связанных со страной и/или городом
CREATE PROCEDURE pr_LocationsData;3
@Country VARCHAR(20) = 'Беларусь',
@City VARCHAR(20) = NULL
AS
IF @Country IS NOT NULL
BEGIN
IF @City IS NOT NULL
SELECT *FROM Locations
WHERE Country = @Country AND City = @City
ELSE
SELECT *
FROM Locations
WHERE Country = @Country
END
ELSE
IF @City IS NOT NULL
SELECT *

89
FROM Locations
WHERE City = @City
GO
Проверка работы хранимой процедуры pr_LocationsData;3
EXEC pr_LocationsData;3
EXEC pr_LocationsData;3 @City = 'Минск'
EXEC pr_LocationsData;3 DEFAULT, 'Воложин'
EXEC pr_LocationsData;3 'Россия'
EXEC pr_LocationsData;3 NULL, 'Львов'
GO
4. Вставка новой строки в таблицу Currency
CREATE PROCEDURE pr_CurrencyInsertion
@Code CHAR(3),
@Name VARCHAR(30),
@Rate SMALLMONEY = 1000
AS
INSERT INTO Currency
VALUES(@Code, @Name, @Rate)
GO
Проверка работы хранимой процедуры pr_CurrencyInsertion.
EXEC pr_CurrencyInsertion'WWW', 'Валюта страны W'
EXEC pr_CurrencyInsertion'XXX', 'Валюта страны X', 1
EXEC pr_CurrencyInsertion'YYY', 'Валюта страны Y', @Rate=500
EXEC pr_CurrencyInsertion'ZZZ', 'Валюта страны Z', 2500
---------------------------
SELECT * FROM Currency
GO

5. Выбор курса валюты по ее коду


CREATE PROCEDURE pr_CurrencyRateChoice
@Code CHAR(3),
@Rate SMALLMONEY OUTPUT
AS

90
IF @Code IS NOT NULL
SELECT @Rate = Rate
FROM Currency
WHERE CurrencyID = @Code
ELSE
SELECT @Rate = Rate
FROM Currency
WHERE CurrencyID = 'USD'
GO
Проверка работы хранимой процедуры pr_CurrencyRateChoice. Для
каждой проверки создайте новый запрос.
DECLARE @Code CHAR(3), @Course SMALLMONEY
SET @Code = 'EUR'
EXEC pr_CurrencyRateChoice @Code, @Course OUTPUT
SELECT @Code AS [Code валюты], @Course AS [Курс валюты]
-------------------------------------
EXEC pr_CurrencyRateChoice NULL, @Course OUTPUT
SET @Code = 'USD'
SELECT @Code AS [Code валюты], @Course AS [Курс валюты]
GO
6. Выбор имени клиента и ФИО руководителя по коду клиента.
CREATE PROCEDURE рr_ClientData;1
@Code INT,
@ClientName VARCHAR(40) OUTPUT,
@FullName VARCHAR(60) OUTPUT
AS
SELECT @ClientName = ClientName, @FullName = HeadFullName
FROM Clients
WHERE ClientID = @Code
GO
Проверка работы хранимой процедуры рr_ClientData;1
DECLARE @Code INT, @ClientName VARCHAR(40), @FullName VARCHAR(60)
SET @Code = 5
EXEC рr_ClientData;1 @Code, @ClientName OUTPUT, @FullName OUTPUT

91
SELECT @ClientName AS [Имя клиента], @FullName AS [ФИО
руководителя]
GO
7. Выбор данных о клиенте по любому из трех параметров
CREATE PROCEDURE рr_ClientData;2
@Code INT = NULL OUTPUT,
@ClientName VARCHAR(40) = NULL OUTPUT,
@FullName VARCHAR(60) = NULL OUTPUT
AS
IF @Code IS NOT NULL
SELECT @ClientName = ClientName, @FullName = HeadFullName
FROM Clients
WHERE ClientID = @Code
ELSE
IF @ClientName IS NOT NULL
SELECT @Code = ClientID, @FullName = HeadFullName
FROM Clients
WHERE ClientName = @ClientName
ELSE
IF @FullName IS NOT NULL
SELECT @Code = ClientID, @ClientName =
ClientName
FROM Clients
WHERE HeadFullName = @FullName
GO
Проверка работы хранимой процедуры рr_ClientData;2.
DECLARE @Code INT, @Name VARCHAR(40), @FIO VARCHAR(60)
SET @Code = 1
EXEC рr_ClientData;2 @Code, @Name OUTPUT, @FIO OUTPUT
SELECT @Code AS [Code Clientsа], @Name AS [Name Clientsа],
@FIO AS [ФИО руководителя]
---------------------------------------
SET @Code = NULL
SET @Name = 'ИП "Темп"'

92
EXEC рr_ClientData;2 @Code OUTPUT, @Name, @FIO OUTPUT
SELECT @Code AS [Code Clientsа], @Name AS [Name Clientsа],
@FIO AS [ФИО руководителя]
---------------------------------------------
SET @Code = NULL
SET @Name = NULL
SET @FIO = 'Прокушев Станислав Игоревич'
EXEC рr_ClientData;2 @Code OUTPUT, @Name OUTPUT, @FIO
SELECT @Code AS [Code Clientsа], @Name AS [Name Clientsа],
@FIO AS [ФИО руководителя]
GO
8. Процедура создания и наполнения данными глобальной временной
таблицы
CREATE PROCEDURE pr_LocationsCopy
@Country VARCHAR(20) = 'Беларусь',
@City VARCHAR(20) = 'Минск'
AS
IF @Country IS NOT NULL
IF @City IS NOT NULL
SELECT *
INTO ##Locations
FROM Locations
WHERE Country = @Country AND City = @City
GO
Проверка работы хранимой процедуры pr_LocationsCopy.
EXEC pr_LocationsCopy
SELECT * FROM ##Locations

DROP TABLE ##Locations


EXEC pr_LocationsCopy @City = 'Полоцк'
SELECT * FROM ##Locations

DROP TABLE ##Locations


EXEC pr_LocationsCopy DEFAULT, 'Воложин'

93
SELECT * FROM ##Locations

DROP TABLE ##Locations


EXEC pr_LocationsCopy 'Россия', 'Королев'
SELECT * FROM ##Locations
GO

Задание 4. Изменение существующей хранимой процедуры

Для внесения изменений в существующую хранимую процедуру


используется та же команда, что и для ее создания, с тем лишь отличием, что
вместо зарезервированного слова CREATE используется слово ALTER.
9. Изменим, например, текст уже существующей хранимой процедуры
pr_CurrencyRateChoice (выбор курса валюты по ее коду):
ALTER PROCEDURE pr_CurrencyRateChoice
@Code CHAR(3) ='BYN',
@Rate SMALLMONEY OUTPUT
AS
SELECT @Rate = Rate
FROM Currency
WHERE CurrencyID = @Code
GO
Проверка работы скорректированной хранимой процедуры
pr_ВыборКурсаВалюты.
DECLARE @Code CHAR(3), @Course SMALLMONEY
SET @Code = 'EUR'
EXEC pr_CurrencyRateChoice @Code, @Course OUTPUT
SELECT @Code AS [Код валюты], @Course AS [Курс валюты]
GO
------------------------------------------------------
DECLARE @Code CHAR(3), @Course SMALLMONEY
EXEC pr_CurrencyRateChoice DEFAULT, @Course OUTPUT
SET @Code = 'BYN'
SELECT @Code AS [Код валюты], @Course AS [Курс валюты]
GO

94
Задание 5. Удаление хранимой процедуры

Для удаления хранимой процедуры используется команда DROP.


Удалим созданные ранее хранимые процедуры:
DROP PROCEDURE pr_LocationsData
GO
Замечание. Три процедуры pr_LocationsData;1, pr_LocationsData;2,
pr_LocationsData;3 образуют группу одноименных процедур, т.е. процедур,
имеющих одинаковое имя и различающихся лишь идентификационными
номерами. В команде DROP PROCEDURE всегда указывается имя группы
процедур, но не отдельные процедуры, входящие в группу. Будут удалены все
три процедуры, образующие группу.
Необходимо отметить, что, по аналогии с созданием временных таблиц,
можно создавать также временные хранимые процедуры, обладающие той же
областью видимости и тем же временем жизни. Имена локальных временных
хранимых процедур начинаются символом «#», а глобальных - двумя такими
символами.
SQL Server снабжен также несколькими сотнями так называемых
системных хранимых процедур с широким спектром применения, которые
хранятся в системной базе данных master и имеют наименование, включающие
в себя префикс sp_.
В SQL Server реализована возможность использования среды Microsoft
.NET Framework и ее языков программирования C#, VB.NET, J# для
разработки хранимых процедур, пользовательских функций и других объектов
базы данных. Для того, чтобы создать такой объект, нужно сначала создать
DLL-файл в среде разработки MS Visual Studio. После этого нужно
импортировать созданный DLL-файл в базу данных SQL Server. И, наконец,
необходимо связать созданную сборку с хранимой процедурой или функцией,
которая позволит вызывать функции DLL-файла.

Создание и работа с определяемыми пользователем функциями


Помимо использования встроенных функций, пользователи могут
создавать свои собственные функции. Эти функции в отличие от встроенных
являются обычными объектами базы данных, т.е. имеют своего владельца,
который может предоставлять другим пользователям право на их вызов.
Имеется три типа определяемых пользователем функций.
1). Функции типа Scalar. Функции этого типа являются возвращают
скалярное значение любого из типов данных, поддерживаемых сервером, за
исключением TEXT, NTEXT, IMAGE, TIMESTAMP, TABLE и CURSOR. Если

95
функция создается без входных параметров нужно написать пустые скобки
после имени функции.
Команда создания пользовательской функции имеет следующий
синтаксис:
--Transact-SQL Scalar Function Syntax
CREATE FUNCTION [schema_name.] function_name
([{@parameter_name [AS] [type_schema_name.] parameter_data_type
[= default] [READONLY]}
[,...n]
]
)
RETURNS return_data_type
[WITH <function_option> [,...n] ]
[AS]
BEGIN
function_body
RETURN scalar_expression
END
[;]

Задание 6. Создание функции типа Scalar

Рассмотрим функцию типа Scalar, возвращающую курс валюты по ее коду:


CREATE FUNCTION fn_CurrencyRateChoice
(@Code CHAR(3))
RETURNS SMALLMONEY
BEGIN
DECLARE @Course SMALLMONEY --объявляем локальную переменную
@Course
SELECT @Course = Rate
FROM Currency
WHERE CurrencyID = @Code
RETURN @Course --функция возвращает значение переменной @Course
END
GO

96
Проверка работы функции fn_CurrencyRateChoice (Рисунок 89):
DECLARE @Code CHAR(3)
SET @Code = 'USD'
SELECT @Code AS [Код валюты],
dbo.fn_CurrencyRateChoice(@Code) AS [Курс валюты]

Рисунок 89. Проверка работы функции fn_CurrencyRateChoice.


Замечание. При вызове скалярной функции, ее имя должно быть
дополнено именем владельца или именем пользователя, которому
предоставлено право на вызов этой функции.

Задание 7. Создание функции типа Inline Table-valued

Функции типа Inline Table-valued всегда возвращают значения типа


данных table (таблица). Тело функции всегда состоит из одной команды
SELECT. Особенностью функций этого типа является то, что код функции при
выполнении программы вставляется непосредственно в исполняемый набор
команд, т.е. происходит не вызов функции, а встраивание.
Команда создания функции имеет следующий синтаксис:
--Transact-SQL Inline Table-Valued Function Syntax
CREATE FUNCTION [schema_name.] function_name
( [{ @parameter_name [AS] [type_schema_name.] parameter_data_type
[= default] [READONLY] }
[ ,...n]
]
)
RETURNS TABLE
[WITH <function_option> [ ,...n ]]
[AS]

97
RETURN [(]select_stmt[)]
[;]

Рассмотрим функцию типа Inline Table-valued, возвращающую список


заказов по коду валюты:
ALTER FUNCTION fn_SelectionOrdersByCurrency
(@Code CHAR(3))
RETURNS TABLE
AS RETURN
SELECT Orders.*, Products.ProductName, Products.Currency
FROM Orders INNER JOIN Products
ON Orders.Product = Products.ProductID
WHERE Products.Currency = @Code
GO
Проверка работы функции fn_SelectionOrdersByCurrency (Рисунок 90).
SELECT * FROM fn_SelectionOrdersByCurrency ('BYN')
GO

Рисунок 90. Проверка работы функции fn_SelectionOrdersByCurrency.

Задание 8. Создание функции типа Multi-statement Table-valued

Функции типа Multi-statement Table-valued возвращают значение типа


table, однако тело функции этого типа может состоять более чем из одной
команды, что дает возможность использовать в теле функции транзакции,
курсоры, вызывать хранимые процедуры и т.д.
--Transact-SQL Multistatement Table-valued Function Syntax
CREATE FUNCTION [schema_name.] function_name
( [{@parameter_name [AS] [type_schema_name.] parameter_data_type

98
[= default ] [READONLY]}
[ ,...n]
]
)
RETURNS @return_variable TABLE <table_type_definition>
[ WITH <function_option> [ ,...n ]
[AS]
BEGIN
function_body
RETURN
END
[;]

Рассмотрим функцию типа Multi-statement Table-valued,


возвращающую таблицу @CountryRegions с новым столбцом RegionalCenter,
в котором определяется является ли город областным центром. По правилам
заполнения таблицы Locations, если город является областным центром у него
в поле Region находится пустая строка.
CREATE FUNCTION fn_RegionalCenters
(@Country VARCHAR(20))
RETURNS @CountryRegions TABLE (
LocationID INT PRIMARY KEY,
Country VARCHAR(20) NOT NULL,
City VARCHAR(20) NULL,
RegionalCenter BIT NULL)
BEGIN
-- Объявляем локальную переменную @rowset типа таблица
DECLARE @rowset TABLE (
LocationID INT PRIMARY KEY,
Country VARCHAR(20) NOT NULL,
Region VARCHAR(20) NULL,
City VARCHAR(20) NULL,
RegionalCenter BIT DEFAULT 0 NULL)
-- Заносим данные в локальную переменную @rowset
INSERT @rowset (LocationID, Country, Region, City)

99
SELECT LocationID, Country, Region, City
FROM Locations
WHERE Country = @Country
-- Заносим данные в столбец RegionalCenter переменной @rowset
UPDATE @rowset SET RegionalCenter= 1 WHERE Region = ''
-- Заносим данные в результирующую переменную @CountryRegions типа
-- таблица, т.к. локальная переменная @rowset после выхода из
функции
-- автоматически уничтожается
INSERT @CountryRegions
SELECT LocationID, Country, City, RegionalCenter
FROM @rowset
RETURN
END
GO
Проверка работы функции fn_RegionalCenters (Рисунок 91):
SELECT * FROM fn_RegionalCenters('Беларусь')
SELECT * FROM fn_RegionalCenters('Россия')
GO

Рисунок 91. Проверка работы функции fn_RegionalCenters.


Для внесения изменений в существующие пользовательские функции
используются те же команды, что и для их создания, с тем лишь отличием, что
вместо зарезервированного слова CREATE используется слово ALTER.
Для удаления пользовательской функции используется команда DROP
FUNCTION.

100
Задания для самостоятельного выполнения

Задание 9. Разработка хранимой процедуры


pr_GreatestDemandProduct

Создайте хранимую процедуру pr_GreatestDemandProduct, которая


решает рассмотренную выше (см. задание 1, п.4) задачу определения
наименование товара, по которому был наибольший спрос за последние N дней.
Эта процедура должна иметь один входной параметр (@Interval) и два
выходных параметра (@NameProduct, @TotalQuantity).

Задание 10. Разработка хранимой процедуры


pr_ClientsSuppliers_CountryInterval

Создайте хранимую процедуру pr_ClientsSuppliers_CountryInterval,


которая подсчитывает, сколько различных клиентов и различных поставщиков
из указанной страны фигурирует в таблице Orders, причем анализируются
только те заказы, в которых значение поля дата заказа OrderDate попадает в
указанный интервал дат. Эта процедура должна иметь три входных параметра
(@Country, @IntervalStart, @IntervalEnd) и два выходных параметра
(@ClientsNumber, @SuppliersNumber).
Усложненный вариант. Расширьте возможности процедуры следующим
образом: если значение параметра @Country не будет указано (т.е. равно NULL),
то подсчет клиентов и поставщиков должен вестись независимо от их
государственной принадлежности.
Замечание. При необходимости используйте при решении задания
временную таблицу.

Задание 11. Разработка пользовательской функции fn_getOnlyDate

Создайте пользовательскую функцию fn_getOnlyDate типа Scalar,


которая, в отличие от встроенной функции getdate(), возвращающей текущие
дату и время, возвращает только текущую дату (без времени). Эта функция, так
же как и встроенная функция getdate(), не имеет входных параметров и
должна возвращать значение типа DATE.

Задание 12. Разработка пользовательской функции fn_getFullName

Создайте пользовательскую функцию fn_getFullName типа Scalar,


которая на основе текстовой строки, содержащей фамилию, имя и отчество,
формирует текстовую строку, содержащую фамилию и инициалы, и при этом
все строчные буквы должны быть заменены прописными. Эта функция должна

101
иметь один входной параметр (@FullName).
Усложненный вариант. Расширьте возможности функции таким образом,
чтобы была допустима исходная строка (задаваемая параметром @FullName),
содержащая не один, а несколько пробелов между фамилией и именем или
между именем и отчеством, а также допускающая наличие лидирующих
пробелов перед фамилией.

Задание 13. Разработка пользовательской функции


fn_getGroup_ProductNameCurrency

Создайте пользовательскую функцию fn_getGroup_ProductNameCurrency


типа Inline Table-valued, которая возвращает таблицу со следующими
столбцами:
Product Name Currency All Quantity
... ... ...

Эта таблица должна отражать результат группировки данных по полям


ProductName и CurrencyName. Для каждой такой группы подсчитывается
итоговое количество заказанного товара.
Пользовательская функция fn_getGroup_ProductNameCurrency должна
иметь два входных параметра (@IntervalStart, @IntervalEnd), поэтому при
формировании результирующей таблицы необходимо учитывать только те
строки из таблицы Orders, в которых значение поля дата заказа OrderDate
попадает в указанный параметрами интервал дат.

Задание 14. Разработка пользовательской функции fn_getCost_BYN

Создайте пользовательскую функцию fn_getCost_BYN типа Multi-


statement Table-valued, которая возвращает таблицу со следующими
столбцами:

Number ProductName OrderDate Measure Quantity PriceBYN CostBYN

... ... ... ... ... ... ...

Эта таблица строится в два этапа. Сначала создается таблица со столбцами,


показанными выше, где столбец Number является автоинкрементным
первичным ключом, столбцы [PriceBYN] (цена в национальной валюте) и
[CostBYN] (стоимость в национальной валюте) являются вычисляемыми. Число
строк этой таблицы будет равно числу строк в таблице Orders.
На втором этапе из полученной таблицы удаляются все те строки, в

102
которых значение столбца [CostBYN] будет меньше, чем значение входного
параметра функции. В результате будет получена таблица, которую и должна
возвращать данная пользовательская функция. Эта функция должна иметь один
входной параметр граница стоимости (@CostBoundary).

Разработайте программный код для проверки работы созданных хранимых


процедур и пользовательских функций.
Фрагменты кода, относящиеся к выполнению задания, сохраните в файле
D:\FIO\TRADE_XXX\StoredProcedures_Functions.sql.
Затем удалите базу данных TRADE_ХХХ. Для этого в ее контекстном меню
выберите команду Удалить (Delete) и затем в появившемся окне Удаление
объекта (Delete Object) установите флажок Закрыть существующие
соединения (Close Existing Connections).

103
Лабораторная работа № 7.
Разработка курсоров и триггеров

Подготовительные действия
1. Запуститеутилиту SQL Server Management Studio, в окне
Обозреватель объектов (Object Explorer) в древовидной структуре раскройте
папку Базы данных (Databases).
2. С помощью команды меню File - Open - File загрузите сценарий из
файла D:\FIO\TRADE_XXX\CreateDB_Insert_Data.sql в Окно запросов
(Query).
3. Выполните сценарий, нажав на панели инструментов кнопку
Выполнить (Execute) (или клавишу F5). В результате будет создана база данных
TRADE_ХХХ.
4. Обновите данные в окне Обозреватель объектов (Object Explorer).
Для этого используйте команду Обновить (Refresh) в контекстном меню папки
Базы данных (Databases) или соответствующую кнопку в верхней части окна.
В результате база данных TRADE_ХХХ станет видимой в окне Обозреватель
объектов (Object Explorer).
5. Закройте Окно запросов (Query), содержащее сценарий
CreateDB_Insert_Data.sql. Затем на панели инструментов нажмите кнопку
Новый запрос (New Query), и откройте новое пустое Окно запросов (Query),
предназначенное для формирования нового сценария Cursors_Triggers.sql.
Сделайте активной созданную базу данных TRADE_ХХХ:
USE TRADE_ХХХ
GO

Теоретические сведения

Использование курсоров и триггеров в языке Transact-SQL

Курсор можно рассматривать как механизм, предоставляющий


пользователю доступ к любой строке набора данных, связанного с курсором и
формируемого с помощью команды выборки данных SELECT. При этом в
каждый момент времени можно работать только с одной строкой набора
данных. Далее можно перейти к другой строке и т.д.
Существуют статические и динамические курсоры. Статический курсор
представляет собой моментальный снимок выбираемых строк на момент его

104
открытия. В дальнейшем содержимое такого курсора не меняется и хранится в
системной базе данных tempdb.
Динамические курсоры каждый раз обновляются при обращении к его
строкам (т.е. обращение к другой строке формирует набор данных заново путем
выполнения команды SELECT). При работе с динамическими курсорами
пользователи могут вносить изменения в строки набора данных с помощью
команд UPDATE, INSERT, DELETE. Однако каждая такая команда за один раз
может работать только с одной строкой.
Курсоры бывают последовательные (Forward-only) и прокручиваемые
(Scrollable). Последовательные курсоры обеспечивают только
последовательное считывание строк в прямом направлении, т.е. начиная с
первой строки и заканчивая последней.
Прокручиваемые курсоры обеспечивают как последовательное считывание
строк в обоих направлениях (прямом и обратном), так и обращение к
произвольной строке набора данных. Однако они работают медленнее, чем
последовательные курсоры.
Весь процесс работы с курсором включает в себя пять этапов.
1. Объявление курсора. Подразумевает указание его имени и запроса
SELECT, который будет использоваться для формирования набора данных,
связанного с курсором. Синтаксис Transact-SQL:
DECLARE cursor_name CURSOR
[LOCAL|GLOBAL]
[FORWARD_ONLY|SCROLL]
[STATIC|KEYSET|DYNAMIC|FAST_FORWARD]
[READ_ONLY|SCROLL_LOCKS|OPTIMISTIC]
[TYPE_WARNING]
FOR select_statement
[FOR UPDATE[OF column_name[,...n]]]
2. Открытие курсора. В процессе открытия курсора выполняется
ассоциированный с курсором запрос SELECT, в результате чего создается
связанный с курсором набор данных. Команда имеет следующий синтаксис:
OPEN{{[GLOBAL]cursor_name}|cursor_variable_name}
3. Манипуляции со строками курсора. После того, как курсор открыт,
можно приступать к выборке данных из этого курсора, а если тип курсора
позволяет, то и к операциям обновления и удаления данных.
Команда считывания строки данных из курсора имеет следующий
синтаксис:

105
FETCH
[[NEXT|PRIOR|FIRST|LAST
|ABSOLUTE{n|@nvar}
|RELATIVE{n|@nvar}
]
FROM
]
{{[GLOBAL]cursor_name}|@cursor_variable_name}
[INTO @variable_name[,...n]]
Замечание. Непосредственно после слова FETCH опцией указывается
строка, которую нужно выбирать, поэтому сначала эта строка становится
текущей, и только после этого производится выборка данных. При этом
возможен выход за пределы диапазона строк набора данных. Эту ситуацию
можно контролировать с помощью встроенной функции @@FETCH_STATUS,
которая возвращает значение 0, если последняя операция выборки данных из
курсора была выполнена успешно. Если возвращается отрицательное значение,
то это означает, что была предпринята попытка выборки строки, находящейся
за пределами набора данных.
Можно также использовать функцию @@CURSOR_ROWS. Она возвращает
количество строк набора данных, но только для статического курсора. Для
динамического курсора всегда возвращается -1.
Обновление данных посредством курсора выполняется с помощью
команды UPDATE, имеющей следующий синтаксис:
UPDATE table_name
SET {column_name = {expression|DEFAULT|NULL}}[,...n]
WHERE CURRENT OF cursor_name
Изменения, внесенные этой командой, будут касаться только текущей
строки курсора. За одну операцию обновления данных допускается изменение
значений полей, относящихся к одной таблице. Если курсор строится на основе
нескольких таблиц и необходимо изменить все значения строки курсора, то для
этого придется выполнить несколько команд UPDATE.
Кроме того, допускается изменение любых столбцов таблицы, в том числе
и не входящих в набор данных курсора.
Удаление данных посредством курсора выполняется с помощью команды
DELETE, имеющей следующий синтаксис:
DELETE [FROM] table_name

106
WHERE CURRENT OF cursor_name
При выполнении этой команды происходит удаление строки указанной
таблицы, связанной с текущей строкой курсора. Если курсор строится на
основе нескольких таблиц, то для удаления данных из этих таблиц необходимо
выполнить команду DELETE отдельно для каждой таблицы.
4. Закрытие курсора. После того, как были выполнены все
необходимые манипуляции со строками курсора, его можно закрыть. Это
приводит к высвобождению выделенных для него ресурсов (например,
пространства в системной базе данных tempdb) и снятию блокировок, если они
были установлены в процессе работы курсора. Команда имеет следующий
синтаксис:
CLOSE {{[GLOBAL]cursor_name}|cursor_variable_name}
5. Освобождение курсора. Закрытый курсор может быть удален, что
подразумевает удаление из оперативной памяти описания курсора как объекта.
Если курсор закрыт, но не удален, он может быть повторно открыт для
использования. При этом в него будет помещен новый набор данных.
Команда освобождения курсора имеет следующий синтаксис:
DEALLOCATE {{[GLOBAL]cursor_name}|@cursor_variable_name}

Задание 1. Работа с курсорами в языке Transact-SQL

Подсчитать суммарную стоимость в национальной валюте


(белорусских рублях) всех товаров, заказанных в течение указанного
интервала времени.
Одним из вариантов решения этой задачи будет создание хранимой
процедуры pr_COST_BYN_Interval с двумя входными параметрами
(@IntervalStart, @IntervalEnd) и одним выходным параметром
(@CostBYR).
/*Подсчет стоимости товаров в национальной валюте*/
CREATE PROCEDURE pr_COST_BYN_Interval
@IntervalStart DATE,
@IntervalEnd DATE,
@CostBYR MONEY OUTPUT AS
/*Так как переменные @IntervalStart, @IntervalEnd, хранящие значения даты
начала и даты завершения интервала отбора данных имеют тип данных DATE, а функция
GETDATE() возвращает значение в формате DATETIME, то необходимо выполнить
преобразование типов данных с помощью функции CAST().*/

107
IF @IntervalStart IS NULL
SET @IntervalStart = CAST(GETDATE() - 100 AS DATE)
IF @IntervalEnd IS NULL
SET @IntervalEnd = CAST(GETDATE() AS DATE)
-- выполняем начальную установку
SET @CostBYR = 0
-- объявляем локальную переменную @СтоимостьЗаказа
DECLARE @OrderCost MONEY
-- объявляем курсор myCursor. При этом набор данных, связанный
-- с курсором, будет содержать всего один столбец
DECLARE myCursor CURSOR LOCAL STATIC FOR
SELECT Orders.Quantity * Products.Price * Currency.Rate FROM Orders
INNER JOIN Products ON Orders.Product = Products.ProductID
INNER JOIN Currency ON Products.Currency = Currency.CurrencyID
WHERE Orders.OrderDate BETWEEN @IntervalStart AND
@IntervalEnd
-- открываем курсор
OPEN myCursor
-- заносим в курсор значение первой строки набора данных и
-- считываем это значение в переменную, которая хранит стоимость заказа @OrderCost
FETCH FIRST FROM myCursor INTO @OrderCost
-- организуем цикл, необходимый для последовательной работы с остальными строками
-- набора данных с целью получения суммы стоимостей заказов в национальной валюте
WHILE @@FETCH_STATUS = 0
BEGIN
SET @CostBYR = @CostBYR + @OrderCost
FETCH NEXT FROM myCursor INTO @OrderCost
END
-- Опцию NEXT (переход к следующей строке) в команде FETCH можно -- опускать,
--т. к. она подразумевается по умолчанию
-- закрываем курсор
CLOSE myCursor
-- освобождаем курсор
DEALLOCATE myCursor
GO

108
Проверка работы хранимой процедуры pr_COST_BYN_Interval.
Значения для переменных @IntervalStart, @IntervalEnd,
определяющих дату начала и дату завершения временного интервала при
вызове функции не определены, поэтому они получат значения, определенные
в теле функции. Это будет интервал, начинающийся за 100 дней от текущей
даты и завершающийся текущей датой (Рисунок 92).

Рисунок 92. Проверка работы хранимой процедуры


pr_COST_BYN_Interval.
Значения для переменных @IntervalStart, @IntervalEnd,
определяющих дату начала и дату завершения временного интервала при
вызове функции определены через значения передаваемых фактических
параметров (Рисунок 93Рисунок 92).

Рисунок 93. Проверка работы хранимой процедуры


pr_COST_BYN_Interval.

Задание 2. Разработка триггеров в языке Transact-SQL

Триггеры представляют собой хранящиеся в базах данных подпрограммы


на языке SQL, выполняющиеся автоматически при операциях вставки,
обновления и удаления данных в таблицах базы данных.
Каждый триггер связан только с одной из таблиц базы данных.

109
Автоматическое срабатывание триггеров в ответ на изменения табличных
данных позволяет использовать их, например, для реализации сложных
алгоритмов проверки данных, для обеспечения правильности и достоверности
данных, для создания сложного значения по умолчанию (вычисляя его с
помощью значений других столбцов и функций языка Transact-SQL), для
обеспечения нестандартной ссылочной целостности, поддержания которой
обычными средствами SQL Server невозможно и т.д.
Использование триггеров превращает сервер из пассивного наблюдателя за
происходящими изменениями данных, в систему, оперативно реагирующую на
такие изменения. Таким образом, правила, в соответствие с которыми
осуществляются активные действия сервера, определяются триггерами (эти
правила называют также бизнес-правилами).
В MS SQL Server существует два вида триггеров:
AFTER-триггеры, которые запускаются после успешного выполнения
команд, связанных с изменением табличных данных. Как команда, так и
триггер реализуются в рамках одной и той же транзакции. Поэтому откат при
выполнении триггера приведет и к откату команды, вызвавшей его запуск.
AFTER-триггеры широко используются и полезны, например, в тех случаях,
когда при модификации строк необходимо сравнивать исходные значения
полей с их новыми значениями. С каждой таблицей может быть связано не
более трех AFTER-триггеров (по одному для каждой из команд INSERT,
UPDATE, DELETE).
INSTEAD OF-триггеры, тело которых выполняется вместо операций
вставки, обновления и удаления строк, вызвавших запуск триггера этого вида.
Синтаксис команды создания триггера:
CREATE TRIGGER trigger_name
ON {table}
[WITH ENCRYPTION]
{
{FOR [{AFTER|INSTEAD OF}]
{[DELETE][,][INSERT][,][UPDATE]}
[WITH APPEND]
[NOT FOR REPLICATION]
AS
[{IF UPDATE (column)
[{AND|OR} UPDATE (column)]
[...n]

110
|IF(COLUMNS_UPDATED())
{comparison operator}
}]
sql statement[...n]
}
}
В этой команде, в частности, присутствуют функции UPDATE(column) и
COLUMNS_UPDATED(), используемые для определения того, какой столбец или
группу столбцов пользователь пытается изменить. Кроме того, всегда можно
получить полную информацию об изменениях, которые пытается произвести
пользователь. Эту информацию дают таблицы inserted и deleted, которые
автоматически создаются сервером при запуске триггера. Содержимое этих
таблиц зависит от команды, вызвавшей запуск триггера:
Команда INSERT. В таблице inserted будут содержаться все строки,
которые пользователь пытается Вставьте в таблицу. Таблица deleted будет
пуста.
• Команда DELETE. В таблице deleted будут содержаться все строки,
которые пользователь пытается удалить. Таблица inserted будет пуста.
• Команда UPDATE. В таблице deleted будут содержаться все строки,
которые пользователь пытается изменить. В таблице inserted указываются
строки, которые будут внесены в таблицу вместо соответствующих строк
таблицы deleted.
Для внесения изменений в текст существующего триггера используется та
же команда, что и для его создания, с тем лишь отличием, что вместо
зарезервированного слова CREATE используется слово ALTER.
Для удаления триггера используется команда, имеющая следующий
синтаксис:
DROP TRIGGER {trigger} [,...n]
В кодах триггеров часто используется команда ROLLBACK TRAN (отмена или
откат транзакции). Кроме нее в программах на языке Transact-SQL
используются также команды BEGIN TRAN (старт транзакции), COMMIT TRAN
(подтверждение транзакции) и SAVE TRAN (создание точки сохранения
транзакции).
Например, отладку какой-нибудь команды или фрагмента программы,
вносящих изменения в данные, можно начать со старта транзакции, а в самом
конце выполнить команду ROLLBACK TRAN, восстановив тем самым
первоначальные значения измененных данных (Рисунок 94).

111
Рисунок 94. Пример работы команды ROLLBACK TRAN.
Рассмотрим два примера по созданию триггеров.
Пример 1. Запретим с помощью триггера возможность модификации
данных в столбце OrderDate таблицы Orders.
CREATE TRIGGER tr_NoModify_OrderDate
ON Orders
FOR UPDATE AS
IF UPDATE(OrderDate)
BEGIN
PRINT 'Обновление столбца OrderDate запрещено'
ROLLBACK TRAN -- откат транзакции
END
GO
Замечание. Команда PRINT в отличие от команды SELECT выводит
сообщения не на панель Results, а не на панель Messages окна Query утилиты
SQL Server Management Studio.
Теперь, несмотря на то, что вы являетесь владельцем базы данных, вы уже

112
не можете редактировать значения столбца OrderDate в таблице Orders:

Рисунок 95. Проверка работы триггера tr_NoModify_OrderDate.


Удалите созданный триггер tr_NoModify_OrderDate и проверьте, что
изменение даты заказа снова возможно.
DROP TRIGGER tr_NoModify_OrderDate
Пример 2. Для реализации следующего триггера добавим в таблицу
Orders два новых столбца Cost и CostBYN:
ALTER TABLE Orders ADD Cost MONEY NULL
ALTER TABLE Orders ADD CostBYN MONEY NULL
---
SELECT * FROM Orders
GO
Убедимся, что столбцы Cost и CostBYN (стоимость в национальной
валюте) добавились в таблицу Orders и во всех строках получили значение
NULL:

113
Рисунок 96. Добавление новых столбцов в таблицу Orders.
Создадим триггер для таблицы Products, срабатывающий при любом
изменении цены товара и корректирующий в таблице Orders значения полей
Cost и CostBYN в тех строках, которые соответствуют товару с изменившейся
ценой:
CREATE TRIGGER tr_ProductPrice
ON Products
FOR UPDATE AS
IF UPDATE(Price)
BEGIN
-- объявляем локальные переменные
DECLARE @ProductCode INT, @Price MONEY, @PriceBYN MONEY
-- присваиваем значения локальным переменным, выбирая эти значения из таблицы inserted
SELECT @ProductCode = inserted.ProductID,
@Price = inserted.Price, @PriceBYN = inserted.Price * Currency.Rate
FROM inserteD INNER JOIN Currency
ON inserted.Currency = Currency.CurrencyID
-- обновляем значения стоимостей в таблице Orders
UPDATE Orders
SET Cost = Quantity * @Price,
CostBYN = Quantity * @PriceBYN
WHERE Product = @ProductCode
END
GO
Проверим работу созданного триггера. Для этого изменим цену товара с
кодом 111 (Рисунок 97).

114
Рисунок 97. Проверка работы триггера tr_ProductPrice.
Однако данный триггер обладает тем недостатком, что отслеживает
изменение цены лишь одного товара, даже если были одновременно изменены
цены сразу у нескольких товаров. Убедимся в этом, изменив цены сразу для
всех товаров ().

115
Рисунок 98. Триггер tr_ProductPrice изменяет стоимость только одного
товара, первого по списку в таблице Products.
Устраним указанный выше недостаток путем внесения изменения в код
триггера:
CREATE TRIGGER tr_ProductsPrice_AllGoods
ON Products
FOR UPDATE AS
IF UPDATE(Price)
BEGIN
DECLARE @ProductCode INT, @Price MONEY, @PriceBYN MONEY
-- объявляем курсор myCursor. Набор данных, связанный с курсором и
-- построенный на основе таблицы inserted, будет содержать три столбца
DECLARE myCursor CURSOR LOCAL STATIC FOR
SELECT inserted.ProductID, inserted.Price,
inserted.Price * Currency.Rate
FROM inserteD INNER JOIN Currency

116
ON inserted.Currency = Currency.CurrencyID
-- открываем курсор
OPEN myCursor
-- заносим в курсор данные первой строки набора данных и считываем
-- значения ее полей в переменные @ProductCode, @Price, @PriceBYN
FETCH FIRST FROM myCursor INTO @ProductCode, @Price, @PriceBYN
-- организуем цикл, необходимый для последовательной работы с остальными
-- строками набора данных с целью обновления стоимостей в таблице Orders
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE Orders
SET Cost = Quantity * @Price,
CostBYN = Quantity * @PriceBYN
WHERE Product = @ProductCode
FETCH NEXT FROM myCursor INTO @ProductCode, @Price, @PriceBYN
END
-- закрываем курсор
CLOSE myCursor
-- освобождаем курсор
DEALLOCATE myCursor
END
GO
Проверим работу триггера, снова изменив цены сразу для всех товаров,
после чего убедимся, что пересчитались стоимости всех заказов,
представленных строками таблицы Orders ().

117
Рисунок 99. Проверка работы триггера tr_ProductsPrice_AllGoods

Задания для самостоятельного выполнения


Задание 3. Разработка хранимой процедуры
pr_Cost_CurrencyInterval

Создайте хранимую процедуру pr_Cost_CurrencyInterval для решения


более общей задачи по сравнению с задачей, рассмотренной в задании 1, а
именно: необходимо подсчитать суммарную стоимость всех товаров,
заказанных в течение указанного интервала времени, однако не в национальной
валюте, а в валюте, указанной пользователем (в частности, может быть указана
и национальная валюта). Эта процедура должна иметь три входных параметра
(@CurrencyCode, @IntervalStart, @IntervalEnd) и один выходной
параметр (@Cost).

118
Задание 4. Разработка хранимой процедуры
pr_Country_Clients_Suppliers

Добавьте в таблицу Locations две новые строки, используя следующие


команды:
INSERT INTO Locations
VALUES (102, ’Россия’, ’’, ’Москва’, ’пр.Калинина, 50’,
’339-62- 10’, ’(495) 339-62-11’)
INSERT INTO Locations
VALUES (401, ’Литва’, ’’, ’Вильнюс’, ’ул.Чурлёниса, 19’,
NULL, ’(372) 33-27-75’)
GO
Разработайте программный код pr_Country_Clients_Suppliers,
который формирует таблицу следующего вида:

Country ClientsNumber SuppliersNumber


. . . . . . . . .

При этом используйте созданную при выполнении лабораторной работы


хранимую процедуру pr_ClientSupplier_CountryInterval, которая
подсчитывает, сколько различных клиентов и поставщиков из указанной
страны фигурирует в таблице Orders (за указанный интервал времени). Эта
хранимая процедура должна применяться для формирования каждой строки в
указанной выше таблице. Число строк этой таблицы должно равняться числу
различных стран, фигурирующих в таблице Locations.

Задание 5. Создание таблицы Protocol

Создайте таблицу Protocol со структурой, приведенной ниже, в которой


должны автоматически фиксироваться все действия, вызванные вставкой,
обновлением или удалением данных в таблице Products. Каждая команда,
изменяющая содержимое таблицы Products, должна быть отражена отдельной
строкой в таблице Protocol.

ID DateTime User Action RowNumber


. . . . . . . . . . . . . . .

Здесь столбец ID является автоинкрементным первичным ключом. В


столбце Action указывается одна из трех возможных операций с данными:
«Insert», «Update», «Delete». Столбец RowNumber будет содержать данные о
числе вставленных, либо обновленных, либо удаленных строк в таблице

119
Products.
Усложненный вариант. Таблица Protocol должна включать в себя еще
один столбец ProductID, в котором указываются коды товаров, фигурирующие
во вставленных, обновленных или удаленных строках.

Задание 6. Доработка триггера tr_ProductsPrice_AllGoods

Доведите до завершения рассмотренную выше в виде примера задачу


корректировки значений полей Cost и CostBYN в таблице Orders. Значения
этих полей должны автоматически обновляться не только при изменении цены
товара (как было реализовано в примере), но и при изменении количества
заказанного товара, а также вставке новых строк в таблицу Orders. Кроме того,
значение столбца CostBYN должно автоматически обновляться также при
изменении курса соответствующей валюты.

Разработайте программный код для проверки работы разработанных


хранимых процедур и триггеров.
Фрагменты кода, относящиеся к выполнению задания, сохраните в файле
D:\FIO\TRADE_XXX\Cursors_Triggers.sql.
Затем удалите базу данных TRADE_ХХХ. Для этого в ее контекстном меню
выберите команду Удалить (Delete) и затем в появившемся окне Удаление
объекта (Delete Object) установите флажок Закрыть существующие
соединения (Close Existing Connections).

120
Лабораторная работа № 8.
Администрирование БД в MS SQL Server

Управление пользователями базы данных


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

Теоретические сведения

Управление пользователями в среде MS SQL Server


После проектирования логической структуры базы данных, связей между
таблицами, ограничений целостности и других структур необходимо
определить круг пользователей, которые будут иметь доступ к базе данных.
В системе MS SQL Server организована двухуровневая настройка
ограничения доступа к данным. На первом уровне необходимо создать так
называемую учетную запись пользователя (login), что позволяет ему
подключиться к самому серверу, но не дает автоматического доступа к базам
данных. На втором уровне для каждой базы данных MS SQL Server на
основании учетной записи необходимо создать запись пользователя. На основе
прав, выданных пользователю как пользователю базы данных (user), его
регистрационное имя (login) получает доступ к соответствующей базе
данных. В разных базах данных login одного и того же пользователя может
иметь одинаковые или разные имена user с разными правами доступа. Иначе
говоря, с помощью учетной записи пользователя осуществляется подключение
к MS SQL Server, после чего определяются его уровни доступа для каждой базы
данных в отдельности.
В системе MS SQL Server существуют дополнительные объекты – роли,
которые определяют уровень доступа к объектам MS SQL Server. Они
разделены на две группы: назначаемые для учетных записей пользователя
сервера и используемые для ограничения доступа к объектам базы данных.
Итак, на уровне сервера система безопасности оперирует следующими

121
понятиями:

• аутентификация;
• учетная запись;
• встроенные роли сервера.
На уровне базы данных применяются следующие понятия;
• пользователь базы данных;
• фиксированная роль базы данных;
• пользовательская роль базы данных.
Режимы аутентификации
MS SQL Server предлагает два режима аутентификации пользователей:
• режим аутентификации средствами Windows;
• смешанный режим аутентификации (Windows NT Authentication and
SQL Server Authentication).

Управление пользователями и правами доступа к данным


инструментальными средствами

1. Запустите утилиту SQL Server Management Studio. На панели


Обозреватель объектов (Object Explorer) в дереве структуры раскройте папку
Базы данных (Databases).
2. Присоедините базу данных TRADE_ХХХ, для чего выберите в
контекстном меню папки Базы данных (Databases) команду Присоединить базу
данных (Attach Database), затем в появившемся окне нажмите кнопку
Присоединить (Append) и далее укажите местоположение первичного файла
данных (т.е. файла данных с расширением .mdf). Убедитесь, что база данных
TRADE_ХХХ появилась в папке Базы данных (Databases).
3. На панели Обозреватель объектов (Object Explorer) откройте папку
Безопасность (Security) и выберите в ней строку Имена входа (Logins). При
этом будет представлен список регистрационных записей MS SQL Server (в
котором отображаются, например, те учетные записи домена ОС Windows,
которым разрешен доступ к серверу).
Создайте для MS SQL Server новую регистрационную запись
ComputerName/User1 следующим образом. Выберите в контекстном меню
строки Имена входа (Logins) команду Создать имя входа (New Login) и
откройте окно Создание имени входа (Login – New). На странице Общие
(General) нажмите кнопку Найти (Search) (три точки - справа от поля ввода Имя
входа (Login name), затем в окне Пользователь или Группа (User or Group)

122
нажмите кнопку Дополнительно (Additionally), в следующем окне нажмите
кнопку Поиск (Search) и выберите из списка существующую учетную запись
ОС Windows с именем ComputerName/User1 и вставьте ее в поле ввода Имя
входа (Login name). В качестве базы данных по умолчанию выберите
TRADE_ХХХ (Рисунок 100).

Рисунок 100. Создание имени входа

На странице Роли сервера (Server Roles) установите флажок dbcreator,


предоставляя тем самым пользователю с учетной записью
ComputerName/User1 право создавать новые базы данных и их объекты
(другими словами, включите данную учетную запись в фиксированную роль
сервера dbcreator (Рисунок 101).

123
Рисунок 101. Назначение фиксированной роли сервера dbcreator
На странице Сопоставление пользователей (Database Access) установите
в верхнем списке флажок TRADE_ХХХ, а в нижнем списке - флажок
db_accessadmin (Рисунок 102), разрешив тем самым пользователю с данной
учетной записью управлять добавлением или удалением пользователей в базе
данных TRADE_ХХХ (другими словами, включите данную учетную запись в
фиксированную роль db_accessadmin базы данных TRADE_ХХХ).

124
Рисунок 102. Включение учетной записи в фиксированную роль
db_accessadmin базы данных TRADE_ХХХ.
Завершите создание регистрационной записи ComputerName/User1
щелчком на кнопке OK.
Аналогичным образом создайте для SQL Server регистрационные записи
ComputerName/User2, ComputerName/User3, ComputerName/User4 при этом,
однако, не включайте соответствующие им учетные записи Windows ни в одну
из фиксированных ролей сервера и ни в одну из фиксированных ролей базы
данных TRADE_ХХХ (однако на странице Database Access флажок TRADE_ХХХ в
верхнем списке должен быть установлен).
Примечание. Регистрационные записи SQL Server определяют перечень
тех пользователей и групп пользователей операционной системы OC Windows,
которые будут иметь доступ к данному SQL Server.
4. На панели Инспектор объектов (Object Explorer) раскройте элемент
TRADE_ХХХ и далее подчиненную ему папку Security. Затем выберите

125
появившуюся папку Пользователи (Users) и убедитесь, что сервер создал
новых пользователей ComputerName/User2, ComputerName/User3,
ComputerName/User4 (другими словами, отобразил учетные записи OC
Windows ComputerName/User2, ComputerName/User3, ComputerName/User4
пользователей базы данных TRADE_ХХХ с такими же именами).
5. Для базы данных TRADE_ХХХ создайте три пользовательские роли
(Рисунок 103) (на уровне роли можно легко менять привилегии пользователей-
членов роли). Для этого в контекстном меню папки Безопасность (Security) -
Роли (Roles) базы данных TRADE_ХХХ, выберите команду Создать
(New) - Создать роль базы данных (New Database Role) и откройте окно Роль
базы данных – Создание (Database Role – New).

Рисунок 103. Создание пользовательской роли


6. Затем введите в поле Имя роли (Role name) имя новой роли как
Главный бухгалтер, а в поле Владелец (Owner)) - значение dbo (Рисунок

126
104). Далее нажмите кнопку Добавить (Add), затем кнопку Поиск (Browse) и
установите флажок в строке ComputerName/User1 (Рисунок 105), завершая
выбор двумя нажатиями кнопки ОК. После этого закройте окно Роль базы
данных – Создание (Database Role – New) с помощью кнопки ОК.

Рисунок 104. Окно поиска владельца БД

Рисунок 105. Назначение роли пользователю


Аналогичным образом создайте пользовательскую роль с именем
Бухгалтер, проставляя флажки в строках членов роли для пользователя
ComputerName/User2 и роли Главный бухгалтер (Рисунок 106).

127
Рисунок 106. Создание пользовательской роли с именем Бухгалтер
Далее создайте пользовательскую роль с именем Экономист, проставляя
флажки в строках ComputerName/User3 и Главный бухгалтер.
Примечание! В SQL Server любой отдельный пользователь
(представляющий, в свою очередь, одного или группу пользователей ОС
Windows), а также любая отдельная роль может входить в состав нескольких
ролей. В свою очередь каждая роль может включать в качестве своих членов
несколько пользователей и ролей. В результате пользователи наследуют
привилегии, установленные во всех ролях, в которые они входят (прямо, либо
косвенно через другие роли).
В нашем случае пользователь ComputerName/User1, помимо привилегий
роли Главный бухгалтер, будет обладать также привилегиями ролей
Бухгалтер и Экономист, в то время как пользователь ComputerName/User2
будет обладать только привилегиями роли Бухгалтер, а пользователь
ComputerName/User3 - только привилегиями роли Экономист.

128
Примечание 2. В любой базе данных автоматически создается
пользователь с именем dbo (database owner), являющийся ее владельцем, также,
как и все члены фиксированной роли базы данных db_owner. Пользователь dbo
имеет абсолютные права по управлению базой данных и его нельзя удалить.
Кроме того, пользователь dbo включен в роль db_owner и не может быть
удален из нее.
Примечание З. Имеется фиксированная роль базы данных public со
специальными функциями. В эту роль нельзя включать пользователей, т.к.
любой пользователь, созданный в базе данных, автоматически включается в
роль public, и нет никакой возможности исключить его из этой роли. Роль
public предназначена для предоставления привилегий по умолчанию всем
пользователям, имеющим доступ к данной базе данных.
7. Задайте привилегии для пользовательских ролей базы данных
TRADE_ХХХ. Для этого в контекстном меню роли Главный бухгалтер выберите
команду Свойства (Properties) (и откройте окно Свойства ролей базы данных
(Database Role Properties) – Главный бухгалтер.
Перейдите на страницу Защищаемые объекты (Protected objects),
выберите через кнопку Поиск (Browse) флажок Определенные объекты...,
нажмите кнопку ОК, в окне поставьте галочки около Таблицы и
Представления, далее нажмите кнопку Обзор, выделите все таблицы БД
TRADE_ХХХ и представление OrdersCost (Рисунок 107).

129
Рисунок 107. Определение привилегий для пользовательских ролей БД
Для таблицы Currency установите привилегии Выборка (Select), Вставка
(Insert), Обновление (Update), Удаление (Delete). Для таблицы Orders
установите привилегию Обновление (Update), а для представления
OrdersCost - привилегию Выборка (Select). Для каждой из таблиц Clients,
Suppliers, Products установите привилегии Обновление (Update) и Удаление
(Delete). Далее, выбрав таблицу Orders, выбрав разрешение Обновление
(Update) нажмите кнопку Разрешение на доступ к столбцу (Column
Permissions)) и в появившемся окне запретите привилегию Обновление
(Update) для столбцов OrderDate и DeliveryDate (Рисунок 108).

130
Рисунок 108. Разрешения на доступ к столбцам
По аналогии задайте привилегии для других пользовательских ролей.
Для роли Бухгалтер каждая из таблиц Orders, Clients должна иметь
привилегии Выборка (Select) и Вставка (Insert).
Для роли Экономист каждая из таблиц Suppliers, Products должна иметь
привилегии Выборка (Select) и Вставка (Insert)..
Кроме того, для роли public таблица Locations должна иметь привилегии
Выборка (Select), Вставка (Insert), Обновление (Update), Удаление (Delete).
Примечание. Запрещение привилегии имеет более высокий приоритет,
чем предоставление привилегии. Если пользователю запрещена привилегия на
доступ к тому или иному объекту, то система безопасности SQL Server
гарантирует, что пользователь не будет иметь ее, даже если она была
предоставлена ему через членство в любой другой роли базы данных или
группе пользователей ОС Windows.
8. Завершите сеанс работы с ОС Windows под текущей учетной записью
и стартуйте сеанс под учетной записью ComputerName/User1.
При помощи пользовательского меню ОС Windows запустите утилиту SQL
Server Management Studio.
В этом случае будем говорить, что установлено соединение c сервером
базы данных от имени пользователя с учетной записью ComputerName/User1.
Убедитесь, что сейчас вы, применительно к базе данных TRADE_ХХХ,
обладаете привилегиями роли Главный бухгалтер, т.е. вы можете выполнять

131
все действия с таблицами Currency, Clients, Suppliers, Locations, Products, а
также все действия с таблицей Orders за исключением удаления строк и
обновления полей OrderDate и DeliveryDate. Также можно просматривать
данные представления OrdersCost.
Примечание. Ряд привилегий оказываются доступными благодаря
членству роли Главный бухгалтер в ролях Бухгалтера, Экономисты и public.
Кроме того, поскольку данная учетная запись является членом
фиксированной роли сервера dbcreators, то предоставлено право создавать
новые базы данных и их объекты.
Также предоставлено право управлять добавлением или удалением
пользователей в базе данных TRADE_ХХХ, поскольку данная учетная запись
включена в фиксированную роль db_accessadmin этой базы данных.
Убедитесь также, что отсутствует, например, право редактирования
структур таблиц в базе данных TRADE_ХХХ и право создавать в ней новые типы
данных.
9. Установите соединение c сервером базы данных от имени
пользователя с учетной записью ComputerName/User2.
Убедитесь, что сейчас вы, применительно к базе данных TRADE_ХХХ,
обладаете привилегиями роли Бухгалтер, т.е. вы можете просматривать данные
и вставлять новые строки только в таблицах Orders и Clients, однако обновлять
данные и удалять строки в этих таблицах вы не можете. Кроме того, вы можете
выполнять все действия с таблицей Locations (соответствующие привилегии
доступны через членство в роли public). К остальным таблицам, а также к
представлению OrdersCost, доступ оказывается запрещен. Также отсутствуют
права на выполнение и многих других действий.
10. Установите соединение c сервером базы данных от имени
пользователя с учетной записью ComputerName/User3.
Убедитесь, что сейчас вы, применительно к базе данных TRADE_ХХХ,
обладаете привилегиями роли Экономист, т.е. вы можете просматривать
данные и вставлять новые строки только в таблицах Suppliers и Products,
однако обновлять данные и удалять строки в этих таблицах вы не можете.
Кроме того, вы можете выполнять все действия с таблицей Locations
(соответствующие привилегии доступны через членство в роли public). К
остальным таблицам, а также к представлению OrdersCost, доступ оказывается
запрещен. Также отсутствуют права на выполнение и многих других действий.
11. Установите соединение c сервером базы данных от имени
пользователя с обычно используемой учетной записью.
Сейчас вы обладаете абсолютными правами по управлению базой данных
TRADE_ХХХ (например, возможна корректировка структур таблиц базы данных,

132
что невозможно в соединениях под учетными записями ComputerName/User1,
ComputerName/User2, ComputerName/User3). В этом можно легко убедиться,
если выберите на панели Инспектор объектов (Object Explorer) в дереве
структуры папку Безопасность (Security) - Пользователи (Users) базы данных
TRADE_ХХХ пользователя dbo. Затем в контекстном меню пользователя dbo
необходимо выполнить команду Свойства (Properties) и открыть окно
Пользователь базы данных – dbo (Database User Properties – dbo). Теперь
видно, что текущая учетная запись отображается в пользователя dbo, который в
свою очередь, является постоянным членом фиксированной роли базы данных
db_owner, которая и предоставляет все имеющиеся привилегии и возможности.
12. Отсоедините базу данных TRADE_ХХХ, выбрав в ее контекстном меню
команду Задачи (Tasks) - Отсоединить…(Detach Database). Убедитесь, что
база данных TRADE_ХХХ исчезла из папки Базы данных (Databases). Теперь
файлы этой базы данных можно, при необходимости, переместить в другую
папку на жестком диске или копировать на другой носитель данных.

Управление пользователями и правами доступа к данным с


помощью команд языка Transact-SQL
На панели Инспектор объектов (Object Explorer) откройте папку
Безопасность (Security) и выберите в ней Имена входа (Logins). При этом будет
представлен список регистрационных записей MS SQL Server.

Задание 1. Создание имени входа на основе учетной записи


домена Windows

Для версий MS SQL Server до 2012 включительно можно использовать


системную процедуру:
sp_grantlogin [@loginame =] 'login'
- Пользователь или группа Windows должны быть дополнены именем
домена Windows в формате Domain\User. Создайте три новых имени входа на
основе существующих в домене Windows.
EXEC sp_grantlogin ’ИмяДомена\User1’
EXEC sp_grantlogin ’ИмяДомена\User2’
EXEC sp_grantlogin ’ИмяДомена\User3’
GO
Отмена доступа к серверу учетной записи выполняется с помощью
хранимой процедуры sp_droplogin, имеющей синтаксис:
sp_droplogin [ @loginame = ] 'login'

133
Использование системной процедуры является устаревшим и не
поддерживается в современных версиях MS SQL Server. Для создания имени
входа на основе учетной записи домена Windows используйте следующую
команду:
CREATE LOGIN ИмяДомена\User1 FROM WINDOWS;
CREATE LOGIN ИмяДомена\User2 FROM WINDOWS;
CREATE LOGIN ИмяДомена\User3 FROM WINDOWS;
GO
Для удаления существующего имени входа используйте команду:
DROP LOGIN login_name

Задание 2. Добавление учетной записи в фиксированную роль


сервера

Синтаксис системной хранимой процедуры:


sp_addsrvrolemember [@loginame=] 'login' , [ @rolename = ] 'role
К предопределенной роли сервера dbcreator добавляется имя входа ОС
MS Windows ’ИмяДомена\ User1:
EXEC sp_addsrvrolemember ’ИмяДомена\ User1’, ’dbcreator’
GO
Удаление учетной записи из фиксированной роли сервера выполняется с
помощью хранимой процедуры sp_dropsrvrolemember, имеющей синтаксис:
sp_dropsrvrolemember [@loginame=] 'login' , [@rolename =] 'role

Задание 3. Добавление нового пользователя в текущую базу


данных

Синтаксис системной хранимой процедуры:


sp_grantdbaccess [@loginame =] 'login'
[,[@name_in_db =] 'name in db' [OUTPUT]]
К текущей базе данных добавляются новые пользователи с именами
User1, User2, User3:
EXEC sp grantdbaccess ’ИмяДомена\User1’, 'User1'
EXEC sp grantdbaccess ’ИмяДомена\User2’, 'User2'
EXEC sp grantdbaccess ’ИмяДомена\User3’, 'User3'
Хранимая процедура sp_grantdbaccess вызывает команду CREATE
USER. В современных версиях MS SQL Server необходимо пользоваться этой

134
командой.
Для добавления к текущей базе данных пользователя базы данных для
имени входа Windows ’ИмяДомена\User1’, используется инструкция CREATE
USER. Новому пользователю присваивается имя User1.
CREATE USER User1 FOR LOGIN [ИмяДомена\User1];
GO
Удаление пользователя выполняется с помощью системной хранимой
процедуры, имеющей синтаксис:
sp_revokedbaccess [ @name_in_db = ] 'name'
Удаление пользователя из текущей базы данных с помощью команды DROP
USER:
DROP USER user_name

Задание 4. Создание пользовательской роли

Синтаксис системной хранимой процедуры создания пользовательской


роли:
sp_addrole [ @rolename = ] 'role'
[ , [ @ownername = ] 'owner' ]
Создание трех пользовательских ролей базы данных с помощью системной
процедуры и назначение им существующих пользователей базы данных:
EXEC sp_addrole ’Главный бухгалтер’, ’User1’
EXEC sp_addrole ’Бухгалтер’, ’User2’
EXEC sp_addrole ’Экономист’, ’User3’
GO
Создание трех пользовательских ролей базы данных с помощью команды
CREATE ROLE и назначение им существующих пользователей базы данных:
CREATE ROLE Главный бухгалтер AUTHORIZATION User1;
CREATE ROLE Бухгалтер AUTHORIZATION User2;
CREATE ROLE Экономист AUTHORIZATION User3;
GO
Удаление пользовательской роли выполняется с помощью системной
хранимой процедуры:
sp_droprole [@rolename =] 'role'
или команды
DROP ROLE role_name
135
Задание 5. Добавление нового члена в роль (как
фиксированную, так и пользовательскую) базы данных

Синтаксис системной хранимой процедуры:


sp_addrolemember [@rolename =] 'role',
[@membername =] 'securityaccount
Добавление новых членов в роль:
EXEC sp_ addrolemember ’db_accessadmin’, ’User1’
EXEC sp_ addrolemember ’Главный бухгалтер’, ’User1’
EXEC sp_ addrolemember ’Бухгалтер’, ’User2’
EXEC sp_ addrolemember ’Бухгалтер’, ’Главный бухгалтер’
EXEC sp_ addrolemember ’Экономисты’, ’User3’
EXEC sp_ addrolemember ’Экономист’, ’Главный бухгалтер’
GO
Исключение члена из роли выполняется с помощью системной хранимой
процедуры, имеющей синтаксис:
sp_droprolemember [@rolename =] 'role',
[@membername =] ' securityaccount

Задание 6. Предоставление прав доступа к объектам базы


данных

Синтаксис системной хранимой процедуры:


GRANT
{ ALL [ PRIVILEGES ] |permission [ ,...n ]}
{
[( column [ ,...n ] ) ] ON { table | view}
|ON { table | view } [ ( column [ ,...n ])]
|ON { stored_procedure | extended_procedure}
|ON { user_defined_function }
}
TO security account [ ,...n ]
[ WITH GRANT OPTION ]
[ AS { group | role } ]
Назначение прав доступа к объектам базы данных:
GRANT SELECT, INSERT, UPDATE, DELETE ON Currency TO [Главный

136
бухгалтер] WITH GRANT OPTION
GRANT UPDATE ON Orders TO [Главный бухгалтер] WITH GRANT OPTION
GRANT SELECT ON Запрос1 TO [Главный бухгалтер] WITH GRANT OPTION
GRANT UPDATE, DELETE ON Clients TO [Главный бухгалтер] WITH GRANT
OPTION
GRANT UPDATE, DELETE ON Поставщик TO [Главный бухгалтер] WITH GRANT
OPTION
GRANT UPDATE, DELETE ON Products TO [Главный бухгалтер] WITH GRANT
OPTION
GRANT SELECT, INSERT ON Orders TO Бухгалтер
GRANT SELECT, INSERT ON Clients TO Бухгалтер
GRANT SELECT, INSERT ON Поставщик TO Экономист
GRANT SELECT, INSERT ON Products TO Экономист
GRANT SELECT, INSERT, UPDATE, DELETE ON Locations TO public
GO
Примечание. С помощью ключевых слов WITH GRANT OPTION
пользователям, указанным с помощью строки TO security_account [,...n]
будет предоставлено право выдавать другим пользователям разрешения
доступа, аналогичные выданным им самим.

Задание 7. Запрещение доступа к объектам базы данных

Синтаксис системной хранимой процедуры:


DENY
{ALL [PRIVILEGES] |permission [ ,...n ]}
{
[( column [ ,...n ] ) ] ON { table | view}
|ON { table | view } [ ( column [ ,...n ])]
|ON { stored_procedure | extended_procedure}
|ON { user_defined_function }
}
TO securityaccount [ ,...n ]
[CASCADE]
Запрещение права доступа к объектам базы данных:
DENY UPDATE ON Orders (ДатаOrdersа, СрокПоставки) TO [Главный
бухгалтер] CASCADE

137
GO
Примечание. Кроме предоставления и запрещения прав доступа
существует еще и третье состояние - неявное отклонение доступа. Его можно
рассматривать как отмену ранее выданных полномочий, как по
предоставлению, так и запрету доступа. Если ранее пользователю не было
выдано никаких полномочий к объекту, то выполнять неявное отклонение
доступа бессмысленно, т.к. оно установлено по умолчанию. Неявное
отклонение доступа не мешает получить доступ к объекту на другом уровне,
например, через членство в некоторой роли. Для неявного отклонения доступа
используется команда REVOKE, имеющая следующий синтаксис:
REVOKE [GRANT OPTION FOR]
{ALL [PRIVILEGES ] | permission [ ,... n ]}
{
[( column [ ,...n ] ) ] ON { table | view}
|ON {table | view} [(column [ ,...n ])]
|ON {stored_procedure | extended_procedure}
} ON {user_defined_function}

{TO|FROM } security account [ ,...n]


[CASCADE]
[ AS { group | role } ]

138
Литература

Основная
1. Дейт, К. Дж. Введение в системы баз данных. - Пер. с англ. - 8-е изд. /
К. Дж. Дейт. – Москва: Вильямс, 2017. – 1327 с.
2. Коннолли, Т. Базы данных. Проектирование, реализация и
сопровождение. Теория и практика. - Пер. с англ. /Т. Коннолли, К. Бегг. –
Москва: Диалектика, 2017. 1440 с.
3. Кренке, Д. Теория и практика построения баз данных. - Пер. с
англ. - 9-е изд. / Д. Кренке. - СПб.: Питер, 2005. – 864 с.
4. Райордан, Р. М. Основы реляционных баз данных. - Пер. с англ. / Р.
М. Райордан. - – Москва: Русская редакция, 2001. – 384 с.
5. Бен-Ган, И. Microsoft SQL Server 2012. Основы T-SQL. - Пер. с англ. /
И. Бен-Ган. – Москва: ЭКСМО, 2015. – 400 с.
6. Петкович, Д. Microsoft SQL Server 2012/ Руководство для
начинающих. - Пер. с англ. /Д. Петкович. - СПб.: БХВ-Петербург, 2013. - 816 с.
7. Грофф, Дж. Р. SQL. Полное руководство. - Пер. с англ. / Дж. Р.Грофф,
П.Н.Вайнберг, Э. Дж.Оппелъ. – Москва: Вильямс, 2015. – 952 с.
8. Бутов, А.А. Базы данных. Лабораторный практикум для студентов
специальности «Информационные системы и технологии» БГУИР / А. А.
Бутов, И. Г. Орешко, Е. А. Шестаков. - Минск: БГУИР, 2009. - 108 с.
9. Астахова, И.Ф. СУБД: язык SQL в примерах и задачах. / И.Ф.
Астахова, В.В. Фертиков, В.М. Мельников, А.П. Толстобров. – Москва:
Физматлит, 2009. – 168 с.
10. Куликов, С.С. Работа с MySQL, SQL Server и Oracle в примерах.
Практическое пособие. / С. С. Куликов– Минск, УП «Бофф», 2016. – 556 с.
11. Карпова, И.П. Базы данных: Учебное пособие / И.П. Карпова. - СПб.:
Питер, 2013. - 240 c.

Дополнительная
12. Хомоненко, А. Д. Базы данных: Учебник для высших учебных
заведений / Под ред. проф. А. Д. Хомоненко. - 6-е изд., доп. - СПб.: КОРОНА-
Век, 2009. - 736 с.
13. Форта, Б. Освой самостоятельно SQL за 10 минут. 4-е изд. - Пер. с
англ. / Б. Форта. – Москва: Вильямс, 2014. – 288 с.
139
14. Кузнецов, С.Д. Основы современных баз данных [Электронный
ресурс] - Режим доступа: http://citforum.ru/database/osbd/contents.shtml. Дата
доступа: 05.11.2017.
15. Верников, Г. Основы методологии IDEF1X [Электронный ресурс] –
Режим доступа: http://www.citforum.ru/cfin/idef/idef1x.shtml. Дата доступа:
05.11.2017.
16. Агальцов, В.П. Базы данных. В 2-х т. Т. 2. Распределенные и
удаленные базы данных: Учебник / В.П. Агальцов. - Москва: ИД ФОРУМ, НИЦ
ИНФРА-М, 2013. - 272 c.
17. Агальцов, В.П. Базы данных. В 2-х т. Т. 1. Локальные базы данных:
Учебник / В.П. Агальцов. - Москва: ИД ФОРУМ, НИЦ ИНФРА-М, 2013. - 352
c.
18. Советов, Б.Я. Базы данных: теория и практика: Учебник для
бакалавров / Б.Я. Советов, В.В. Цехановский, В.Д. Чертовской. - Москва:
Юрайт, 2013. – 463 с.
19. Белодед, Н. И., Змитрович А. В., Обернихина И. С., Сасова Н. А.
Системы баз данных. / Н.И. Белодед, А.В. Змитрович, И.С. Обернихина,
Н.А. Сасова. - Минск: Академия управления при Президенте Республики
Беларусь. - 142 c.
20. Голицына, О. Л. Основы проектирования баз данных. / О.Л.
Голицына, Т.Л. Партыка, И.И. Попов - Москва: Форум, 2012. - 416 c.
21. Хаббард, Дж. Автоматизированное проектирование баз данных / Дж.
Хаббард. - Москва: Мир, 2014. - 296 c.
22. Редько, В.Н. Базы данных и информационные системы / В.Н. Редько,
И.А. Басараб. - Москва: Знание, 2015. - 371 c.

140
Послесловие

Авторы выражают глубокую благодарность господам А. А. Бутову,


И. Г. Орешко, Е. А. Шестакову, труд которых «Базы данных. Лабораторный
практикум для студентов специальности «Информационные системы и
технологии» БГУИР» был взят за основу при составлении данного практикума
при любезном разрешении Игоря Георгиевича Орешко.

141

Вам также может понравиться