- •Аннотация
- •Содержание
- •Введение
- •1. Формулировка задания
- •1.1. Задание
- •1.2. Структура идз
- •Описание предметной области
- •Проектирование базы данных
- •Создание бАзы данных
- •Создание таблиц и ограничений целостности
- •Заполнение таблиц данными
- •Заполнение таблицы «Staff» (Сотрудники)
- •Заполнение таблицы «Tables» (Столы):
- •Заполнение таблицы «Categories» (Категории)
- •Заполнение таблицы «MenuItems» (Меню)
- •Заполнение таблицы «Orders» (Заказы)
- •Заполнение таблицы «OrderItems» (Позиции заказа)
- •Заполнение таблицы «Payments» (Платежи)
- •Разработка объектов промежуточного слоя
- •Хранимые процедуры
- •Процедура «CreateOrder» для создания нового заказа
- •Процедура «AddItemToOrder» для добавления позиций в заказ
- •Процедура «SetOrderWaitingForPayment» для перевода заказа в статус ожидания оплаты
- •Процедура «PayOrder» для оплаты заказа
- •Представления
- •Представление «ActiveOrders» для просмотра активных заказов
- •Представление «WaiterDailyRevenue», показывающее выручку, принесённую каждым из официантов
- •Представление «DailyOrderStats», показывающее по дням заработок ресторана, оплаченные заказы, средний чек
- •Представление «OrdersByWaiterStatus», показывающее количество заказов, обслуженных каждым из официантов по статусам заказа
- •Функции
- •Скалярная функция «OrderTotal» для подсчета стоимости заказа
- •Табличная функция «GetOrdersWithTotal», которая возвращает блюда по заказам
- •Табличная функция «GetMenuItemsByAvailability», показывающая оставшиеся блюда
- •Табличная функция «GetLastOrderItems» возвращающая последние блюда в заказах
- •Скалярная функция «MenuItemSalesPaid» для подсчета проданных позиций блюд в день
- •Разработка триггеров
- •Триггер «InsertWaiterTable» для вставки в таблицу WaiterTables, когда происходит заказ
- •Триггер «CheckStock», уменьшающий количество блюд в MenuItems и предупреждающий, если блюда закончились
- •Триггер «PreventWaitingPaymentWithoutItems», проверяющий пустой заказ
- •Разработка стратегии резервного копирования и восстановления
- •Процедура полного резервного копирования
- •Процедура дифференциального резервного копирования
- •Процедура резервного копирования журнала транзакций
- •Процедура тестирования всех бэкапов
- •Автоматизация через sql server agent
- •Процедура восстановления
- •Заключение
- •Список использованных источников
Заполнение таблицы «OrderItems» (Позиции заказа)
Запрос для внесения данных в таблицу:
INSERT INTO rest.OrderItems (OrderID, ItemID, Quantity, UnitPrice)
VALUES
(1, 10, 1, 180),
(2, 2, 1, 300),
(2, 12, 2, 150),
(3, 5, 1, 650),
(3, 6, 2, 200),
(4, 3, 1, 1200),
(5, 4, 2, 350),
(5, 11, 2, 180);
Проверим выполнение запроса (рис. 17).
Рисунок 17. Данные в таблице позиций заказов
Заполнение таблицы «Payments» (Платежи)
Запрос для внесения данных в таблицу:
INSERT INTO rest.Payments (OrderID, PaymentMethod, Amount, TipAmount)
VALUES
(1, 'Наличные', 820, 50),
(2, 'Карта', 600, 40),
(3, 'Карта', 1050, 70),
(4, 'Наличные', 1600, 100),
(5, 'Онлайн', 1060, 60);
Проверим выполнение запроса (рис. 18).
Рисунок 18. Данные в таблице категорий меню
Таблица WaiterTables не заполняется вручную, для нее будет создан триггер автоматического заполнения в следующем разделе.
Разработка объектов промежуточного слоя
Хранимые процедуры
Процедура «CreateOrder» для создания нового заказа
В данной процедуре мы указываем стол, официанта и примечания к заказу. Процедура проверяет первые два параметра и в случае корректного ввода создает заказ с новым номером.
Запрос:
CREATE PROCEDURE rest.CreateOrder
@TableID INT,
@WaiterID INT,
@Notes NVARCHAR(500) = NULL,
@NewOrderID INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
IF NOT EXISTS (SELECT 1 FROM rest.Tables WHERE TableID = @TableID)
BEGIN
PRINT 'Ошибка: стол не найден.';
RETURN;
END
IF NOT EXISTS (SELECT 1 FROM rest.Staff WHERE StaffID = @WaiterID AND Position = 'Официант')
BEGIN
PRINT 'Ошибка: официант не найден или не имеет должности "Официант".';
RETURN;
END
INSERT INTO rest.Orders (TableID, WaiterID, Status, Notes)
VALUES (@TableID, @WaiterID, 'Принят', @Notes);
SET @NewOrderID = SCOPE_IDENTITY();
PRINT 'Заказ успешно создан. OrderID = ' + CAST(@NewOrderID AS NVARCHAR(10));
END
GO
Примеры использования:
Когда стол указан неверно
Напишем запрос, в котором укажем несуществующий стол (всего у нас пять столов, а мы указываем десятый):
DECLARE @OrderID INT;
EXEC rest.CreateOrder
@TableID = 10,
@WaiterID = 2,
@Notes = 'Без соли',
@NewOrderID = @OrderID OUTPUT;
PRINT 'Создан заказ с ID = ' + CAST(@OrderID AS NVARCHAR(10));
В Messages увидим ошибку выполнения процедуры, так как стол будет не найден (рис. 19).
Рисунок 19. Выполнение ошибочного запроса
Когда официант указан неверно
Теперь укажем существующий стол, но впишем сотрудника, не являющегося официантом:
DECLARE @OrderID INT;
EXEC rest.CreateOrder
@TableID = 1,
@WaiterID = 5,
@Notes = 'Без соли',
@NewOrderID = @OrderID OUTPUT;
PRINT 'Создан заказ с ID = ' + CAST(@OrderID AS NVARCHAR(10));
В Messages увидим ошибку выполнения процедуры, так как сотрудник не существует или не является официантом (рис. 20).
Рисунок 20. Выполнение запроса
Правильный запрос
Напишем запрос, где всё указано корректно:
DECLARE @OrderID INT;
EXEC rest.CreateOrder
@TableID = 1,
@WaiterID = 4,
@Notes = 'Без соли',
@NewOrderID = @OrderID OUTPUT;
PRINT 'Создан заказ с ID = ' + CAST(@OrderID AS NVARCHAR(10));
Запрос успешно выполнен, мы видим новый созданный заказ (рис. 21).
Рисунок 21. Выполнение запроса
