Uploaded by Oleg Petrov

Базы Данных

advertisement
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ
Федеральное государственное бюджетное образовательное учреждение высшего образования
«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ МОРСКОЙ ТЕХНИЧЕСКИЙ
УНИВЕРСИТЕТ»
Кафедра прикладной математики и математического моделирования
Курсовой проект
по дисциплине «Базы данных»
на тему
«Создание приложения, описывающего некоторую предметную область»
Выполнил:
Студент группы 1400
Петров О.Ю.
Проверил(а):
Семенова Тян-Шанская В.А.
……………………….…………..… (оценка)
……………………….………………. (дата)
Санкт-Петербург
2019 г.
Содержание
Введение ................................................................................................... 2
Теоретическая часть ................................................................................ 2
Проектирование базы данных ............................................................... 10
Разработка объектов БД ........................................................................ 17
Приложение 1. Сценарий создания структуры базы данных в СУБД
SQL Server............................................................................................... 18
Создание оконного приложения и привязка к нему базы данных ........ 23
Приложение 2. Сценарий создания приложения «Аптека» с помощью
Windows Forms ........................................................................................ 25
Список литературы ................................................................................. 31
1
Введение
Современные информационные технологии – это методы и средства
для сбора, хранения, обработки и получения информации на основе
современных средств вычислительной техники.
Составными частями любой информационной системы являются базы
данных и приложение для обработки данных.
База данных обеспечивает хранение информации и представляет
собой поименованную совокупность данных, организованных по
определенным правилам, включающим общие принципы описания,
хранения и манипулирования данными.
Система управления базами данных представляет собой пакет
прикладных программ и совокупность языковых средств,
предназначенных для создания, сопровождения и использования баз
данных.
Теоретическая часть
При проектировании базы данных решаются две основные проблемы:
1. Отображение объектов предметной области в абстрактные
объекты модели данных таким образом, чтобы это отображение
не противоречило семантике предметной области, и было по
возможности лучшим (эффективным, удобным и т.д.). Часто эту
проблему называют проблемой логического проектирования баз
данных;
2. Обеспечение эффективного выполнения запросов к базе
данных, т.е. рациональное расположение данных во внешней
памяти, создание полезных дополнительных структур (например,
индексов) с учетом особенностей конкретной СУБД. Эту
проблему называют проблемой физического проектирования баз
данных.
Проблема проектирования реляционной базы данных состоит в
обоснованном принятии решений о том, из каких отношений (таблиц)
должна состоять БД и какие атрибуты (характеристики и свойства)
должны быть у этих отношений.
Классическим является подход, при котором весь процесс
проектирования производится в терминах реляционной модели
данных методом последовательных приближений к
удовлетворительному набору схем отношений.
2
Исходной точкой является представление предметной области в виде
одного или нескольких отношений, и на каждом шаге проектирования
производится некоторый набор схем отношений, обладающих
лучшими свойствами. Процесс проектирования представляет собой
процесс нормализации схем отношений, причем каждая следующая
нормальная форма обладает свойствами лучшими, чем предыдущая.
При проектировании базы данных используем, наиболее
распространенный метод моделирования данных – «сущность связь».
Эта модель введена Питером Ченом в 1976 году.
В базах данных содержится информация об объектах, существующих
в реальном мире. Все эти объекты являются материальными,
обладающим некоторыми свойствами и присущим им поведением.
При создании программного продукта, свойства объектов хранятся в
базе данных, а их поведение реализуется в приложении посредством
методов – процедур, которые представляют собой отклик на события
инициируемых пользователем.
Инфологическая модель является проблемно-ориентированной и
системно-независимой, т.е. не зависимой от конкретной СУБД,
операционной системы и аппаратного обеспечения ЭВМ.
Основным требованием к инфологической модели, вытекающим из ее
назначения, является требование адекватного отображения
предметной области. Инфологическая модель должна быть
непротиворечивой. Она является единым интегрированным
описанием предметной области и отражает взгляды и потребности
всех пользователей системы
Инфологическая модель представляет информационные потоки,
сущности и связи данной предметной области. Она может быть
представлена в виде ER-модели и реляционной схемы.
Целью построения этой структуры является выявление и объединение
информационных требований пользователя, связей между
элементами данных без относительно к их содержанию и среде их
хранения. Инфологическая модель должна обладать свойством
легкой расширяемости, обеспечивающим ввод новых данных без
изменений ранее определенных.
3
Центральной компонентой инфологической модели является
описание объектов предметной области и связей между ними (ERмодель).
Цель инфологического моделирования – обеспечение наиболее
естественных для человека способов сбора и представления той
информации, которую предполагается хранить в создаваемой базе
данных. Поэтому инфологическую модель данных пытаются строить
по аналогии с естественным языком (последний не может быть
использован в чистом виде из-за сложности компьютерной обработки
текстов и неоднозначности любого естественного языка).
Основными конструктивными элементами инфологических моделей
являются сущности, связи между ними, идентификаторы (ключи) и
свойства (атрибуты).
Сущность – любой различимый объект (объект, который мы можем
отличить от другого), информацию о котором необходимо хранить в
базе данных. Сущностями могут быть люди, места, самолеты, рейсы,
вкус, цвет и т.д. Необходимо различать такие понятия, как тип
сущности и экземпляр сущности. Понятие тип сущности относится к
набору однородных личностей, предметов, событий или идей,
выступающих как целое.
Экземпляр сущности относится к конкретной вещи в наборе.
Например, типом сущности может быть ГОРОД, а экземпляром –
Москва, Киев и т.д.
Атрибут – поименованная характеристика сущности.
Ключ – минимальный набор атрибутов, по значениям которых можно
однозначно найти требуемый экземпляр сущности. Минимальность
означает, что исключение из набора любого атрибута не позволяет
идентифицировать сущность по оставшимся.
Связь – ассоциирование двух или более сущностей. Если бы
назначением базы данных было только хранение отдельных, не
связанных между собой данных, то ее структура могла бы быть очень
простой. Однако одно из основных требований к организации базы
данных – это обеспечение возможности отыскания одних сущностей
по значениям других, для чего необходимо установить между ними
определенные связи. А так как в реальных базах данных нередко
содержатся сотни или даже тысячи сущностей, то теоретически между
ними может быть установлено более миллиона связей. Наличие
4
такого множества связей и определяет сложность инфологических
моделей.
Для реляционной базы данных проектирование логической структуры
заключается в том, чтобы разбить всю информацию по файлам
(отношениям), а также определить состав полей (атрибутов) для
каждого из этих файлов.
Одно из требований — реляционная база данных должна быть
нормализована. Процесс нормализации имеет своей целью
устранение избыточности данных и заключается в приведении к
третьей нормальной форме (или к нормальной форме Бойса-Кодда).
Нормализацией называется формальная процедура, в ходе которой
атрибуты данных группируются в таблицы, а таблицы группируются в
базу данных (БД).
Единицей, хранящейся в БД информации, является таблица. Каждая
таблица представляет собой совокупность строк и столбцов, где
строки соответствуют экземпляру, а столбцы - атрибутам (признакам,
характеристикам, параметрам объекта, события, явления).
Первая нормальная форма (1НФ). Для нее требуется, чтобы таблица
была плоской и не содержала повторяющихся групп. У плоской
таблицы есть только две характеристики - длина (количество записей
или строк) и ширина (количество полей или столбцов). Такая таблица
не должна содержать ячеек, включающих несколько значений.
Никакую из систем управления базами данных (СУБД) не
удовлетворяет только 1НФ, так как в этом случае необходимо
определить большое число полей, многие из которых остаются в
основном пустыми. Избыточные данные могут послужить причиной
проблем целостности и снижение эффективности при внесении
изменений, поэтому подобных решений при проектировании баз
данных необходимо избегать.
Вторая нормальная форма (2НФ). Для 2НФ требуется, чтобы все поля
таблицы зависели от первичного ключа, то есть, чтобы первичный
ключ однозначно определял запись и не был избыточен.
В каждой таблице БД может существовать первичный ключ - поле или
набор полей, однозначно идентифицирующий запись.
Значение первичного ключа в таблице БД должно быть уникальным,
т.е. в таблице не должно существовать двух и более записей с
одинаковым значением первичного ключа.
5
Те поля, которые зависят только от части первичного ключа, должны
быть выделены в составе отдельных таблиц. 2НФ позволяет удалить
большую часть повторяющихся данных, которые часто остаются
после первого этапа нормализации.
Для третьей нормальной формы (ЗНФ) требуется, чтобы все
неключевые столбцы таблицы зависели от первичного ключа
таблицы, но были независимы друг от друга. Для этого требуется,
чтобы таблицы были приведены к 1НФ и 2НФ.
Однако бывает необходимость введения более сильных зависимостей
– НФ Бойса-Кодда (НФ БК).
НФ БК учитывает все потенциальные ключи, которые входят в
отношения. Если отношение имеет единственный потенциальный
ключ, то 3-я НФ и НФ БК – эквивалентны. Считается, что отношение,
находящееся в НФ БК, если каждый его детерминант является
потенциальным ключом. Что бы убедиться, что отношение находится
в НФ БК необходимо отыскать все его детерминанты и убедиться, что
они являются потенциальными ключами.
Отношение находится в четвертой нормальной форме (4НФ), если в
нем не присутствуют функциональные многозначные зависимости.
Для 4НФ требуется, чтобы в одной таблице не содержались
независимые элементы данных, если между ними существует
отношение "многие-ко-многим".
Если в отношении имеется много функциональных зависимостей, 4НФ
не устраняет избыточность, то применяют пятую нормальную форму
(5НФ).
Разложение отношений из 4НФ в пятую нормальную форму должно
быть выполнено так, чтобы каждая проекция, полученная из 4НФ,
содержала не менее одного возможного ключа и хотя бы один не
ключевой атрибут из исходного отношения. Для 5НФ требуется, чтобы
можно было восстановить исходную таблицу на основе информации
таблиц, на которые она была разбита. Кроме того, необходимо, чтобы
таблицы соответствовали ЗНФ, а при наличии отношений "многие-комногим" - 4НФ.
Для большинства существующих СУБД необходимо представить
проект базы данных в ЗНФ, так как этого вполне достаточно
практически для всех обычных приложений. При разработке
исключительно больших систем, когда необходимо максимальное
сокращение объемов хранимых данных, желательно произвести
6
дальнейшую нормализацию. Но в этом случае можно столкнуться с
недостатками нормализации. Поскольку порог человеческого
восприятия не позволяет одновременно анализировать большое
число объектов с учетом их взаимосвязей, можно утверждать, что с
увеличением числа нормализованных таблиц уменьшается целостное
восприятие базы данных как системы взаимосвязанных данных.
Другим недостатком нормализованной базы данных является
необходимость считывать связанные данные из нескольких таблиц
при выполнении одного запроса.
После логического проектирования можно перейти к описанию БД в
терминах языка какой-либо СУБД. При этом используются такие
объекты:
•
•
•
•
Таблицы
Представления
Хранимые процедуры
Триггеры
Таблица – основной объект для хранения информации в реляционной
базе данных. Она состоит из содержащих данные строк и столбцов,
занимает в базе данных физическое пространство и может быть
постоянной или временной.
Поле, также называемое в реляционной базе данных столбцом,
является частью таблицы, за которой закреплен определенный тип
данных. Каждая таблица базы данных должна содержать хотя бы
один столбец. Строка данных – это запись в таблице базы данных,
она включает поля, содержащие данные из одной записи таблицы.
Базовый синтаксис оператора создания таблицы имеет следующий
вид:
CREATE TABLE имя_таблицы
(имя_столбца тип_данных [,...n])
Представления, или просмотры (VIEW), представляют собой
временные, производные (иначе - виртуальные) таблицы и являются
объектами базы данных, информация в которых не хранится
постоянно, как в базовых таблицах, а формируется динамически при
обращении к ним. Обычные таблицы относятся к базовым, т.е.
содержащим данные и постоянно находящимся на устройстве
хранения информации. Представление не может существовать само
по себе, а определяется только в терминах одной или нескольких
7
таблиц. Применение представлений позволяет разработчику базы
данных обеспечить каждому пользователю или группе пользователей
наиболее подходящие способы работы с данными, что решает
проблему простоты их использования и безопасности. Содержимое
представлений выбирается из других таблиц с помощью выполнения
запроса, причем при изменении значений в таблицах данные в
представлении автоматически меняются. Представление - фактически
тот же запрос, который выполняется всякий раз при участии в какойлибо команде. Результат выполнения этого запроса в каждый момент
времени становится содержанием представления. У пользователя
создается впечатление, что он работает с настоящей, реально
существующей таблицей.
Представление – это предопределенный запрос, хранящийся в базе
данных, который выглядит подобно обычной таблице и не требует для
своего хранения дисковой памяти. Для хранения представления
используется только оперативная память. В отличие от других
объектов базы данных представление не занимает дисковой памяти
за исключением памяти, необходимой для хранения определения
самого представления.
Создания и изменения представлений в стандарте языка и
реализации в MS SQL Server совпадают и представлены следующей
командой:
{CREATE| ALTER} VIEW имя_просмотра
[(имя_столбца [,...n])]
[WITH ENCRYPTION]
AS SELECT_оператор
[WITH CHECK OPTION]
Хранимые процедуры представляют собой группы связанных между
собой операторов SQL, применение которых делает работу
программиста более легкой и гибкой, поскольку выполнить хранимую
процедуру часто оказывается гораздо проще, чем
последовательность отдельных операторов SQL. Хранимые
процедуры представляют собой набор команд, состоящий из одного
или нескольких операторов SQL или функций и сохраняемый в базе
данных в откомпилированном виде. Выполнение в базе данных
хранимых процедур вместо отдельных операторов SQL дает
пользователю следующие преимущества:
8
• необходимые операторы уже содержатся в базе данных;
• все они прошли этап синтаксического анализа и находятся в
исполняемом формате; перед выполнением хранимой
процедуры SQL Server генерирует для нее план исполнения,
выполняет ее оптимизацию и компиляцию;
• хранимые процедуры поддерживают модульное
программирование, так как позволяют разбивать большие
задачи на самостоятельные, более мелкие и удобные в
управлении части;
• хранимые процедуры могут вызывать другие хранимые
процедуры и функции;
• хранимые процедуры могут быть вызваны из прикладных
программ других типов;
• как правило, хранимые процедуры выполняются быстрее, чем
последовательность отдельных операторов;
• хранимые процедуры проще использовать: они могут состоять из
десятков и сотен команд, но для их запуска достаточно указать
всего лишь имя нужной хранимой процедуры. Это позволяет
уменьшить размер запроса, посылаемого от клиента на сервер,
а значит, и нагрузку на сеть.
Создание новой и изменение имеющейся хранимой процедуры
осуществляется с помощью следующей команды:
{CREATE | ALTER } PROC[EDURE] имя_процедуры
[{@имя_параметра тип_данных} [Значение по
умлочанию][OUTPUT] ][,...n]
[WITH {RECOMPILE, ENCRYPTION }]
AS
sql_оператор [...n]
GO
Триггеры являются одной из разновидностей хранимых процедур. Их
исполнение происходит при выполнении для таблицы какого-либо
оператора языка манипулирования данными (DML). Триггеры
используются для проверки целостности данных, а также для отката
транзакций.
Триггер – это откомпилированная SQL-процедура, исполнение
которой обусловлено наступлением определенных событий внутри
реляционной базы данных. Применение триггеров большей частью
9
весьма удобно для пользователей базы данных. И все же их
использование часто связано с дополнительными затратами ресурсов
на операции ввода/вывода. В том случае, когда тех же результатов (с
гораздо меньшими непроизводительными затратами ресурсов) можно
добиться с помощью хранимых процедур или прикладных программ,
применение триггеров нецелесообразно.
Триггер представляет собой специальный тип хранимых процедур,
запускаемых сервером автоматически при попытке изменения данных
в таблицах, с которыми триггеры связаны. Каждый триггер
привязывается к конкретной таблице. Все производимые им
модификации данных рассматриваются как одна транзакция. В случае
обнаружения ошибки или нарушения целостности данных происходит
откат этой транзакции. Тем самым внесение изменений запрещается.
Отменяются также все изменения, уже сделанные триггером.
Основной формат команды CREATE TRIGGER показан ниже:
CREATE TRIGGER имя_триггера
ON <имя_таблицы>|<представление>
[WITH ENCRYPTION]
{AFTER|INSTEAD OF TRIGGER}{INSERT,UPDATE,DELETE}
AS
<тело_триггера>
GO
Проектирование базы данных
Описание предметной области
Выбор создания и проектирования базы данных для аптеки
продиктован насущными потребностями современного рынка продаж.
В настоящий момент существует огромный спрос на такие базы
данных, которые позволяют хранить и отображать данные в удобном
для пользователя виде. В данной курсовой работе представляется
разработка подобной базы данных.
Разработка базы данных проводилась в Microsoft SQL Server, который
предназначен для управления, проектирования и разработки баз
данных.
Основная задача заключается в создании информационной системы,
которая совмещала бы в себе удобство, простоту, надежность,
10
достоверность, актуальность. Необходимо разработать
информационную систему аптеки для выполнения учета сотрудников,
а также лекарственных средств, реализуемых в аптеке.
Каждый сотрудник должен быть отнесён к одному отделу и занимать
только одну должность. Должность определяет оклад. Кроме этого
сотрудники могут получать премиальные. Также необходимо хранить
в базе паспортные данные, телефон и адрес сотрудника.
Лекарственные средства также могут относится Толька к одному
отделу, могут иметь разную форму выпуска, могут продаваться только
по рецепту или без рецепта. У них могут быть различные показания и
условия хранения. Лекарственные средства закупаются у поставщиков
по закупочным ценам. В базе следует хранить дату поставки и список
лекарственных средств с указанием количества.
В рецепте указывается фамилия, имя, отчество клиента и список
лекарственных средств, а также дата и количество.
1 Этап. Выделение сущностей и связей
В результате этих рассуждений мы можем выделить следующий
набор сущностей:
1. Сотрудник
2. Отдел
3. Должность
4. Препарат
5. Поставка
6. Поставщик
7. Отпуск
8. Рецепт
9. Зарплата
и следующий набор связей:
1. Сотрудник получает зарплату
2. Сотрудник занимает должность
3. Сотрудник работает в отделе
4. Сотрудник уходит в отпуск
11
5. Препарат относится к определенному отделу
6. Препарат имеет цену
7. Поставка осуществляется поставщиком
8. Поставка содержит в себе препарат
9. Рецепт выписывается на препарат
2 Этап. Построение ER-диаграммы
1. Сотрудник обязательно получает зарплату
Сотрудник
1
Получает
1
Зарплату
Сотрудник обязательно получает зарплату. Зарплата
обязательно выдаётся сотруднику. Фиксируется дата выдачи
зарплаты, также предусмотрены премии сотрудникам.
2. Сотрудник обязательно занимает одну должность
Сотрудник
N
Занимает
1
Должность
Сотрудник обязательно занимает одну должность. Каждая
должность может заниматься несколькими сотрудниками. Для
соответствующей должности должно быть определена
квалификация образования, также определен соответствующий
ей оклад.
3. Сотрудник обязательно работает в каком-то отделе
Сотрудник
N
Работает в
1
Отделе
Сотрудник обязательно работает в каком-то отделе. В каждом
отделе работает один или несколько сотрудников. Отделы
делятся как по специализирующимся работникам по продукции,
так и по выполняемой работе.
4. Каждому сотруднику соответствует один отпуск, в каждом году
Сотрудник
1
Уходит в
1
Отпуск
Каждому сотруднику соответствует один отпуск, в каждом году.
Каждая запись об отпуске соответствует одному сотруднику,
фиксируется начало и конец отпуска сотрудника.
12
5. Каждая поставка осуществляется одним поставщиком
Поставка
N
Осуществляется
1
Поставщик
ом
Каждая поставка осуществляется одним поставщиком. Каждый
поставщик может совершать несколько поставок. Фиксируется
информация Адреса и телефона поставщика, если она известна.
6. В каждой поставке может быть несколько препаратов
Поставка
N
Содержит
N
Препарат
В каждой поставке может быть несколько препаратов. Каждый
препарат может содержаться в нескольких поставках. Назначена
дата поставки и наименование поставщика, осуществляющего
требуемую поставку. Как правило определенные поставщики
специализируются по определенным товарам.
7. Каждый рецепт может выписываться на несколько препаратов
Рецепт
N
Выписывается на
N
Препарат
Каждый рецепт может выписываться на несколько препаратов.
Препарат может содержаться в нескольких рецептах. Не все
препараты продаются по рецептам. Может фиксироваться
информация о Показаниях к применению и условиям хранения
препарата.
8. Каждый препарат относится к одному отделу
Препарат
N
Относится
1
Отдел
Каждый препарат относится к одному отделу. Не все отделы
имеют препараты. У отдела есть заведующий, который отвечает
за препараты, которые в нем есть. Есть номер телефона
заведующего.
Общая ER-диаграмма:
13
Должность
1
Занимает
N
Отпуск
1
Уходит в
1
Сотрудник
1
Получает
1
Зарплату
N
Работает в
1
Отделе
1
Занимает
N
Рецепт
M
Выписывается на
N
Препарат
N
Содержит
M
Поставка
N
Осуществляется
1
Поставщик
ом
Этап 3. Формирование предварительных отношений
по ER-диаграмме
Сотрудник занимает должность
По правилу 4 получим 2 отношения:
• Должности (Должность)
• Сотрудники(Фамилия, имя, отчество, должность)
Сотрудник уходит в отпуск
По правилу 1 получим 1 отношение:
• Отпуска (Фамилия, имя, отчество, год)
14
Сотрудник обязательно получает зарплату
По правилу 1 получим 1 отношение:
• Зарплаты (Фамилия, имя, отчество, дата)
Сотрудник работает в отделе
По правилу 4 получим 2 отношения:
• Сотрудники(Фамилия, имя, отчество, отдел)
• Отделы(Отдел)
Препарат занимает место в отделе
По правилу 4 получим 2 отношения:
• Отделы(Отдел)
• Препараты(Препарат, форма выпуска, отдел)
Препарат выписывается на рецепт
По правилу 6 получим 3 отношения:
• Препараты(Препарат, форма выпуска, по рецепту)
• Препараты по рецепту(Препарат, форма выпуска, № рецепта)
• Рецепты(№ рецепта)
Поставка содержит препараты
По правилу 6 получим 3 отношения:
• Препараты(Препарат, форма выпуска)
• Поставляемы препараты(Препарат, форма выпуска, Номерпост)
• Поставки(Номерпост, Поставщик)
Поставка осуществляется поставщиком
По правилу 4 получим 2 отношения:
• Поставки(Номерпост, Поставщик)
• Поставщики(Поставщик)
4 Этап. Распределение атрибутов по отношениям
1. Сотрудники (Фамилия, Имя, Отчество, Домашний телефон,
Отдел, Должность)
2. Отделы (Отдел, Заведующий, Телефон)
3. Должности (Должность, Требуемое образование, Оклад)
15
Препараты (Препарат, Цена, Отдел, По рецепту)
Поставки (Номерпост, Поставщик, Дата)
Поставщики (Поставщик, Адрес, Телефон)
Рецепты (№ рецепта, Фамилия, Имя, Отчество, Дата)
Отпуска (Фамилия, Имя, Отчество, Начало отпуска, Конец
отпуска)
9. Зарплаты (Фамилия, Имя, Отчество, Дата, Зарплата, Премия)
10.
Поставляемые препараты (Номерпост, Препарат,
Количество, Цена за единицу)
11.
Препараты по рецептам (Препарат, № рецепта, Количество
по рецепту)
4.
5.
6.
7.
8.
5 Этап. Проверка отношений на БКНФ
Отношение находится во 2НФ, т.к. каждый неключевой атрибут
функционально полно зависит от первичного ключа.
Отношение находится в 3НФ, т. к. в нём нет транзитивных
зависимостей неключевых атрибутов.
Отношение находится в БКНФ, т. к. в нем существует единственный
потенциальный ключ, который является детерминантом всех
функциональных зависимостей.
6 Этап. Построение схемы БД
16
Разработка объектов БД
Были разработаны хранимые процедуры:
• Изменить_Поставщика – изменяет информацию о поставщике и
обновляет таблицу
• Новый_Поставщик – добавляет информацию о новом
поставщике в таблицу Поставщики(Имя поставщика, Адрес и
телефон)
• Удаляем_Поставщики – позволяет удалять поставщика из
таблицы Поставщики с ее информацией о нем
При разработке данной БД были спроектированы триггеры:
• TRIGGER Print_Update – Выводит информации
обновлении/модификации Таблицы Рецепты, при добавлении
нового рецепта
• TRIGGER УДАЛ_СОТР – позволяет удалять (увольнять)
сотрудников из таблицы сотрудники. Удалять можно всех кроме
заведующего аптекой
При разработке БД были созданы представления:
• Вывод_ближайших_поставок_препаратов – позволяет увидеть
поставки препаратов, датируемые большей, чем текущей датой
• Препараты_на_букву_Ф – выводит список препаратов, название
которых начинается с буквы «Ф»
• Сотрудники_с_высшим_образованием – выводит всех
сотрудников с «высшим» образованием
17
Приложение 1. Сценарий создания структуры базы
данных в СУБД SQL Server
Создание таблиц
USE Coursework
CREATE TABLE Должности (
Должность char(50) NOT NULL ,
Требуемое_образование char(20) NULL ,
Оклад money NULL,
Primary Key(Должность)
)
CREATE TABLE Отделы (
Отдел char(80) NOT NULL Primary KEY,
Заведующий char(50) NULL ,
Телефон char(12) NULL
)
CREATE TABLE Сотрудники (
Фамилия char(20),
Имя char(20),
Отчество char(20),
Адрес char(80) NULL ,
Телефон char(12) NULL ,
Отдел char(80) NULL Foreign KEY References Отделы(Отдел),
Должность char(50) NULL Foreign KEY References Должности(Должность),
Primary Key(Фамилия, Имя, Отчество)
)
CREATE TABLE Зарплаты (
Фамилия char(20) Not null,
Имя char(20) Not null,
Отчество char (20) Not null,
Дата date Not null,
Зарплата money NULL ,
Премия money NULL,
Primary Key(Фамилия, Имя, Отчество, Дата),
FOREIGN KEY (Фамилия, Имя, Отчество) REFERENCES Сотрудники(Фамилия, Имя,
Отчество)
)
CREATE TABLE Отпуска (
Фамилия char(20) NOT NULL ,
Имя char(20) NOT NULL ,
Отчество char(20) NOT NULL ,
Начало_отпуска date NULL ,
Конец_отпуска date NULL,
Primary Key(Фамилия, Имя, Отчество),
FOREIGN KEY (Фамилия, Имя, Отчество) REFERENCES Сотрудники(Фамилия, Имя,
Отчество)
)
CREATE TABLE Поставщики (
Поставщик char(35) NOT NULL Primary Key,
Адрес char(80) NULL ,
Телефон char(12) NULL
)
CREATE TABLE Поставки (
Номерпост int NOT NULL Primary KEy,
18
Поставщик char(35) NULL Foreign KEy references Поставщики(Поставщик),
Дата datetime NULL
)
CREATE TABLE Препараты (
Препарат char(70) NOT NULL,
Цена money NULL ,
Отдел char(80) NULL Foreign Key references Отделы(Отдел),
По_рецепту bit NULL ,
Показания char(120) NULL ,
Условия_хранения char(100) NULL,
Primary Key(Препарат)
)
CREATE TABLE Поставляемые_препараты (
Номерпост int NOT NULL FOREIGN KEY REFERENCES Поставки(Номерпост),
Препарат char(70) NOT NULL,
Количество int NULL ,
Цена_за_единицу money NULL,
Primary Key(Номерпост, Препарат),
Foreign Key (Препарат) References Препараты(Препарат)
)
CREATE TABLE Рецепты (
Номер_рецепта int NOT NULL Primary Key,
Фамилия char(20) NULL ,
Имя char(20) NULL ,
Отчество char(20) NULL ,
Дата date NULL
)
CREATE TABLE Препараты_по_рецептам (
Препарат char(70) NOT NULL ,
Номер_рецепта int NOT NULL ,
Количество_по_рецепту int NULL,
Primary Key(Препарат, Номер_рецепта),
Foreign Key(Препарат) References Препараты(Препарат),
Foreign Key(Номер_рецепта) References Рецепты(Номер_рецепта)
)
GO
19
Пример, как выглядит таблица «Должности» после ее заполнения.
Заполнять таблицы можно как и вручную, так и с помощью операции
Insert, которая имеет такой синтаксис:
INSERT INTO <имя таблицы>[(<имя столбца>,...)]
{VALUES (<значение столбца>,…)}
| <выражение запроса>
| {DEFAULT VALUES}
Создание хранимых процедур
--изменение поставщика (ХП)
Use Coursework
Go
CREATE PROCEDURE Изменить_Поставщика(
@postavshik char(35),
@adress char(20),
@telephon char(20)
)
AS
BEGIN
UPDATE Поставщики
SET Адрес = @adress, Телефон = @telephon
WHERE Поставщик = @postavshik
END
Go
--Добавление поставщика (ХП)
CREATE PROCEDURE Новый_Поставщик(
@post char(35),
@adress char(20),
@tel char(20)
20
)
AS
BEGIN
INSERT INTO Поставщики
VALUES (
@post,
@adress,
@tel
)
END
GO
--Удаление поставщика (ХП)
CREATE PROCEDURE Удаляем_Поставщики(@post char(35))
AS
BEGIN
delete
from Поставщики
where Поставщик = @post;
END
GO
Создание представлений
--Сотрудники с высшим образованием (VIEW)
CREATE VIEW Сотрудники_с_высшим_образованием
AS
SELECT
dbo.Сотрудники.Должность, dbo.Сотрудники.Фамилия, dbo.Сотрудники.Имя,
dbo.Сотрудники.Отчество, dbo.Сотрудники.Адрес,
dbo.Сотрудники.Отдел, dbo.Сотрудники.Домашний_телефон,
dbo.Должности.Требуемое_образование
FROM
dbo.Сотрудники INNER JOIN
dbo.Должности ON dbo.Сотрудники.Должность =
dbo.Должности.Должность
WHERE
(dbo.Должности.Требуемое_образование = 'Высшее')
--Препараты на букву "Ф" (VIEW)
CREATE VIEW [dbo].[Препараты_на_букву_Ф]
AS
SELECT Препарат, Цена, Отдел
FROM
dbo.Препараты
WHERE (Препарат LIKE 'Ф%')
GO
--Вывод ближайших поставок (VIEW)
CREATE VIEW [dbo].[Вывод_ближайших_поставок_препаратов]
AS
SELECT * From поставки
Where Дата>GetDate()
GO
Представление выглядит как таблица, собственно говоря, оно и
представляет из себя сохраненный запрос:
21
Создание триггеров
--Триггер удал_сотр
CREATE TRIGGER УДАЛ_СОТР
ON Сотрудники
INSTEAD OF DELETE
AS
DELETE
FROM Сотрудники
WHERE Должность <>'Заведующий'
IF EXISTS(SELECT *
FROM Deleted
WHERE Должность='Заведующий')
Print 'Нельзя удалить/уволить заведующего'
GO
--Триггер Запрет удаления Номерпост=6
CREATE TRIGGER НОМЕРПОСТ_6_НЕЛЬЗЯ_УДАЛИТЬ
ON Поставки
AFTER DELETE
AS
IF EXISTS (SELECT * FROM DELETED WHERE Номерпост=6)
BEGIN
ROLLBACK TRAN
PRINT 'Нельзя удалить'
END
GO
22
Создание оконного приложения и привязка к нему
базы данных
Приложение «Аптека» было написано на языке C# в IDE Visual Studio
2015 с использованием Windows Forms.
База данных подключалась к «форме» с помощью обозревателя
серверов. Использовался «Поставщик данных .NET Framework для
SQL Server».
Приложение представляет из себя окно с небольшим меню и
вкладками «Таблицы», «Представления» и «Управление данными».
В каждую вкладку интегрированы другие вкладки с собственным
разработанным дизайном.
• «Таблицы» - можно перемещаться по таблицам базы данных,
которые привязаны к инструменту dataGridView.
• «Представления» - можно перемещаться по представлениям из
базы данных.
• «Управление данными» - можно перемещаться по таблицам
базы данных и с помощью кнопок «Добавить», «Изменить» и
«Удалить» производить изменения в этих таблицах.
23
24
Приложение 2. Сценарий создания приложения
«Аптека» с помощью Windows Forms
using
using
using
using
using
using
using
using
using
using
System;
System.Collections.Generic;
System.ComponentModel;
System.Data;
System.Data.SqlClient;
System.Drawing;
System.Linq;
System.Text;
System.Threading.Tasks;
System.Windows.Forms;
namespace AptekaDB
{
public partial class Form1 : Form
{
SqlConnection sqlConnection;
public Form1()
{
InitializeComponent();
tabControl2.DrawItem += new
DrawItemEventHandler(tabControl2_DrawItem);
tabControl3.DrawItem += new
DrawItemEventHandler(tabControl3_DrawItem);
tabControl4.DrawItem += new
DrawItemEventHandler(tabControl4_DrawItem);
}
private async void Form1_Load(object sender, EventArgs e)
{
string connectionString = @"Data
Source=.;AttachDbFilename=C:\Database\AptekaDB\Coursework.mdf;Integrated
Security=True;Connect Timeout=30";
sqlConnection = new SqlConnection(connectionString);
await sqlConnection.OpenAsync();
// TODO: данная строка кода позволяет загрузить данные в таблицу
"courseworkDataSet.Сотрудники_с_высшим_образованием". При необходимости она
может быть перемещена или удалена.
this.сотрудники_с_высшим_образованиемTableAdapter.Fill(this.courseworkDataSet
.Сотрудники_с_высшим_образованием);
// TODO: данная строка кода позволяет загрузить данные в таблицу
"courseworkDataSet.Препараты_на_букву_Ф". При необходимости она может быть
перемещена или удалена.
this.препараты_на_букву_ФTableAdapter.Fill(this.courseworkDataSet.Препараты_н
а_букву_Ф);
// TODO: данная строка кода позволяет загрузить данные в таблицу
"courseworkDataSet.Вывод_ближайших_поставок_препаратов". При необходимости
она может быть перемещена или удалена.
this.вывод_ближайших_поставок_препаратовTableAdapter.Fill(this.courseworkData
Set.Вывод_ближайших_поставок_препаратов);
// TODO: данная строка кода позволяет загрузить данные в таблицу
"courseworkDataSet.Вывод_ближайших_поставок_препаратов". При необходимости
она может быть перемещена или удалена.
25
this.вывод_ближайших_поставок_препаратовTableAdapter.Fill(this.courseworkData
Set.Вывод_ближайших_поставок_препаратов);
// TODO: данная строка кода позволяет загрузить данные в таблицу
"courseworkDataSet.Сотрудники". При необходимости она может быть перемещена
или удалена.
this.сотрудникиTableAdapter.Fill(this.courseworkDataSet.Сотрудники);
// TODO: данная строка кода позволяет загрузить данные в таблицу
"courseworkDataSet.Рецепты". При необходимости она может быть перемещена или
удалена.
this.рецептыTableAdapter.Fill(this.courseworkDataSet.Рецепты);
// TODO: данная строка кода позволяет загрузить данные в таблицу
"courseworkDataSet.Препараты_по_рецептам". При необходимости она может быть
перемещена или удалена.
this.препараты_по_рецептамTableAdapter.Fill(this.courseworkDataSet.Препараты_
по_рецептам);
// TODO: данная строка кода позволяет загрузить данные в таблицу
"courseworkDataSet.Препараты". При необходимости она может быть перемещена
или удалена.
this.препаратыTableAdapter.Fill(this.courseworkDataSet.Препараты);
// TODO: данная строка кода позволяет загрузить данные в таблицу
"courseworkDataSet.Поставщики". При необходимости она может быть перемещена
или удалена.
this.поставщикиTableAdapter.Fill(this.courseworkDataSet.Поставщики);
// TODO: данная строка кода позволяет загрузить данные в таблицу
"courseworkDataSet.Поставляемые_препараты". При необходимости она может быть
перемещена или удалена.
this.поставляемые_препаратыTableAdapter.Fill(this.courseworkDataSet.Поставляе
мые_препараты);
// TODO: данная строка кода позволяет загрузить данные в таблицу
"courseworkDataSet.Поставки". При необходимости она может быть перемещена или
удалена.
this.поставкиTableAdapter.Fill(this.courseworkDataSet.Поставки);
// TODO: данная строка кода позволяет загрузить данные в таблицу
"courseworkDataSet.Отпуска". При необходимости она может быть перемещена или
удалена.
this.отпускаTableAdapter.Fill(this.courseworkDataSet.Отпуска);
// TODO: данная строка кода позволяет загрузить данные в таблицу
"courseworkDataSet.Отделы". При необходимости она может быть перемещена или
удалена.
this.отделыTableAdapter.Fill(this.courseworkDataSet.Отделы);
// TODO: данная строка кода позволяет загрузить данные в таблицу
"courseworkDataSet.Зарплаты". При необходимости она может быть перемещена или
удалена.
this.зарплатыTableAdapter.Fill(this.courseworkDataSet.Зарплаты);
// TODO: данная строка кода позволяет загрузить данные в таблицу
"courseworkDataSet.Должности". При необходимости она может быть перемещена
или удалена.
this.должностиTableAdapter.Fill(this.courseworkDataSet.Должности);
sqlConnection.Close();
}
private void btnExitProgram_Click(object sender, EventArgs e)
{
this.Close();
}
26
private void dataGridView1_CellContentClick(object sender,
DataGridViewCellEventArgs e)
{
}
private void tabControl2_DrawItem(Object sender,
System.Windows.Forms.DrawItemEventArgs e)
{
Graphics g = e.Graphics;
Brush _textBrush;
// Get the item from the collection.
TabPage _tabPage = tabControl2.TabPages[e.Index];
// Get the real bounds for the tab rectangle.
Rectangle _tabBounds = tabControl2.GetTabRect(e.Index);
if (e.State == DrawItemState.Selected)
{
// Draw a different background color, and don't paint a focus
rectangle.
_textBrush = new SolidBrush(Color.Black);
g.FillRectangle(Brushes.LightGray, e.Bounds);
}
else
{
_textBrush = new System.Drawing.SolidBrush(e.ForeColor);
e.DrawBackground();
}
// Use our own font.
Font _tabFont = new Font("Arial", 11.5f, FontStyle.Bold,
GraphicsUnit.Pixel);
// Draw string. Center the text.
StringFormat _stringFlags = new StringFormat();
_stringFlags.Alignment = StringAlignment.Center;
_stringFlags.LineAlignment = StringAlignment.Center;
g.DrawString(_tabPage.Text, _tabFont, _textBrush, _tabBounds, new
StringFormat(_stringFlags));
}
private void tabControl3_DrawItem(Object sender,
System.Windows.Forms.DrawItemEventArgs e)
{
Graphics g = e.Graphics;
Brush _textBrush;
// Get the item from the collection.
TabPage _tabPage = tabControl3.TabPages[e.Index];
// Get the real bounds for the tab rectangle.
Rectangle _tabBounds = tabControl3.GetTabRect(e.Index);
if (e.State == DrawItemState.Selected)
{
// Draw a different background color, and don't paint a focus
rectangle.
_textBrush = new SolidBrush(Color.Black);
g.FillRectangle(Brushes.LightGray, e.Bounds);
27
}
else
{
_textBrush = new System.Drawing.SolidBrush(e.ForeColor);
e.DrawBackground();
}
// Use our own font.
Font _tabFont = new Font("Arial", 11.5f, FontStyle.Bold,
GraphicsUnit.Pixel);
// Draw string. Center the text.
StringFormat _stringFlags = new StringFormat();
_stringFlags.Alignment = StringAlignment.Center;
_stringFlags.LineAlignment = StringAlignment.Center;
g.DrawString(_tabPage.Text, _tabFont, _textBrush, _tabBounds, new
StringFormat(_stringFlags));
}
private void tabControl4_DrawItem(Object sender,
System.Windows.Forms.DrawItemEventArgs e)
{
Graphics g = e.Graphics;
Brush _textBrush;
// Get the item from the collection.
TabPage _tabPage = tabControl4.TabPages[e.Index];
// Get the real bounds for the tab rectangle.
Rectangle _tabBounds = tabControl4.GetTabRect(e.Index);
if (e.State == DrawItemState.Selected)
{
// Draw a different background color, and don't paint a focus
rectangle.
_textBrush = new SolidBrush(Color.Black);
g.FillRectangle(Brushes.LightGray, e.Bounds);
}
else
{
_textBrush = new System.Drawing.SolidBrush(e.ForeColor);
e.DrawBackground();
}
// Use our own font.
Font _tabFont = new Font("Arial", 11.5f, FontStyle.Bold,
GraphicsUnit.Pixel);
// Draw string. Center the text.
StringFormat _stringFlags = new StringFormat();
_stringFlags.Alignment = StringAlignment.Center;
_stringFlags.LineAlignment = StringAlignment.Center;
g.DrawString(_tabPage.Text, _tabFont, _textBrush, _tabBounds, new
StringFormat(_stringFlags));
}
private void button1_Click_1(object sender, EventArgs e)
{
string connectionString = @"Data
Source=.;AttachDbFilename=C:\Database\AptekaDB\Coursework.mdf;Integrated
Security=True;Connect Timeout=30";
28
using (SqlConnection connection = new
SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand("Insert Into Препараты
(Препарат, Цена) Values(@Preparat, @Cena)", connection);
command.Parameters.AddWithValue("@Preparat", textBox1.Text);
command.Parameters.AddWithValue("@Cena", textBox2.Text);
command.ExecuteNonQuery();
MessageBox.Show(
"Добавлена запись в таблицу Препараты",
"Сообщение",
MessageBoxButtons.OK,
MessageBoxIcon.Information,
MessageBoxDefaultButton.Button1
);
this.препаратыTableAdapter.Fill(this.courseworkDataSet.Препараты);
this.препараты_на_букву_ФTableAdapter.Fill(this.courseworkDataSet.Препараты_н
а_букву_Ф);
textBox1.Clear();
textBox2.Clear();
connection.Close();
}
}
private void button2_Click(object sender, EventArgs e)
{
string connectionString = @"Data
Source=.;AttachDbFilename=C:\Database\AptekaDB\Coursework.mdf;Integrated
Security=True;Connect Timeout=30";
using (SqlConnection connection = new
SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand("DELETE FROM Препараты
WHERE Препарат = @Preparat", connection);
command.Parameters.AddWithValue("@Preparat", textBox4.Text);
try
{
command.ExecuteNonQuery();
MessageBox.Show(
"Удалена запись из таблицы Препараты",
"Сообщение",
MessageBoxButtons.OK,
MessageBoxIcon.Information,
MessageBoxDefaultButton.Button1
);
}
catch (SqlException ex)
{
Exception error = new Exception("Такого препарата нет в
таблице!", ex);
throw error;
}
this.препаратыTableAdapter.Fill(this.courseworkDataSet.Препараты);
29
this.препараты_на_букву_ФTableAdapter.Fill(this.courseworkDataSet.Препараты_н
а_букву_Ф);
textBox4.Clear();
connection.Close();
}
}
private void button3_Click(object sender, EventArgs e)
{
string connectionString = @"Data
Source=.;AttachDbFilename=C:\Database\AptekaDB\Coursework.mdf;Integrated
Security=True;Connect Timeout=30";
using (SqlConnection connection = new
SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand("UPDATE Препараты SET
Цена = @Cena WHERE Препарат = @Preparat", connection);
command.Parameters.AddWithValue("@Preparat", textBox5.Text);
command.Parameters.AddWithValue("@Cena", textBox3.Text);
command.ExecuteNonQuery();
MessageBox.Show(
"Изменена запись в таблице Препараты",
"Сообщение",
MessageBoxButtons.OK,
MessageBoxIcon.Information,
MessageBoxDefaultButton.Button1
);
this.препаратыTableAdapter.Fill(this.courseworkDataSet.Препараты);
this.препараты_на_букву_ФTableAdapter.Fill(this.courseworkDataSet.Препараты_н
а_букву_Ф);
textBox5.Clear();
textBox3.Clear();
connection.Close();
}
}
private void инфоToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show(
@"Файл C:\Database\AptekaDB\Coursework.mdf является
исходником базы данных Аптека. База данных содержит 11 таблиц, 3
представления и 3 хранимых процедуры",
"Инфо",
MessageBoxButtons.OK,
MessageBoxIcon.Information,
MessageBoxDefaultButton.Button1
);
}
private void dataGridView8_CellContentClick(object sender,
DataGridViewCellEventArgs e)
{
}
}
}
30
Список литературы
1. Семенова-Тян-Шанская В.А. – Создание баз данных в среде SQL
Server Management Studio, СПб, 2017
2. А.Д. Хомоненко «Базы данных» СПб, Корона-принт, 2004 г
3. Кевин Клайн «SQL справочник» М, Кудиц-образ, 2006
4. Леон Аткинсон «MySQL. Библиотека профессионала» M,
«Вильяме», 2002
5. Функции SQL. Справочник программиста, Эйри Джоунс, Райан К.
Стивенз, Рональд Р. Плю, Роберт Ф. Гарретт, Алекс Кригель
6. https://metanit.com/sql/
7. http://2sql.ru/
31
Download