Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
БД_ресторан_5семестр.doc
Скачиваний:
0
Добавлен:
23.01.2026
Размер:
1.76 Mб
Скачать
  1. Триггер «PreventWaitingPaymentWithoutItems», проверяющий пустой заказ

Запрос:

CREATE OR ALTER TRIGGER trg_PreventWaitingPaymentWithoutItems

ON Orders

INSTEAD OF UPDATE

AS

BEGIN

SET NOCOUNT ON;

IF EXISTS (

SELECT 1

FROM inserted i

JOIN deleted d ON i.OrderID = d.OrderID

WHERE i.Status = 'Ожидает оплаты' AND d.Status <> 'Ожидает оплаты'

)

BEGIN

IF EXISTS (

SELECT 1

FROM inserted i

LEFT JOIN OrderItems oi ON i.OrderID = oi.OrderID

GROUP BY i.OrderID

HAVING COUNT(oi.ItemID) = 0

)

BEGIN

RAISERROR('Невозможно перевести заказ в "Ожидает оплаты": в заказе нет блюд.', 16, 1);

RETURN;

END

END

UPDATE o

SET o.Status = i.Status,

o.Notes = i.Notes,

o.TableID = i.TableID,

o.WaiterID = i.WaiterID

FROM Orders o

JOIN inserted i ON o.OrderID = i.OrderID;

END;

GO

Пример использования

  1. Пустой заказ

Создаем который не будет заполнен блюдами, после чего попытаемся его перевести в статус ожидания оплаты:

DECLARE @OrderID INT;

EXEC rest.CreateOrder

@TableID = 5,

@WaiterID = 4,

@Notes = 'Разделить блюдо на две порции',

@NewOrderID = @OrderID OUTPUT;

PRINT 'Создан заказ с ID = ' + CAST(@OrderID AS NVARCHAR(10));

EXEC rest.SetOrderWaitingForPayment @OrderID = 10;

Ошибка выполнения запроса (рис. 45).

Рисунок 45. Результат работы триггера на проверку заказов без блюд

  1. Правильный запрос

EXEC rest.AddItemToOrder

@OrderID = 10,

@ItemID = 5,

@Quantity = 1;

EXEC rest.SetOrderWaitingForPayment @OrderID = 10;

EXEC rest.PayOrder

@OrderID = 10,

@Amount = 6000,

@PaymentMethod = 'Наличные';

При корректном запросе оплата заказа успешно проходит (рис. 45).

Рисунок 45. Результат работы триггера на проверку корректных заказов

  1. Разработка стратегии резервного копирования и восстановления

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

  1. Процедура полного резервного копирования

Повтор при сбоях реализован через встроенный механизм 3-х попыток с задержкой 5 секунд между ними для надежности. Уникальные имена файлов обеспечиваются автоматическим формированием с использованием timestamp, что предотвращает конфликты и упорядочивает версии. Сжатие данных задействует технологию COMPRESSION для значительной экономии дискового пространства без потери информации. Изоляция файлов достигается за счет хранения в отдельной папке D:\Backup\FULL.

USE master;

GO

CREATE OR ALTER PROCEDURE dbo.sp_Restaurant_BackupFull

@RetryCount INT = 3

AS

BEGIN

SET NOCOUNT ON;

DECLARE @BackupPath NVARCHAR(500);

DECLARE @Attempt INT = 1;

DECLARE @Success BIT = 0;

DECLARE @ErrorMessage NVARCHAR(4000);

SET @BackupPath = N'D:\Backup\FULL\DataBase_Restaurant_FULL_' +

REPLACE(CONVERT(NVARCHAR(20), GETDATE(), 120), ':', '-') + '.bak';

PRINT 'ПОЛНОЕ РЕЗЕРВНОЕ КОПИРОВАНИЕ БАЗЫ RESTAURANT';

PRINT 'Файл: ' + @BackupPath;

WHILE @Attempt <= @RetryCount AND @Success = 0

BEGIN

BEGIN TRY

PRINT 'Попытка ' + CAST(@Attempt AS NVARCHAR) + '...';

BACKUP DATABASE [DataBase_Restaurant]

TO DISK = @BackupPath

WITH FORMAT,

INIT,

NAME = N'Restaurant - Full Database Backup',

STATS = 10,

COMPRESSION;

PRINT 'Бэкап успешно создан!';

SET @Success = 1;

END TRY

BEGIN CATCH

SET @ErrorMessage = ERROR_MESSAGE();

PRINT 'Ошибка: ' + @ErrorMessage;

SET @Attempt = @Attempt + 1;

IF @Attempt <= @RetryCount

BEGIN

PRINT 'Повторная попытка через 5 секунд...';

WAITFOR DELAY '00:00:05';

END

END CATCH

END

IF @Success = 0

RAISERROR('Не удалось выполнить резервное копирование после %d попыток.', 16, 1, @RetryCount);

END;

GO