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

лаба 7 / laba6_7

.sql
Скачиваний:
19
Добавлен:
17.06.2021
Размер:
15 Кб
Скачать
/*Создайте хранимую процедуру pr_КолебанияСпросаТоваров,
которая решает рассмотренную выше (см. раздел I) задачу
определения наименования товара, по которому был
наибольший или наименьший спрос за последние N дней.
Эта процедура должна иметь два входных параметра
(@Интервал, @ТипРезультата) и два выходных параметра
(@Имя, @Итог). Если значение входного параметра @ТипРезультата
равно 1, находится товар наибольшего спроса.
Если же значение параметра равно 2 – находится товар
наименьшего спроса.*/


use СкладЛаба5
go

create procedure pr_КолебанияСпросаТоваров
@Интервал INT,
@ТипРезультата int,
@Имя varchar(50) output,
@Итог numeric (12,3) output
as
declare @Code INT /*создание переменной*/
if @ТипРезультата = 1
select @Code=КодТовара, @Итог=sum(Количество) /*присвоение значений нескольким переменным*/
from Заказ
where ДатаЗаказа between getdate()-@Интервал and getdate()
group by КодТовара
order by sum(Количество)
else
select @Code=КодТовара, @Итог=sum(Количество)
from Заказ
where ДатаЗаказа between getdate()-@Интервал and getdate()
group by КодТовара
order by sum(Количество) desc
SELECT @Имя = Наименование
FROM Товар
WHERE КодТовара = @Code
go

declare @Имя varchar(50), @Итог numeric (12,3)
exec pr_КолебанияСпросаТоваров 60, 1, @Имя output, @Итог output /*запуск хранимых процедур*/ -- output это выходные параметры
select @Имя as [Название], @Итог as [Итог]
go

declare @Name varchar(50), @Result numeric (12,3)
exec pr_КолебанияСпросаТоваров 60, 2, @Name output, @Result output
select @Name as [Название], @Result as [Итог]
go



/*Создайте хранимую процедуру pr_КлиентПоставщик_СтранаИнтервал, которая подсчитывает,
сколько различных клиентов и различных поставщиков из указанной страны фигурирует
в таблице Заказ, причем анализируются только те заказы, в которых значение поля
Дата заказа попадает в указанный интервал дат. Эта процедура должна иметь
три входных параметра (@Страна, @НачалоИнтервала, @КонецИнтервала)
и два выходных параметра (@ЧислоКлиентов, @ЧислоПоставщиков).
Если же значение параметра @Страна не будет указано (т.е. будет равно NULL),
то подсчет клиентов и поставщиков должен вестись независимо от их национальной принадлежности.*/

DROP PROCEDURE pr_КлиентПоставщик_СтранаИнтервал /*удаление хранимой процедуры*/
GO


create procedure pr_КлиентПоставщик_СтранаИнтервал
@Страна VARCHAR(20) null ,
@НачалоИнтервала DATE,
@КонецИнтервала DATE,
@ЧислоКлиентов int output,
@ЧислоПоставщиков int output
as
if @Страна is not null
begin
select @ЧислоКлиентов = count(DISTINCT(Заказ.КодКлиента)) /*используется для возврата только отдельных (разных) значений*/
from Заказ inner join Клиент
on Заказ.КодКлиента=Клиент.КодКлиента
inner join Регион on Клиент.КодРегиона=Регион.КодРегиона
where ДатаЗаказа between @НачалоИнтервала and @КонецИнтервала and Страна=@Страна
select @ЧислоПоставщиков = count(DISTINCT(Заказ.КодПоставщика))
from Заказ inner join Поставщик
on Заказ.КодПоставщика=Поставщик.КодПоставщика
inner join Регион on Поставщик.КодРегиона=Регион.КодРегиона
where ДатаЗаказа between @НачалоИнтервала and @КонецИнтервала and Страна=@Страна
end
else
select @ЧислоКлиентов = count(DISTINCT(Заказ.КодКлиента)), @ЧислоПоставщиков = count(DISTINCT(Заказ.КодПоставщика)) --DISTINCT используется для указания на то, что следует работать только с уникальными значениями столбца
from Заказ
where ДатаЗаказа between @НачалоИнтервала and @КонецИнтервала
go

declare @Client int, @Service int
declare @Start DATE, @End DATE
select @Start = '2017-01-01'
select @End='2021-04-04'
exec pr_КлиентПоставщик_СтранаИнтервал 'Беларусь', @Start, @End, @Client output, @Service output
select @Client as [Количество клиентов], @Service as [Количество поставщиков]
go


declare @Client int, @Service int
declare @Start datetime, @End datetime
select @Start='2017-01-01'
select @End='2021-04-03'
exec pr_КлиентПоставщик_СтранаИнтервал null, @Start, @End, @Client output, @Service output
select @Client as [Количество клиентов], @Service as [Количество поставщиков]
go



/*Создайте хранимую процедуру pr_Товар_СтранаВалютаИнтервал, которая подсчитывает,
сколько различных товаров в конкретной валюте было заказано клиентами из указанной страны,
причем анализируются только те заказы, в которых значение поля Дата заказа попадает
в заданный интервал дат. Эта процедура должна иметь четыре входных параметра
(@Страна, @Валюта, @НачалоИнтервала, @КонецИнтервала)
и один выходной параметр (@ЧислоТоваров).
При этом расширьте возможности процедуры следующим образом:
- если значение параметра @Страна не будет указано (т.е. будет равно NULL),
то подсчет товаров должен вестись независимо от национальной принадлежности клиента;
- если значение параметра @Валюта не будет указано (т.е. будет равно NULL),
то подсчет товаров должен вестись применительно к национальной валюте (код валюты – BYR).
*/

alter procedure pr_Товар_СтdранаВалютаИнтервал
@Страна VARCHAR(20) null,
@Валюта CHAR(3) null,
@НачалоИнтервала datetime,
@КонецИнтервала datetime,
@ЧислоТоваров int output
as
if @Валюта is null set @Валюта='BYR'
if @Страна is not null
select distinct @ЧислоТоваров = count(Заказ.КодТовара)
from Заказ
join Товар on Заказ.КодТовара=Товар.КодТовара
join Клиент on Заказ.КодКлиента=Клиент.КодКлиента
join Регион on Клиент.КодРегиона=Регион.КодРегиона
where КодВалюты=@Валюта and ДатаЗаказа between @НачалоИнтервала and @КонецИнтервала
and Страна=@Страна
else
select distinct @ЧислоТоваров = count(Заказ.КодТовара)
from Заказ
join Товар on Заказ.КодТовара=Товар.КодТовара
join Клиент on Заказ.КодКлиента=Клиент.КодКлиента
where КодВалюты=@Валюта and ДатаЗаказа between @НачалоИнтервала and @КонецИнтервала
go


declare @Country VARCHAR(20), @Currency char(3), @Start datetime, @End datetime, @Res int
select @Start='2017-01-01', @End='2021-05-05', @Country = 'Россия', @Currency = 'USD'
exec pr_Товар_СтdранаВалютаИнтервал @Country, @Currency, @Start, @End, @Res output
select @Res as [Количество товаров]
go

declare @Start smalldatetime, @End smalldatetime, @Res int
select @Start='2017-01-01', @End='2021-13-09'
exec pr_Товар_СтdранаВалютаИнтервал null, null, @Start, @End, @Res output
select @Res as [Количество товаров]
go




/*Создайте пользовательскую функцию fn_getЧислоДней_вМесяце типа Scalar,
которая для конкретной даты возвращает число дней в месяце, который определяется этой датой
(високосность года не учитывается). Эта функция должна иметь один входной параметр (@Дата).*/


create function fn_getЧислоДней_вМесяце
(@Дата date)
returns int
begin
declare @Res int
set @Res=day(EOMONTH(@Дата))
return @Res
end
go

declare @Date date

set @Date ='2016-02-12'
select @Date AS [ВЫБРАННАЯ ДАТА] , dbo.fn_getЧислоДней_вМесяце(@Date) as [Количество дней]
go

/*Создайте пользовательскую функцию fn_getФИО_вФормате типа Scalar, которая на основе текстовой строки,
содержащей фамилию, имя и отчество, формирует текстовую строку в одном из следующих форматов:
1) исходная строка переводится в верхний регистр;
2) исходная строка переводится в нижний регистр;
3) на верхнем регистре должны быть только первые буквы слов;
4) выводится только фамилия, а имя и отчество заменяются их первыми буквами с точкой.
Эта функция должна иметь два входных параметра (@ФИО, @Формат).
Усложненный вариант. Расширьте возможности функции таким образом,
чтобы была допустима исходная строка (задаваемая параметром @ФИО), содержащая не один,
а несколько пробелов между фамилией и именем или между именем и отчеством,
а также допускающая наличие лидирующих пробелов перед фамилией.
*/

create function fn_getФИО_вФормате
(@ФИО varchar(50), @Формат int)
returns varchar(50)
begin
declare @Temp char, @Ind int, @Name varchar(50)
set @ФИО=ltrim(@ФИО) /*обрезает пробелы, которые стоят в начале строки*/
set @ФИО=rtrim(@ФИО) /*обрезает пробелы, которые стоят в конце строки*/
if @Формат=1
set @ФИО=upper(@ФИО) /* в верхний регистр*/
else if @Формат=2
set @ФИО=lower(@ФИО)
else if @Формат=3
begin
set @ФИО = lower(@ФИО)
set @Temp = left(@ФИО,1)
set @ФИО = stuff(@ФИО, 1, 1, upper(@Temp))
set @Ind = charindex(' ', @ФИО)
set @Temp = substring(@ФИО, @Ind+1, 1)
set @ФИО = stuff(@ФИО, @Ind+1, 1, upper(@Temp))
set @Ind = charindex(' ', @ФИО, @Ind+1)
set @Temp = substring(@ФИО, @Ind+1, 1) -- вырезает и возвращает заданное количество символов из строки
set @ФИО = stuff(@ФИО, @Ind+1, 1, upper(@Temp))
end
else if @Формат=4
begin
set @ФИО = lower(@ФИО)
set @Temp = left(@ФИО,1)
set @ФИО = stuff(@ФИО, 1, 1, upper(@Temp))
set @Ind = charindex(' ', @ФИО)
set @Temp = substring(@ФИО, @Ind+1, 1)
set @ФИО = stuff(@ФИО, @Ind+1, 1, upper(@Temp))
set @Name = substring (@ФИО, 1, @Ind+1) + '. '
set @Ind = charindex(' ', @ФИО, @Ind+1)
set @Temp = upper(substring(@ФИО, @Ind+1, 1))
set @Name = @Name + @Temp + '.'
set @ФИО = @Name
end
return @ФИО
end
go


declare @str nvarchar(50)
set @str=' Рушева маргарИТА владисла '
set @
select dbo.fn_getФИО_вФормате(@str, 4)


--Создайте пользовательскую функцию fn_getG roup_НаименованиеВалюта типа Inline Table-valued, которая
--возвращает таблицу со следующими столбцами: Наименование товара, Имя валюты, Заказанное кол-во, Стоимость
--в валюте, Стоимость в нац.валюте. Эта таблица должна отражать результат группировки данных по полям
--Наименование и ИмяВалюты. Для каждой такой группы подсчитывается итоговое количество заказанного
--товара и итоговая стоимость в валюте и в национальной валюте.
--Пользовательская функция fn_getGroup_НаименованиеВалюта должна иметь два входных параметра
--(@НачалоИнтервала, @КонецИнтервала), поэтому при формировании результирующей таблицы необходимо
--учитывать только те строки из таблицы Заказ, в которых значение поля Дата заказа попадает в
--указанный параметрами интервал дат.


create function fn_getGroup_НаименованиеВалюта
(@НачалоИнтервала date, @КонецИнтервала date)
returns table
as return
SELECT Товар.Наименование AS [Наименование товара], Валюта.ИмяВалюты AS [Имя валюты], COUNT(Заказ.КодЗаказа) AS [Заказанное количество], SUM(Цена) AS [Стоимость в валюте], SUM(Цена*Валюта.КурсВалюты) AS [Стоимость в нац. валюте]
FROM Заказ
INNER JOIN Товар ON Заказ.КодТовара = Товар.КодТовара
INNER JOIN Валюта ON Товар.КодВалюты = Валюта.КодВалюты
WHERE (ДатаЗаказа BETWEEN @НачалоИнтервала AND @КонецИнтервала)
GROUP BY Товар.Наименование, Валюта.ИмяВалюты
GO

SELECT * FROM fn_getGroup_НаименованиеВалюта('2012-01-01', '2026-12-31')
GO



/*Создайте пользовательскую функцию fn_getTable_СтоимостьНВ типа Multi-statement Table-valued, которая возвращает таблицу со следующими столбцами:
Номер Дата заказа Имя клиента Наименование товара Количество Цена в НВ Стоимость в НВ

Эта таблица строится в три этапа. Сначала создается таблица со столбцами, показанными выше, где столбец
Номер является автоинкрементным первичным ключом, столбцы Цена в НВ (цена в национальной валюте) и Стоимость в НВ
(стоимость в национальной валюте) являются вычисляемыми. Число строк этой таблицы будет равно числу строк в таблице Заказ.
На втором этапе подсчитывается средняя стоимость в национальной валюте всех заказанных товаров.
На третьем этапе из полученной таблицы удаляются все те строки, в которых значение столбца Стоимость в НВ будет меньше,
чем подсчитанная на втором этапе средняя стоимость в национальной валюте. В результате будет получена таблица,
которую и должна возвращать данная пользовательская функция. Эта функция не имеет ни одного входного параметра. */


create function fn_getTable_СтоимостьНВ
()
returns @СтоимостьНВ table(
Номер INT IDENTITY(1,1) PRIMARY KEY,
ДатаЗаказа DATETIME DEFAULT getdate() NULL,
ИмяКлиента VARCHAR(40) NOT NULL,
НаименованиеТовара VARCHAR(50) NOT NULL,
Количество NUMERIC(12, 3) NULL CHECK (Количество > 0),
ЦенаНВ MONEY NULL CHECK (ЦенаНВ > 0),
СтоимостьНВ MONEY NULL CHECK (СтоимостьНВ > 0)
)
begin
declare @temp table(
Номер INT IDENTITY(1,1) PRIMARY KEY,
ДатаЗаказа DATETIME DEFAULT getdate() NULL,
ИмяКлиента VARCHAR(40) NOT NULL,
НаименованиеТовара VARCHAR(50) NOT NULL,
Количество NUMERIC(12, 3) NULL CHECK (Количество > 0),
ЦенаНВ MONEY NULL CHECK (ЦенаНВ > 0),
СтоимостьНВ MONEY NULL CHECK (СтоимостьНВ > 0)
)
insert @temp (ДатаЗаказа, ИмяКлиента, НаименованиеТовара, Количество, ЦенаНВ, СтоимостьНВ)
select ДатаЗаказа, ИмяКлиента, Наименование, Количество, Цена*КурсВалюты, Цена*КурсВалюты*Количество
from Заказ
inner join Клиент on Заказ.КодКлиента=Клиент.КодКлиента
inner join Товар on Заказ.КодТовара=Товар.КодТовара
inner join Валюта on Товар.КодВалюты=Валюта.КодВалюты

declare @avg money
select @avg=avg(СтоимостьНВ)
from @temp

delete from @temp
where СтоимостьНВ<@avg

insert @СтоимостьНВ
select ДатаЗаказа, ИмяКлиента, НаименованиеТовара, Количество, ЦенаНВ, СтоимостьНВ
from @temp

return
end
go

select *
from fn_getTable_СтоимостьНВ()




/*Процедура называется блоком PL / SQL, который выполняет одну или несколько задач.
где функция называется блоком PL / SQL, который выполняет определенное действие.
Процедура может возвращать или не возвращать значение,
когда функция as должна возвращать одно значение*/

\



/*создаем процедуру в которой делаем (селект )запрос на выборку выводим
(код зак ,код товара, дата заказа, наимнование товара, цена товара)
для записей у которых дата заказа больше 1ого параметра цена товара процедуры , цена товара в промежутке межлу 2 и 3 параметрмо процедуры
либо наименование начинается с 4 параметра*/


/*создаем процедуру в которой делаем (селект )запрос на выборку выводим КОД ЗАКАЗА, ДАТА ЗАКАЗА, колво заказа, имя клиента
для записей у которых дата заказа больше 1ого параметра цена товара процедуры , колво в промежутке межлу 2 и 3 параметрмо процедуры
и имя клиента начинается с 4 параметра*/

create PROCEDURE pr_йфыадание
@Парам1 DATETIME,
@Парам2 INT,
@Парам3 INT,
@Парам4 char(20)
AS
SELECT КодЗаказа, ДатаЗаказа, Количество, Товар.Наименование, Товар.Цена
FROM Заказ
INNER JOIN Товар
ON Заказ.КодЗаказа = Товар.КодТовара
WHERE (ДатаЗаказа > @Парам1) OR (Цена BETWEEN @Парам2 AND @Парам3) OR (Товар.Наименование like @Парам4 + '%')
GO

SET DATEFORMAT dmy
DECLARE @Парам1 DATETIME
SET @Парам1 = GETDATE()
EXEC pr_йфыадание @Парам1, 100 , 2000, 'и'
GO

DROP PROCEDURE pr_йфыадание
GO
Соседние файлы в папке лаба 7