- •Аннотация
- •Содержание
- •Введение
- •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
- •Процедура восстановления
- •Заключение
- •Список использованных источников
Процедура «SetOrderWaitingForPayment» для перевода заказа в статус ожидания оплаты
В данной процедуре проверяется, существует ли указанный заказ и имеет ли он статус «Принят». Также, если сумма заказа равна 0 (то есть в него не добавлены никакие позиции), процедура не выполнится.
Запрос:
CREATE PROCEDURE rest.SetOrderWaitingForPayment
@OrderID INT
AS
BEGIN
SET NOCOUNT ON;
IF NOT EXISTS (SELECT 1 FROM rest.Orders WHERE OrderID = @OrderID)
BEGIN
PRINT 'Ошибка: заказ не найден.';
RETURN;
END
DECLARE @CurrentStatus NVARCHAR(20);
SELECT @CurrentStatus = Status FROM rest.Orders WHERE OrderID = @OrderID;
IF @CurrentStatus <> 'Принят'
BEGIN
PRINT 'Заказ не находится в статусе "Принят" и не может быть переведён в "Ожидает оплаты".';
RETURN;
END
DECLARE @TotalAmount DECIMAL(10,2);
SELECT @TotalAmount = rest.ufn_OrderTotal(@OrderID);
UPDATE rest.Orders
SET Status = 'Ожидает оплаты'
WHERE OrderID = @OrderID;
PRINT 'Заказ будет переведён в статус "Ожидает оплаты", если сумма к оплате больше 0.';
PRINT 'Сумма к оплате: ' + CAST(@TotalAmount AS NVARCHAR(20)) + ' руб.';
END;
GO
Примеры использования
Несуществующий заказ
Запрос, в котором применим процедуру к несуществующему заказу:
EXEC rest.SetOrderWaitingForPayment @OrderID = 15;
Ошибка выполнения (рис. 27).
Рисунок 27. Выполнение запроса
Заказ указан корректно
EXEC rest.SetOrderWaitingForPayment @OrderID = 9;
При корректном запросе увидим сообщение о переводе заказа в режим ожидания оплаты и сумму к оплате (рис. 28).
Рисунок 28. Выполнение запроса
Процедура «PayOrder» для оплаты заказа
В данной процедуре мы указываем заказ, сумму для оплаты и способ оплаты. Процедура проверяет параметры и в случае корректного ввода совершает оплату заказа. Если заплатили меньше, чем нужно, оплата не пройдет. Если заплатили больше, чем указанная сумма, остаток засчитывается как чаевые официанту.
CREATE PROCEDURE rest.PayOrder
@OrderID INT,
@Amount DECIMAL(10,2),
@PaymentMethod NVARCHAR(20)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @CurrentStatus NVARCHAR(20),
@Total DECIMAL(10,2),
@Overpayment DECIMAL(10,2);
IF NOT EXISTS (SELECT 1 FROM rest.Orders WHERE OrderID = @OrderID)
BEGIN
PRINT 'Ошибка: заказ не найден.';
RETURN;
END
SELECT @CurrentStatus = Status
FROM rest.Orders
WHERE OrderID = @OrderID;
IF @CurrentStatus <> 'Ожидает оплаты'
BEGIN
PRINT 'Заказ не находится в статусе "Ожидает оплаты". Оплата невозможна.';
RETURN;
END
SET @Total = rest.ufn_OrderTotal(@OrderID);
IF @Amount < @Total
BEGIN
PRINT 'Ошибка: сумма оплаты меньше полной стоимости заказа. Статус заказа не изменен.';
RETURN;
END
SET @Overpayment = @Amount - @Total;
INSERT INTO rest.Payments (OrderID, PaymentMethod, Amount, TipAmount)
VALUES (@OrderID, @PaymentMethod, @Total, @Overpayment);
UPDATE rest.Orders
SET Status = 'Оплачен', CompletedDate = GETDATE()
WHERE OrderID = @OrderID;
IF @Overpayment > 0
BEGIN
PRINT 'Заказ успешно оплачен. Чаевые официанту: ' + CAST(@Overpayment AS NVARCHAR(20)) + ' руб.';
END
ELSE
BEGIN
PRINT 'Заказ успешно оплачен.';
END
END;
GO
Примеры использования
Оплата несуществующего заказа
Запрос:
EXEC rest.PayOrder
@OrderID = 15,
@Amount = 150.50,
@PaymentMethod = 'Наличные';
Ошибка выполнения процедуры (рис. 29).
Рисунок 29. Выполнение запроса
Оплата заказа, у которого не стоит статус «Ожидает оплаты»
Запрос для оплаченного или принятого заказа:
EXEC rest.PayOrder
@OrderID = 10,
@Amount = 150.50,
@PaymentMethod = 'Наличные';
Ошибка выполнения процедуры (рис. 30).
Рисунок 30. Выполнение запроса
Недостаточно средств для оплаты
Запрос, в котором в поле оплаты введена слишком маленькая сумма:
EXEC rest.PayOrder
@OrderID = 9,
@Amount = 150.50,
@PaymentMethod = 'Наличные';
Ошибка выполнения запроса, потому что недостаточно средств (рис. 31).
Рисунок 31. Выполнение запроса
Корректный запрос
EXEC rest.PayOrder
@OrderID = 9,
@Amount = 3000,
@PaymentMethod = 'Наличные';
Оплата прошла успешно, остаток средств зачислен официанту в качестве чаевых (рис. 32).
Рисунок 32. Выполнение запроса
