БД_лабы(11 лаб, 5 семестр) / БД_ЛР9
.docxМИНОБРНАУКИ РОССИИ
Санкт-Петербургский государственный
электротехнический университет
«ЛЭТИ» им. В.И. Ульянова (Ленина)
Кафедра Систем автоматизированного проектирования
отчет
по лабораторной работе №9
по дисциплине «Базы Данных»
Тема: СОЗДАНИЕ UDF
Студенты гр. 3352 |
________________ |
Гареева К.Р. |
|
________________ |
Жигунова О.М. |
Преподаватель |
________________ |
Горяинов С.В. |
Санкт-Петербург
2025
Цель работы
Научиться писать и применять функции, определяемые гользователем (UDF). В лабораторной работе используются две базы даных: Adventure Works и AdventureWorksDW. Перед выполнением работы откройте файл InitializeData.sql и выполните его.
Упражнение 1 - создание скалярной функции.
Запрос 1
Создадим скалярную функцию (UDF), которая принимает название категории (@Category) и возвращает максимальный процент скидки из таблиц, где указаны скидки, действующие сегодня (между StartDate и EndDate).
CREATE FUNCTION Sales.GetMaximumDiscountForCategory
( @Category NVARCHAR(50))
RETURNS DECIMAL(5,2)
AS
BEGIN
DECLARE @MaxDiscount DECIMAL(5,2);
SELECT @MaxDiscount = MAX(so.DiscountPct * 100)
FROM Sales.SpecialOffer AS so
INNER JOIN Sales.SpecialOfferProduct AS sop ON so.SpecialOfferID = sop.SpecialOfferID
INNER JOIN Production.Product AS p ON sop.ProductID = p.ProductID
INNER JOIN Production.ProductSubcategory AS ps ON p.ProductSubcategoryID = ps.ProductSubcategoryID
INNER JOIN Production.ProductCategory AS pc ON ps.ProductCategoryID = pc.ProductCategoryID
WHERE pc.Name = @Category
AND GETDATE() BETWEEN so.StartDate AND so.EndDate;
RETURN ISNULL(@MaxDiscount, 0);
END;
GO
Рисунок 1 - Результат выполнения запроса 1.
Запрос 2
Проверим результат выполнения первого запроса (рис. 2) с помощью команды:
SELECT Sales.GetMaximumDiscountForCategory('Reseller');
Рисунок 2 - Проверка выполнения запроса 1.
Упражнение 2- создание функции, возвращающей табличное значение (In-Line Table-valued UDF).
Запрос 3
Создадим табличную функцию (In-line Table-Valued Function), которая возвращает те же данные, что и хранимая процедура из предыдущей лабораторной, но с возможностью указать дату, для которой нужно отфильтровать действующие скидки.
Функция возвращает таблицу со всеми полями, принимает параметр @DateToCheck (тип datetime), показывает только те скидки, которые активны на указанную дату (между StartDate и EndDate).
CREATE FUNCTION Sales.GetDiscountsForDate
(@DateToCheck DATETIME)
RETURNS TABLE
AS
RETURN
(SELECT
Description,
DiscountPct,
Type,
Category,
StartDate,
EndDate,
MinQty,
MaxQty
FROM Sales.SpecialOffer
WHERE @DateToCheck BETWEEN StartDate AND EndDate
);
GO
Рисунок 3 - Результат выполнения запроса 3.
Проверим результат выполнения первого запроса (рис. 4) с помощью команды:
SELECT *
FROM Sales.GetDiscountsForDate(GETDATE())
ORDER BY DiscountPct DESC;
Рисунок 4 - Результат выполнения запроса 4
Упражнение 3- создание функции, возвращающей табличное значение (Multi-Statement Table-valued UDF).
Запрос 5
Создадим многооператорную табличную функцию (Multi-statement table-valued UDF). В отличие от In-Line функции (упр. 2), здесь структура таблицы задается самостоятельно и пошагово наполняется.
Функция Sales.GetDiscountedProducts, возвращает сведения о продуктах с действующими или завершившимися скидками, объединяет данные из трёх таблиц — Production.Product, Sales.SpecialOffer, Sales.SpecialOfferProduct — и вычисляет сумму и итоговую цену после скидки.
CREATE FUNCTION Sales.GetDiscountedProducts(@IncludeHistory BIT)
RETURNS @DiscountedProducts TABLE
(
ProductID INT,
Name NVARCHAR(50),
ListPrice MONEY,
DiscountDescription NVARCHAR(255),
DiscountPercentage SMALLMONEY,
DiscountAmount MONEY,
DiscountedPrice MONEY
)
AS
BEGIN
INSERT INTO @DiscountedProducts
SELECT
p.ProductID,
p.Name,
p.ListPrice,
so.Description AS DiscountDescription,
so.DiscountPct AS DiscountPercentage,
p.ListPrice * so.DiscountPct AS DiscountAmount,
p.ListPrice - (p.ListPrice * so.DiscountPct) AS DiscountedPrice
FROM Sales.SpecialOfferProduct sop
JOIN Sales.SpecialOffer so ON sop.SpecialOfferID = so.SpecialOfferID
JOIN Production.Product p ON sop.ProductID = p.ProductID
WHERE
@IncludeHistory = 1
OR (GETDATE() BETWEEN so.StartDate AND so.EndDate);
RETURN;
END;
GO
Рисунок 5 - Результат выполнения запроса 5.
Запрос 6
Сделаем проверку написанной функции. При вызове SELECT * FROM Sales.GetDiscountedProducts(0) выводятся только активные скидки, в нашем случае их нет. При вызове SELECT * FROM Sales.GetDiscountedProducts(1) выводятся все скидки, включая завершённые (рис. 6).
SELECT * FROM Sales.GetDiscountedProducts(0);
SELECT * FROM Sales.GetDiscountedProducts(1);
Рисунок 6 - Результат выполнения запроса 6
Вывод
В ходе выполнения лабораторной работы были изучены принципы создания и применения пользовательских функций (User Defined Functions, UDF). В процессе работы были реализованы три типа функций: скалярная, табличная и многооператорная. Скалярная функция Sales.GetMaximumDiscountForCategory позволила определить максимальный процент скидки для выбранной категории товаров на текущую дату. Табличная функция Sales.GetDiscountsForDate была разработана для получения всех активных скидок, действующих на указанную дату. Многооператорная табличная функция Sales.GetDiscountedProducts объединила данные из нескольких таблиц, рассчитала сумму скидки и итоговую цену товара, а также предоставила возможность фильтрации по текущим и историческим скидкам. В результате работы освоено создание пользовательских функций разных типов, применение параметров, использование агрегатных выражений, фильтрацию по диапазонам дат и объединение данных из связанных таблиц.
