Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
0
Добавлен:
24.01.2026
Размер:
12.85 Mб
Скачать

МИНОБРНАУКИ РОССИИ

Санкт-Петербургский государственный

электротехнический университет

«ЛЭТИ» им. В.И. Ульянова (Ленина)

Кафедра Систем автоматизированного проектирования

отчет

по лабораторной работе №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 объединила данные из нескольких таблиц, рассчитала сумму скидки и итоговую цену товара, а также предоставила возможность фильтрации по текущим и историческим скидкам. В результате работы освоено создание пользовательских функций разных типов, применение параметров, использование агрегатных выражений, фильтрацию по диапазонам дат и объединение данных из связанных таблиц.

Соседние файлы в папке БД_лабы(11 лаб, 5 семестр)