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

Кашина_ТРиЗБД_ЛБ6

.docx
Скачиваний:
0
Добавлен:
03.12.2025
Размер:
1.48 Mб
Скачать

Министерство науки и высшего образования Российской Федерации Федеральное государственное бюджетное образовательное учреждение высшего образования

«Владимирский государственный университет

имени Александра Григорьевича и Николая Григорьевича Столетовых» (ВлГУ)

Колледж инновационных технологий и предпринимательства

КАФЕДРА ФИЗИКИ И ПРИКЛАДНОЙ МАТЕМАТИКИ

Лабораторная работа № 6

по дисциплине «Технология разработки и защиты баз данных»

на тему: «Основы программирования с помощью встроенного языка TRANSACT-SQL в MS SQL Server.»

Выполнил

студент группы ИПсп-123

Кашина Д. А.

Принял

Кабанова М.Ю.

Владимир, 2025

Цель работы:

1. Изучить используемый в реляционных СУБД встроенный язык программирования TransactSQL для написания программ в MS SQL Server.

2. Изучить правила построения идентификаторов, правила объявления переменных и их типов.

3. Изучить принципы работы с циклами и ветвлениями.

4. Изучить работу с переменными типа Table.

5. Изучить синтаксис и семантику функций и хранимых процедур Transact– SQL: способов их идентификации, методов задания и спецификации параметров и возвращаемых значений, и вызовов функций и хранимых процедур.

Ход работы:

Самостоятельные запросы

/*Кашина 2.10.25

Подсчитать среднюю зарплату преподавателей(с помощью SELECT) и умножить ее на 123.34,

которое необходимо сохранить в отдельной переменной, и вывести значение переменной на экран*/

USE University_Кашина_Диана

DECLARE @avg_salary DECIMAL(10,2);

DECLARE @result DECIMAL(10,2);

SELECT @avg_salary = AVG(salary+rise) FROM Teacher

SET @result = @avg_salary * 123.34;

SELECT @result AS результат;

/*Кашина 2.10.25

Подсчитать суммарное значение всех стипендий у студентов, результат поместить

в переменную, вывести значение переменной на экран.*/

USE University_Кашина_Диана

DECLARE @total_stipend DECIMAL(10,2);

SELECT @total_stipend = SUM(Stipend) FROM Student1;

SELECT @total_stipend AS общая_сумма_стипендий;

  1. Подсчитать количество кафедр, результат поместить в переменную, вывести значение переменной на экран.

/*Кашина 2.10.25

Подсчитать количество кафедр, результат поместить в переменную,

вывести значение переменной на экран*/

USE University_Кашина_Диана

DECLARE @count_kafedr INT;

SELECT @count_kafedr = COUNT(*) FROM Kafedra;

SELECT @count_kafedr AS 'Количество кафедр';

  1. Создать локальную таблицу с названием TEMP и полями типа дата/время, длинное целое, строка. Добавить в нее две записи с данными и вывести результат на экран.

/*Кашина 2.10.25

Создать локальную таблицу с названием TEMP и полями типа дата/время,

длинное целое, строка. Добавить в нее две записи с данными и вывести результат на экран.*/

USE University_Кашина_Диана

--Создание временной таблицы

CREATE TABLE #TEMP1 (

date_time_column DATETIME,

big_int_column BIGINT,

string_column NVARCHAR(100)

);

-- Добавление данных с правильным форматом даты

INSERT INTO #TEMP (date_time_column, big_int_column, string_column) VALUES

('20240115 10:30:00', 123456789, 'Первая запись'),

('20240116 14:45:30', 987654321, 'Вторая запись');

-- Вывод результата

SELECT * FROM #TEMP;

  1. Подсчитать количество факультетов. Если их в таблице от 2 до 4, то ничего не сообщать, в противном случае вывести сообщение вида "В таблице ... факультетов" (вместо многоточия поставить точное количество факультетов).

/* Кашина 2.10.25

Подсчитать количество факультетов. Если их в таблице от 2 до 4, то ничего не

сообщать, в противном случае вывести сообщение вида "В таблице ... факультетов" (вместо

многоточия поставить точное количество факультетов).*/

USE University_Кашина_Диана

DECLARE @faculty_count INT;

SELECT @faculty_count = COUNT(*) FROM Facultet;

IF @faculty_count < 2 OR @faculty_count > 4

BEGIN

PRINT 'В таблице ' + CONVERT(VARCHAR, @faculty_count) + ' факультетов';

END;

  1. Подсчитать средний год рождения студентов. Если полученный год в диапазоне от 1980 до 1999, то ничего не сообщать, в противном случае вывести сообщение вида "Средний год рождения = ." (вместо многоточия поставить точный средний год).

/*Кашина 2.10.25

Подсчитать средний год рождения студентов. Если полученный год в диапазоне

от 1980 до 1999, то ничего не сообщать, в противном случае вывести сообщение вида "Средний

год рождения = ." (вместо многоточия поставить точный средний год).*/

USE University_Кашина_Диана

DECLARE @avg_birth_year INT;

SELECT @avg_birth_year = AVG(YEAR(Birthday))

FROM Student1;

IF @avg_birth_year < 1980 OR @avg_birth_year > 1999

BEGIN

PRINT 'Средний год рождения = ' + CONVERT(VARCHAR, @avg_birth_year);

END;

  1. Определить количество записей в таблице кафедра. Пока записей меньше 10, делать в цикле добавление записи в временную таблицу с автоматическим наращиванием значения ключевого поля, а вместо названия кафедры ставить значение 'Имя не известно'.

/*Кашина 2.10.25

Определить количество записей в таблице кафедра. Пока записей меньше 10,

делать в цикле добавление записи в временную таблицу с автоматическим наращиванием

значения ключевого поля, а вместо названия кафедры ставить значение 'Имя не известно'.*/

USE University_Кашина_Диана

-- Создаем временную таблицу

CREATE TABLE #temp_kafedra (

id INT IDENTITY(1,1) PRIMARY KEY,

name NVARCHAR(100) NOT NULL

);

-- Определяем начальное количество записей

DECLARE @record_count INT;

SELECT @record_count = COUNT(*) FROM Kafedra;

-- Цикл добавления записей

WHILE @record_count < 10

BEGIN

INSERT INTO #temp_kafedra (name) VALUES ('Имя не известно');

SET @record_count = @record_count + 1;

END;

-- Выводим результат

SELECT * FROM #temp_kafedra;

SELECT 'Итоговое количество записей: ' + CONVERT(VARCHAR, @record_count) AS результат;

  1. Создать пользовательскую функцию, которая будет возвращать результат в виде таблицы, а именно выводить всех учащихся студентов по кафедрам с указанием курса. При этом функция имеет один параметр @city, с помощью которого введем ограничение на вычисление, а именно город проживания должен быть Ростов-на-Дону.

/*Кашина 9.10.25

Создать пользовательскую функцию, которая будет возвращать результат в виде

таблицы, а именно выводить всех учащихся студентов по кафедрам с указанием курса. При этом

функция имеет один параметр @city, с помощью которого введем ограничение на вычисление,

а именно город проживания должен быть Ростов-на-Дону. */

CREATE FUNCTION dbo.GetStudentsByDepartment(@city VARCHAR(50))

RETURNS TABLE

AS

RETURN (

SELECT

s.Student_ID,

s.Sutname + ' ' + s.Sutfname AS 'Полное имя',

s.kod_kafedru AS 'Код кафедры',

s.Kurs AS 'Курс',

s.City,

s.Groupname

FROM Student1 s

WHERE s.City = @city

);

GO

-- Вызов функции для получения студентов из Ростова-на-Дону

SELECT * FROM dbo.GetStudentsByDepartment('Ростов-на-Дону');

  1. Создать процедуру Count_Assistent_Salary_Title c входными параметрами @Sum_salary целого типа, @Title строка с длиной 15 символов, которая определяет кол-во преподавателей, должность которых совпадает с параметром @Title и зарплата у которых не менее заданного параметра @Sum_salary.

/*кашина 10.10

Создать процедуру Count_Assistent_Salary_Title c входными параметрами

@Sum_salary целого типа, @Title строка с длиной 15 символов, которая определяет кол-во

преподавателей, должность которых совпадает с параметром @Title и зарплата у которых не

менее заданного параметра @Sum_salary.*/

CREATE PROCEDURE Count_Assistent_Salary_Title

@Sum_salary INT,

@Title VARCHAR(15)

AS

BEGIN

SELECT COUNT(*) AS TeacherCount

FROM Teacher

WHERE dolgnost = @Title

AND salary >= @Sum_salary;

END;

  1. Создать процедуру update_proc_rise с входным параметром и значением по умолчанию @p real = 0.5 для увеличения значения надбавки к зарплате в таблице Teacher в заданное количество раз. Процедура не возвращает никаких данных.

/*Создать процедуру update_proc_rise с входным параметром и значением по

умолчанию @p real = 0.5 для увеличения значения надбавки к зарплате в таблице Teacher в

заданное количество раз. Процедура не возвращает никаких данных.*/

-- Первый пакет: удаление процедуры если существует

USE University_Кашина_Диана

IF OBJECT_ID('update_proc_rise', 'P') IS NOT NULL

DROP PROCEDURE update_proc_rise;

GO -- Разделитель пакетов

-- Второй пакет: создание процедуры

CREATE PROCEDURE update_proc_rise

@p REAL = 0.5

AS

BEGIN

UPDATE Teacher

SET salary = salary * @p;

PRINT 'Надбавка к зарплате увеличена в ' + CAST(@p AS VARCHAR(10)) + ' раз(а)';

PRINT 'Обновлено записей: ' + CAST(@@ROWCOUNT AS VARCHAR(10));

END;

GO

/*Кашина 10.10.25

Вызов процедуры*/

USE University_Кашина_Диана

EXEC update_proc_rise 1.5

Задания по собственному варианту

  1. один запрос для создания временной таблицы через переменную типа TABLE;

/*Кашина 10.10.25

1 запрос по собственному варианту*/

-- Временная таблица для статистики заказов по клиентам

DECLARE @ClientOrderStats TABLE (

ClientName VARCHAR(MAX),

OrderCount INT,

TotalSpent MONEY

);

-- Заполняем данными о заказах клиентов

INSERT INTO @ClientOrderStats

SELECT

c.Name,

COUNT(o.ID_Order),

SUM(o.Total_Cost)

FROM Client c

INNER JOIN [Order] o ON c.ID_Client = o.ID_Client

GROUP BY c.Name;

-- Выводим результаты

SELECT * FROM @ClientOrderStats

ORDER BY TotalSpent DESC;

  1. один запрос с использованием условной конструкции IF;

/*Кашина 10.10.25

– один запрос с использованием условной конструкции IF; */

DECLARE @active_couriers int

DECLARE @status_message varchar(50)

-- Считаем курьеров с активными статусами (в пути)

SET @active_couriers = (SELECT COUNT(*) FROM Courier WHERE Employment_status = 'в пути')

IF @active_couriers > 0 BEGIN

SET @status_message = 'Активных курьеров: ' + CAST(@active_couriers AS varchar)

SELECT @status_message AS 'Статус'

-- Показываем активных курьеров

SELECT

Name AS 'Имя курьера',

Number AS 'Телефон',

Delivery_Area AS 'Район доставки'

FROM Courier

WHERE Employment_status = 'в пути'

END ELSE BEGIN

SET @status_message = 'Нет активных курьеров в пути'

SELECT @status_message AS 'Статус'

-- Показываем всех курьеров с их статусами

SELECT

Name AS 'Имя курьера',

Number AS 'Телефон',

Delivery_Area AS 'Район',

Employment_status AS 'Статус'

FROM Courier

WHERE Employment_status IS NOT NULL

END

  1. один запрос с использованием цикла WHILE;

/*Кашина 10.10.25

– один запрос с использованием цикла WHILE */

DECLARE @discount_count INT = 1

DECLARE @total_discounts INT

-- Считаем заказы со скидкой

SET @total_discounts = (SELECT COUNT(*) FROM [Order] WHERE Discount > 0)

PRINT 'Заказы со скидкой:'

WHILE @discount_count <= @total_discounts

BEGIN

PRINT 'Заказ №' + CAST(@discount_count AS VARCHAR) + ' имеет скидку'

-- Выходим если дошли до 5 заказов

IF @discount_count = 5

BREAK

SET @discount_count = @discount_count + 1

END

PRINT 'Проверено заказов: ' + CAST(@discount_count AS VARCHAR)

  1. один запрос для создания скалярной функции

/*Кашина 10.10.25

4. один запрос для создания скалярной функции*/

-- Функция для форматирования адреса клиента

CREATE FUNCTION FormatClientAddress(

@city VARCHAR(MAX),

@street VARCHAR(MAX),

@house INT

)

RETURNS VARCHAR(MAX)

AS

BEGIN

DECLARE @full_address VARCHAR(MAX)

SET @full_address = 'г. ' + @city + ', ул. ' + @street + ', д. ' + CAST(@house AS VARCHAR)

RETURN @full_address

END

/*Кашина 10.10.25

вызов скалярной функции*/

SELECT

Name,

dbo.FormatClientAddress(City, Street, House) AS 'Полный адрес'

FROM Client;

  1. один запрос для создания функции, которая возвращает табличное значение;

/*Кашина 10.10.25

– один запрос для создания функции, которая возвращает табличное значение*/

-- Функция возвращает всех клиентов из указанного города

CREATE FUNCTION GetClientsByCity(@city_name VARCHAR(MAX))

RETURNS TABLE

AS

RETURN

(

SELECT

ID_Client,

Name AS 'Имя_Клиента',

Street,

House,

Apartment,

Number AS 'Номер телефона'

FROM Client

WHERE City = @city_name);

/*Кашина 10.10.25*/

-- Получить всех клиентов из Москвы

SELECT * FROM dbo.GetClientsByCity('Москва');

-- Получить клиентов из Владимира с сортировкой по имени

SELECT

ClientName,

Street,

House,

PhoneNumber

FROM dbo.GetClientsByCity('Владимир')

ORDER BY ClientName;

  1. один запрос для создания процедуры без параметров

/*Кашина 10.10.25

один запрос для создания процедуры без параметров*/

-- Процедура показывает топ-5 самых популярных пицц

CREATE PROCEDURE GetTopPizzas

AS

BEGIN

SELECT TOP 5

p.Name AS 'Название',

SUM(po.Quantity) AS 'Общее_Количество',

SUM(po.Quantity * ps.Price) AS 'Выручка'

FROM Pizza p

INNER JOIN Pizza_Order po ON p.ID_Pizza = po.ID_Pizza

INNER JOIN Pizza_Size ps ON p.ID_Pizza_Size = ps.ID_Pizza_Size

GROUP BY p.Name

ORDER BY Общее_Количество DESC;

END;

/*Кашина 10.10.25

вызов процедуры*/

EXEC GetTopPizzas;

  1. один запрос для создания процедуры c входным параметром

/*Кашина 10.10.25

один запрос для создания процедуры c входным параметром*/

-- Процедура показывает заказы клиента по его ID

CREATE PROCEDURE GetClientOrders

@client_id INT -- входной параметр

AS

BEGIN

SELECT

o.ID_Order AS 'Номер заказа',

o.Order_Time AS 'Время заказа',

o.Order_Status AS 'Статус',

o.Total_Cost AS 'Стоимость',

o.Discount AS 'Скидка %',

(o.Total_Cost * (100 - ISNULL(o.Discount, 0)) / 100) AS 'Итоговая сумма'

FROM [Order] o

WHERE o.ID_Client = @client_id

ORDER BY o.Order_Time DESC;

END;

/*Кашина 10.10.25

вызов функции*/

-- Получить заказы клиента с ID = 17

EXEC GetClientOrders @client_id = 17;

-- Получить заказы клиента с ID = 19

EXEC GetClientOrders 19;

  1. один запрос для создания процедуры c входными параметрами и RETURN

/*кашина 10.10.25

один запрос для создания процедуры c входными параметрами и RETURN*/

-- Процедура возвращает общее количество заказов клиента

CREATE PROCEDURE GetClientOrderCount

@client_id INT -- входной параметр

AS

BEGIN

DECLARE @order_count INT;

-- Считаем количество заказов клиента

SELECT @order_count = COUNT(*)

FROM [Order]

WHERE ID_Client = @client_id;

-- Возвращаем результат через RETURN

RETURN @order_count;

END;

/*кашина 10.10.25

один запрос для создания процедуры c входными параметрами и RETURN

вызов функции*/

-- Объявляем переменную для получения результата

DECLARE @result INT;

-- Вызываем процедуру и получаем результат через RETURN

EXEC @result = GetClientOrderCount @client_id = 17;

-- Выводим результат

PRINT 'Количество заказов клиента: ' + CAST(@result AS VARCHAR);

  1. один запрос для создания процедуры обновления данных в таблице базы данных UPDATE;

/*Кашина 10.10.25

один запрос для создания процедуры обновления данных в таблице базы данных UPDATE*/

-- Процедура для обновления статуса заказа

CREATE PROCEDURE UpdateOrderStatus

@order_id INT,

@new_status VARCHAR(MAX)

AS

BEGIN

-- Обновляем статус заказа

UPDATE [Order]

SET Order_Status = @new_status

WHERE ID_Order = @order_id;

-- Проверяем сколько строк было обновлено

IF @@ROWCOUNT > 0

PRINT 'Статус заказа №' + CAST(@order_id AS VARCHAR) + ' успешно обновлен на: ' + @new_status;

ELSE

PRINT 'Заказ с ID ' + CAST(@order_id AS VARCHAR) + ' не найден!';

END;

/*Кашина 10.10.25

выполнение процедуры*/

-- Обновить статус заказа на "доставлен"

EXEC UpdateOrderStatus

@order_id = 11,

@new_status = 'доставлен';

  1. один запрос для создания процедуры извлечения данных из таблиц базы данных SELECT.

/*Кашина 10.10.25

один запрос для создания процедуры извлечения данных из таблиц базы данных SELECT*/

-- Процедура для извлечения статистики продаж пицц

CREATE PROCEDURE GetPizzaSalesStats

AS

BEGIN

SELECT

p.Name AS 'Пицца',

pz.Name AS 'Пиццерия',

SUM(po.Quantity) AS 'Количество продаж',

SUM(po.Quantity * ps.Price) AS 'Общая выручка',

AVG(ps.Price) AS 'Средняя цена'

FROM Pizza p

INNER JOIN Pizza_Order po ON p.ID_Pizza = po.ID_Pizza

INNER JOIN Pizza_Size ps ON p.ID_Pizza_Size = ps.ID_Pizza_Size

INNER JOIN Pizzeria pz ON p.ID_Pizzeria = pz.ID_Pizzeria

INNER JOIN [Order] o ON po.ID_Order = o.ID_Order

WHERE o.Order_Status = 'доставлен'

GROUP BY p.Name, pz.Name

ORDER BY SUM(po.Quantity) DESC;

END;

/*Кашина 10.10.25

один запрос для создания процедуры извлечения данных из таблиц базы данных SELECT

выполнение процедуры*/

EXEC GetPizzaSalesStats;

Вывод: в ходе лабораторной работы были изучены используемые в реляционной СУБД встроенный язык программирования TransactSQL для написание программ в MS SQL Server. Изучены правила построения идентификаторов, правила объявления переменных и их типов. Изучены принципы работы с циклами и ветвлениями. Изучена работа с переменными типа Table. Изучен синтаксист и семантика функций и хранимых процедур.