Добавил:
rushevamar@mail.ru Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
9
Добавлен:
17.06.2021
Размер:
14.33 Кб
Скачать
USE СкладЛаба5
GO

/*1.Создайте для таблицы Заказ триггер tr_Set_СрокПоставки, с помощью которого в этой таблице будет автоматически устанавливаться значение поля СрокПоставки при вставке новой записи и при обновлении поля ДатаЗаказа следующим образом:
- если цена товара определена в белорусских рублях, то срок поставки равен дате заказа плюс 3 дня;
- если цена товара определена в российских рублях или украинских гривнах, то срок поставки равен дате заказа плюс 7 дней;
- если цена товара определена в долларах США или евро, то срок поставки равен дате заказа плюс 10 дней;
- если цена товара определена в валюте, отличной от указанных выше валют, то срок поставки равен дате заказа плюс 14 дней.*/


CREATE TRIGGER tr_Set_СрокПпоставки
ON Заказ
FOR INSERT, UPDATE
AS
IF UPDATE(ДатаЗаказа)
DECLARE @OrderCode INT;
DECLARE @CurrencyCode VARCHAR(3);
SELECT @CurrencyCode = Т.КодВалюты
FROM inserted И
INNER JOIN Товар Т ON И.КодТовара = Т.КодТовара;
SELECT @OrderCode = КодЗаказа
FROM inserted;
DECLARE @Days INT;
IF @CurrencyCode = 'BYR'
SET @Days = 3;
ELSE IF @CurrencyCode = 'RUR' OR @CurrencyCode = 'GRV'
SET @Days = 7;
ELSE IF @CurrencyCode = 'USD' OR @CurrencyCode = 'EUR'
SET @Days = 10;
ELSE
SET @Days = 14;
UPDATE Заказ
SET СрокПоставки = ДатаЗаказа + @Days
WHERE КодЗаказа = @OrderCode;
GO

SELECT* FROM Заказ
UPDATE Заказ
SET ДатаЗаказа = '2020.02.01'
WHERE КодЗаказа = 5;

SELECT* FROM Заказ



/*2. Добавьте в базу данных новую таблицу Отпуск, которая снабжена связью типа «один к одному» с таблицей Товар:*/

--CREATE TABLE Отпуск (
-- КодТовара INT PRIMARY KEY,
-- Наименование VARCHAR(50) NOT NULL,
-- ВсегоЗаказано NUMERIC(12, 3) NULL,
-- CONSTRAINT FK_Отпуск_Товар FOREIGN KEY (КодТовара)
-- REFERENCES Товар ON UPDATE CASCADE
--);
--GO

/*Создайте для таблицы Заказ триггер tr_Кол _ЗаказанногоТовара, с помощью которого в таблице Отпуск будет автоматически обновляться информация о суммарном количестве заказанного товара.
Триггер должен срабатывать при операциях вставки и удаления строк в таблице Заказ, а также при обновлении в ней поля Количество. Если в таблице Отпуск еще нет строки,
подлежащей корректировке (а так вначале и будет), то должна быть выполнена операция вставки новой строки,
в которой в поле ВсегоЗаказано записывается суммарное количество заказанного товара, подсчитанное на основе всех строк таблицы Заказ, связанных с данным товаром.*/

ALTER TRIGGER tr_Кол_ЗаказанногоТовараа
ON Заказ
FOR INSERT, UPDATE, DELETE
AS
IF UPDATE(Количество)
DECLARE @Rows INT;
DECLARE @ProductCode INT;
DECLARE @ProductName VARCHAR(50);
DECLARE @Count INT;
SELECT @ProductCode = И.КодТовара, @ProductName = Т.Наименование
FROM inserted И
INNER JOIN Товар Т ON И.КодТовара = Т.КодТовара;

SELECT @Count = SUM(Количество)
FROM Заказ
WHERE КодТовара = @ProductCode;

SELECT @Rows = COUNT(*)
FROM Отпуск О
INNER JOIN Товар Т
ON О.КодТовара = Т.КодТовара
INNER JOIN inserted И
ON И.КодТовара = Т.КодТовара
WHERE И.КодТовара = О.КодТовара;
IF @Rows = 0
INSERT INTO Отпуск VALUES (@ProductCode, @ProductName, @Count);
ELSE
UPDATE Отпуск SET ВсегоЗаказано = @Count
WHERE КодТовара = @ProductCode;
GO

SELECT SUM(Количество) FROM Заказ
WHERE КодТовара = 110;
SELECT * FROM Отпуск
SELECT * FROM Товар
SELECT* FROM Поставщик
INSERT INTO Заказ (КодКлиента, КодТовара, Количество, КодПоставщика) VALUES (3, 110, 20, 123);
INSERT INTO Заказ (КодКлиента, КодТовара, Количество, КодПоставщика) VALUES (1, 112, 15, 234);
GO

/*3. Создайте хранимую процедуру pr_Стоимость_ВалютаИнтервал для решения более общей задачи по сравнению с задачей, рассмотренной в разделе I, а именно:
необходимо подсчитать суммарную стоимость всех товаров, заказанных в течение указанного интервала времени, однако не в национальной валюте, а в валюте, указанной пользователем
(в частности, может быть указана и национальная валюта). Эта процедура должна иметь три входных параметра (@КодВалюты, @НачалоИнтервала, @КонецИнтервала) и один выходной параметр (@Стоимость).*/
Create PROCEDURE pr_Стоимость_ВалютаИнтерваffл
(@КодВалюты VARCHAR(3),
@НачалоИнтервала DATE,
@КонецИнтервала DATE,
@Стоимость MONEY OUTPUT)
AS
DECLARE @Rate SMALLMONEY;
SELECT @Rate = КурсВалюты
FROM Валюта
WHERE @КодВалюты = КодВалюты;
SET @Стоимость = 0;
DECLARE @OrderPrice MONEY;
DECLARE myCursor CURSOR LOCAL STATIC
FOR
SELECT з.Количество * т.Цена / в.КурсВалюты * @Rate
FROM Заказ з
JOIN Товар т
ON з.КодТовара = т.КодТовара
JOIN Валюта в
ON т.КодВалюты = в.КодВалюты
WHERE з.ДатаЗаказа BETWEEN @НачалоИнтервала AND @КонецИнтервала;
OPEN myCursor;
FETCH FIRST FROM myCursor INTO @OrderPrice;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @Стоимость = @Стоимость + @OrderPrice;
FETCH NEXT FROM myCursor INTO @OrderPrice;
END;
CLOSE myCursor;
DEALLOCATE myCursor;
GO
SELECT * FROM Заказ
DECLARE @Price MONEY;
EXEC pr_Стоимость_ВалютаИнтервал 'BYR', '2021.05.09', '2022.01.01', @Price OUTPUT;
SELECT @Price;

/*4. Добавьте в таблицу Регион две новые строки, используя следующие команды:*/
INSERT INTO Регион
VALUES (102, 'Россия', '', 'Москва', 'пр.Калинина, 50',
'339-62- 10', '456456456');

INSERT INTO Регион
VALUES (106, 'Литва', '', 'Вильнюс', 'ул.Чурлёниса, 19', NULL,
'55555555');
GO

/*Разработайте программный код (не обязательно в виде хранимой процедуры), который формирует таблицу следующего вида:

Страна Число клиентов Число поставщиков
. . . . . . . . .

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

DROP PROC clientsSuppliersByCountry
GO

CREATE PROCEDURE clientsSuppliersByCountryy
(@НачалоИнтервала DATE,
@КонецИнтервала DATE)
AS
DECLARE @Country VARCHAR(20);
DECLARE @ClientsNumber INT;
DECLARE @SuppliersNumber INT;
DECLARE @table TABLE (
Страна VARCHAR(20),
ЧислоКлиентов INT,
ЧислоПоставщиков INT);
DECLARE myCursor CURSOR LOCAL STATIC
FOR
SELECT DISTINCT Страна
FROM Регион;
OPEN myCursor;
FETCH FIRST FROM myCursor INTO @Country;
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC pr_КлиентПоставщик_СтранаИнтервал @Country, @НачалоИнтервала, @КонецИнтервала, @ClientsNumber OUTPUT, @SuppliersNumber OUTPUT;
INSERT INTO @table VALUES (@Country, @ClientsNumber, @SuppliersNumber);
FETCH NEXT FROM myCursor INTO @Country;
END;
SELECT * FROM @table;
CLOSE myCursor;
DEALLOCATE myCursor;
GO

EXEC clientsSuppliersByCountryy '2020.10.10', '2021.10.10';

/*5. Создайте таблицу Протокол со структурой, приведенной ниже, в которой должны автоматически фиксироваться все действия, вызванные вставкой, обновлением или удалением данных в таблице Товар. Каждая команда, изменяющая содержимое таблицы Товар, должна быть отражена отдельной строкой в таблице Протокол.

Номер ДатаВремя Пользователь Действие ЧислоСтрок
. . . . . . . . . . . . . . .

Здесь столбец Номер является автоинкрементным первичным ключом. В столбце Действие указывается одна из трех возможных операций с данными: «Вставка», «Обновление», «Удаление». Столбец ЧислоСтрок будет содержать данные о числе вставленных, либо обновленных, либо удаленных строк в таблице Товар.
Усложненный вариант. Таблица Протокол должна включать в себя еще один столбец КодыТоваров, в котором указываются коды товаров, фигурирующие во вставленных, обновленных или удаленных строках.*/

CREATE TABLE Пdgdроотокол (
Номер INT IDENTITY(1,1) PRIMARY KEY,
ДатаВремя DATETIME NOT NULL,
Пользователь VARCHAR(80) NOT NULL,
Действие VARCHAR(10) NOT NULL,
ЧислоСтрок INT NOT NULL
);
GO

CREATE TRIGGER tr_insertProвdddd
ON Товар
FOR INSERT
AS
DECLARE @RowsNumber INT;
SELECT @RowsNumber = COUNT(*)
FROM inserted;
INSERT INTO Протоколл VALUES (GETDATE(), SUSER_NAME(), 'Вставка', @RowsNumber);
GO

CREATE TRIGGER tr_updProjjdв
ON Товар
FOR UPDATE
AS
DECLARE @RowsNumber1 INT;
SELECT @RowsNumber1 = COUNT(*)
FROM inserted;
INSERT INTO Протоколл VALUES (GETDATE(), SUSER_NAME(), 'Обновление', @RowsNumber1);
GO

CREATE TRIGGER tr_deдjjlProdd
ON Товар
FOR DELETE
AS
DECLARE @RowsNumber2 INT;
SELECT @RowsNumber2 = COUNT(*)
FROM deleted;
INSERT INTO Протоколл VALUES (GETDATE(), SUSER_NAME(), 'Удаление', @RowsNumber2);
GO

SELECT* FROM Пdgdроотокол;
SELECT* FROM Товар
INSERT INTO Товар (КодТовара, Наименование, Цена, КодВалюты, Расфасован) VALUES (555, 'Шуруповерт', 150, 'BYR', 'Да');
DELETE FROM Товар WHERE КодТовара = 222;

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

GO
CREATE TRIGGER tr_Товарh_Ценa
ON Товар
FOR INSERT, UPDATE
AS
IF UPDATE(Цена)
BEGIN
DECLARE @КодТовара INT, @Цена MONEY, @ЦенаНВ MONEY
DECLARE myCursor CURSOR LOCAL STATIC
FOR
SELECT и.КодТовара, и.Цена, и.Цена * в.КурсВалюты
FROM inserted и
JOIN Валюта в
ON и.КодВалюты = в.КодВалюты;
OPEN myCursor;
FETCH FIRST FROM myCursor INTO @КодТовара, @Цена, @ЦенаНВ;
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE Заказ
SET Стоимость = Количество * @Цена, СтоимостьНВ = Количество * @ЦенаНВ
WHERE КодТовара = @КодТовара;
FETCH NEXT FROM myCursor INTO @КодТовара, @Цена, @ЦенаНВ;
END;
CLOSE myCursor;
DEALLOCATE myCursor;
END;
GO


SELECT * FROM Товар
UPDATE Товар
SET Цена = Цена + 10;
GO
SELECT * FROM Товар

CREATE TRIGGER tr_Товаар_Количествооо
ON Заказ
FOR INSERT, UPDATE
AS
IF UPDATE(Количество)
BEGIN
DECLARE @КодЗаказа INT, @Цена MONEY, @ЦенаНВ MONEY
DECLARE myCursor CURSOR LOCAL STATIC
FOR
SELECT и.КодЗаказа, т.Цена, т.Цена * в.КурсВалюты
FROM inserted и
JOIN Товар т
ON и.КодТовара = т.КодТовара
JOIN Валюта в
ON т.КодВалюты = в.КодВалюты;
OPEN myCursor;
FETCH FIRST FROM myCursor INTO @КодЗаказа, @Цена, @ЦенаНВ;
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE Заказ
SET Стоимость = Количество * @Цена, СтоимостьНВ = Количество * @ЦенаНВ
WHERE КодЗаказа = @КодЗаказа;
FETCH NEXT FROM myCursor INTO @КодЗаказа, @Цена, @ЦенаНВ;
END;
CLOSE myCursor;
DEALLOCATE myCursor;
END;
GO

SELECT * FROM Заказ
UPDATE Заказ
SET Количество = 5
SELECT * FROM Заказ

WHERE КодЗаказа = 9;

GO

/*Доп.задание/Триггер на таблицу Товар:
если это обновление наименования товара - то отменяем транзакцию,
если это обновление единица измерения - то мы ставим дату заказа сегодняшнюю,
если удаление товара - то та валюта, у которой был этот товар - меняем шан округлления валюты на 0.01*/

CREATE TRIGGER tr_updatee_delete_FOR
ON Товар
FOR DELETE, UPDATE
AS
DECLARE @countInsertedTable INT = 0
DECLARE @insertedCodeRow INT = 0
DECLARE @CurrencyCode VARCHAR(5)
DECLARE @deleteCount INT = 0

SELECT @countInsertedTable = COUNT(КодТовара), @insertedCodeRow = inserted.КодТовара
FROM inserted
GROUP BY КодТовара

SELECT @deleteCount = COUNT(КодТовара)
FROM deleted
GROUP BY КодТовара

IF UPDATE(Наименование)
BEGIN
PRINT 'Транзакция отменена'
ROLLBACK TRAN
END;
ELSE IF UPDATE(ЕдиницаИзм)
BEGIN
PRINT 'ЕДиНИЦА'

UPDATE Заказ
SET ДатаЗаказа = GETDATE()
WHERE КодТовара = @insertedCodeRow
END
ELSE IF (@countInsertedTable != 0 AND @deleteCount != 0)
BEGIN
PRINT 'Последнее'
SELECT @CurrencyCode = КодВалюты
FROM Товар

UPDATE Валюта
SET ШагОкругления = 0.001
WHERE КодВалюты LIKE @CurrencyCode
END
GO

UPDATE Товар
SET Наименование = '123'
WHERE КодТовара = 111

UPDATE Товар
SET ЕдиницаИзм = '123'
WHERE КодТовара = 111
SELECT * FROM Товар
SELECT * FROM Заказ

DELETE Товар
WHERE КодТовара = '111'
SELECT * FROM Товар




drop TRIGGER tr_ДОПqw

select * from Заказ

select * from Товар --inner join





ALTER TRIGGER tr_ДапапОывП
ON Товар
FOR INSERT, UPDATE
AS
DECLARE @КодТовара INT
IF EXISTS (select * from inserted Товар) AND not EXISTS (select * from deleted Товар)
begin
DECLARE myCursor CURSOR LOCAL STATIC
FOR
SELECT КодТовара
FROM inserted Товар
OPEN myCursor;
FETCH FIRST FROM myCursor INTO @КодТовара;
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO Заказ (КодКлиента, КодТовара, Количество, ДатаЗаказа, СрокПоставки, КодПоставщика)
VALUES (@КодТовара, 111, 8, GETDATE(), GETDATE()+12, 123)
FETCH NEXT FROM myCursor INTO @КодТовара;
END;
CLOSE myCursor;
DEALLOCATE myCursor;
end
else IF UPDATE(Наименование)
begin
DECLARE myCursor CURSOR LOCAL STATIC
FOR
SELECT КодТовара
FROM inserted Товар
OPEN myCursor;
FETCH FIRST FROM myCursor INTO @КодТовара;
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE Заказ
SET ДатаЗаказа = getdate()
from Товар
inner join Заказ on Заказ.КодТовара = Товар.КодТовара
WHERE Товар.КодТовара = @КодТовара;
FETCH NEXT FROM myCursor INTO @КодТовара;
END;
CLOSE myCursor;
DEALLOCATE myCursor;
end
else IF UPDATE(Наименование)
begin
DECLARE @Наименование varchar(30)
select @КодТовара = КодТовара,@Наименование = Наименование from deleted Товар
update Товар
set Наименование = @Наименование
where КодТовара = @КодТовара
end




GO






update Товар set Наименование= 'ывывы' where КодВалюты = 'BYN'

INSERT INTO Товар (Наименование, КодВалюты)
VALUES ('Мутный ывывы', 'BYN')
Соседние файлы в папке чужие лабы бд и прочее