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

Запрос:

CREATE FUNCTION rest.ufn_MenuItemSalesPaid (

@ItemID INT,

@SalesDate DATE

)

RETURNS INT

AS

BEGIN

DECLARE @Count INT;

SELECT @Count = SUM(oi.Quantity)

FROM rest.OrderItems oi

JOIN rest.Orders o ON oi.OrderID = o.OrderID

WHERE oi.ItemID = @ItemID

AND CAST(o.OrderDateTime AS DATE) = @SalesDate

AND o.Status = 'Оплачен';

RETURN ISNULL(@Count, 0);

END;

GO

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

DECLARE @SalesCount INT;

SET @SalesCount = rest.ufn_MenuItemSalesPaid(5, '2025-12-04');

PRINT 'Блюдо с ItemID = 5 продано сегодня в количестве: ' + CAST(@SalesCount AS NVARCHAR(10));

Результат выполнения (рис. 40).

Рисунок 40. Результат работы функции подсчета блюд

  1. Разработка триггеров

  1. Триггер «InsertWaiterTable» для вставки в таблицу WaiterTables, когда происходит заказ

Запрос:

CREATE OR ALTER TRIGGER rest.trg_InsertWaiterTable

ON rest.Orders

AFTER INSERT, UPDATE

AS

BEGIN

SET NOCOUNT ON;

INSERT INTO rest.WaiterTables (StaffID, TableID, StartTime, EndTime)

SELECT i.WaiterID, i.TableID, GETDATE(), NULL

FROM inserted i

WHERE NOT EXISTS (

SELECT 1

FROM rest.WaiterTables wt

WHERE wt.StaffID = i.WaiterID

AND wt.TableID = i.TableID

AND wt.EndTime IS NULL

);

UPDATE wt

SET EndTime = GETDATE()

FROM rest.WaiterTables wt

JOIN inserted i ON wt.StaffID = i.WaiterID AND wt.TableID = i.TableID

JOIN rest.Orders o ON o.OrderID = i.OrderID

WHERE o.Status = 'Оплачен' AND wt.EndTime IS NULL;

END;

GO

После создания триггера было создано несколько заказов.

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

  1. Выводим таблицу относительно столов

SELECT

s.StaffID,

s.FirstName,

s.LastName,

t.TableID,

t.TableNumber,

wt.StartTime,

wt.EndTime

FROM rest.Staff s

JOIN rest.WaiterTables wt ON s.StaffID = wt.StaffID

JOIN rest.Tables t ON wt.TableID = t.TableID

ORDER BY s.StaffID, t.TableID;

Результат выполнения запроса (рис. 41).

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

  1. Выводим таблицу относительно официантов

SELECT

t.TableID,

t.TableNumber,

s.StaffID,

s.FirstName,

s.LastName,

wt.StartTime,

wt.EndTime

FROM rest.Tables t

JOIN rest.WaiterTables wt ON t.TableID = wt.TableID

JOIN rest.Staff s ON wt.StaffID = s.StaffID

ORDER BY t.TableID, s.StaffID;

Результат выполнения (рис. 42).

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

  1. Триггер «CheckStock», уменьшающий количество блюд в MenuItems и предупреждающий, если блюда закончились

Запрос:

CREATE TRIGGER rest.trg_CheckStock

ON rest.OrderItems

INSTEAD OF INSERT

AS

BEGIN

INSERT INTO rest.OrderItems (OrderID, ItemID, Quantity, UnitPrice, SpecialInstructions)

SELECT i.OrderID, i.ItemID, i.Quantity, i.UnitPrice, i.SpecialInstructions

FROM inserted i

JOIN rest.MenuItems m ON i.ItemID = m.ItemID

WHERE m.IsAvailable = 1

AND m.Stock >= i.Quantity;

UPDATE m

SET m.Stock = m.Stock - i.Quantity,

m.IsAvailable = CASE WHEN m.Stock - i.Quantity <= 0 THEN 0 ELSE 1 END

FROM rest.MenuItems m

JOIN inserted i ON m.ItemID = i.ItemID

WHERE m.IsAvailable = 1

AND m.Stock >= i.Quantity;

IF EXISTS (

SELECT 1

FROM inserted i

JOIN rest.MenuItems m ON i.ItemID = m.ItemID

WHERE m.IsAvailable = 0 OR m.Stock < i.Quantity

)

BEGIN

PRINT 'Внимание: некоторые выбранные блюда недоступны или количество порций ограничено.';

END

END;

GO

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

Создаем заказ, где блюдо берется максимальное количество раз:

EXEC rest.AddItemToOrder

@OrderID = 6,

@ItemID = 7,

@Quantity = 8;

EXEC rest.SetOrderWaitingForPayment @OrderID = 6;

EXEC rest.PayOrder

@OrderID = 6,

@Amount = 6000,

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

Запрос успешно выполнен (рис.43).

Рисунок 43. Выполнение запроса

Далее проверим таблицу MenuItems и увидим, что блюдо, которое мы заказывали максимальное количество раз, закончилось (рис. 44).

Рисунок 44. Результат работы триггера на уменьшение кол-ва блюд