Вы находитесь на странице: 1из 7

/*1) DML триггер, регистрирующий изменение данных (вставку, обновление, удаление)

в таблице "waybills". Во вспомогательную таблицу waybills_LOG записывается кто,


когда (дата и время) и какое именно изменение произвел.

-- Создание таблицы LOG1, в которой будет храниться информация о действиях с


таблицей waybills
CREATE TABLE LOG1 (
oper_name CHAR(1),
pk_key VARCHAR2(20),
column_name VARCHAR2(30),
old_value VARCHAR2(20),
new_value VARCHAR2(20),
username VARCHAR2(30),
dateoper DATE);

-- Создание процедуры, которая будет сохранять данные в таблицу LOG1


CREATE OR REPLACE PROCEDURE logging (
voper_name IN CHAR,
vpk_key IN VARCHAR2,
vcolumn_name IN VARCHAR2,
vold_value IN VARCHAR2,
vnew_value IN VARCHAR2)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
date_and_time DATE;
BEGIN
IF vold_value <> vnew_value or voper_name IN ('I','D')
THEN
-- в переменную date_and_time записываем текущую дату и время
SELECT to_char(SYSDATE)
INTO date_and_time
FROM dual;
INSERT INTO LOG1
(oper_name, pk_key, column_name, old_value,
new_value, username, dateoper)
VALUES (voper_name, vpk_key, vcolumn_name, vold_value,
vnew_value, USER, date_and_time);
COMMIT;
END IF;
END;
/

--Создание триггера, который будет запускаться на события изменения данных в


таблице waybills

CREATE OR REPLACE TRIGGER waybills_LOG


AFTER INSERT OR UPDATE OR DELETE
ON waybills
FOR EACH ROW
DECLARE
op CHAR (1) := 'I';
BEGIN
CASE
WHEN INSERTING
THEN
op := 'I';
logging (op, :NEW.WAYBILL_ID, 'QUANTITY', NULL, :NEW.QUANTITY);
logging (op, :NEW.WAYBILL_ID, 'FUELLUBRI_ID',
NULL, :NEW.FUELLUBRI_ID);
logging (op, :NEW.WAYBILL_ID, 'price', NULL, :NEW.price);
WHEN UPDATING('QUANTITY') or UPDATING('FUELLUBRI_ID') or
UPDATING('price')
THEN
op := 'U';
logging (op, :NEW.WAYBILL_ID, 'QUANTITY', NULL, NULL);
logging (op, :NEW.WAYBILL_ID,
'FUELLUBRI_ID', :OLD.FUELLUBRI_ID, :NEW.FUELLUBRI_ID);
logging (op, :NEW.WAYBILL_ID, 'Price',NULL, NULL);
WHEN DELETING
THEN
op := 'D';
logging (op, :old.WAYBILL_ID, 'QUANTITY', :OLD.name_sw, NULL);
logging (op, :old.WAYBILL_ID, 'FUELLUBRI_ID', :OLD.FUELLUBRI_ID,
NULL);
logging (op, :old.WAYBILL_ID, 'Price', :OLD.Price, NULL);
ELSE
null;
END CASE;
END waybills_LOG;
/

-- Добавление строки
begin
insert into waybills(waybill_id,date_s,quantity,price,
fuellubri_id,supplier_id,city_id,worker_id)
values('13',to_date('01/01/2021','dd/mm/yyyy'),'232.00','123','10','4','4','2');
end;
/

select * from waybills;


select*from log1;

-- Изменение значения в поле "price"


UPDATE waybills
SET price = price - 25
WHERE waybill_id = 5;

select * from waybills;

-- Удаление строки из таблицы Software


DELETE FROM waybills
WHERE waybill_id = 3;

select * from waybills


select * from log1

/*2) Написать DDL триггер, протоколирующий действия пользователей по созданию,


изменению и удалению таблиц в схеме во вспомогательную таблицу LOG2 в определенное
время и запрещающий эти действия в другое время.*/
-- Создание таблицы LOG2, в которой будет храниться информация о действиях с
таблицами базы

CREATE TABLE LOG2 (


oper_name CHAR(1),
table_name VARCHAR2(30),
username VARCHAR2(30),
dateoper DATE);

-- Создание процедуры, которая будет сохранять данные в таблицу LOG2

CREATE OR REPLACE PROCEDURE logging_2 (


voper_name IN CHAR,
vtable_name IN VARCHAR2)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF voper_name IN ('C','A','D')
THEN
INSERT INTO LOG2
(oper_name, table_name, username, dateoper)
VALUES (voper_name,vtable_name, USER, SYSDATE);
COMMIT;
END IF;
END;
/

-- Создание триггера, который будет запускаться на события


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

CREATE OR REPLACE TRIGGER user_operations_LOG


BEFORE CREATE OR ALTER OR DROP
ON SCHEMA
DECLARE
op CHAR (1) := 'C';
date_and_time DATE;
l_sysevent VARCHAR2(10);
name_object VARCHAR2(20);
BEGIN
IF TO_CHAR(SYSDATE, 'HH24:MI') BETWEEN '12:00' AND '01:00'
THEN
RAISE_APPLICATION_ERROR (
num => -20000,
msg => 'Error!Wrong time!');

ELSE
-- Запишем в переменную l_sysevent название события, производимое над
объектом
SELECT ORA_SYSEVENT INTO l_sysevent FROM dual;
-- А в переменную name_object - имя объекта
SELECT ORA_DICT_OBJ_NAME INTO name_object FROM dual;
IF (l_sysevent = 'CREATE')
THEN
op := 'C';
logging_2 (op, name_object);
ELSE
null;
END IF;
IF (l_sysevent = 'ALTER')
THEN
op := 'A';
logging_2 (op, name_object);
ELSE
null;
END IF;
IF (l_sysevent = 'DROP')
THEN
op := 'D';
logging_2 (op, name_object);
ELSE
null;
END IF;
END IF;
END user_operations_LOG;
/

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


CREATE TABLE test(test_field INTEGER);

select * from log2

-- Внесем любое изменение


ALTER TABLE test MODIFY test_field VARCHAR2(10);

select * from log2;

-- Удаляем тестовую таблицу


DROP TABLE test;

select * from log2;

/*3) Системный триггер, добавляющий запись во вспомогательную таблцу LOG3, когда


пользователь подключается или отключается.
В таблицу логов записывается имя пользователя (USER), тип активности (LOGON или
LOGOFF), дата (SYSDATE), количество записей в основной таблице БД.*/

-- Создаём таблицу логов, которая будет храниться в системной БД


--таблица логов
CREATE TABLE IN_OUT_LOG (
USERNAME VARCHAR2(20),
OPER VARCHAR2(20),
DATEOPER DATE,
ROW_AMOUNT INTEGER);

--процедура записи

CREATE OR REPLACE PROCEDURE IN_OUT_WRITER (VOPER IN VARCHAR2) IS


PRAGMA AUTONOMOUS_TRANSACTION;
ROW_AMOUNT NUMBER;
BEGIN
SELECT COUNT(*) INTO ROW_AMOUNT FROM waybills;
INSERT INTO IN_OUT_LOG VALUES (USER,VOPER,SYSDATE,ROW_AMOUNT);
COMMIT;
END;
/

--триггер входа
CREATE OR REPLACE TRIGGER IN_AUD AFTER LOGON ON schema
BEGIN
IN_OUT_WRITER(ORA_SYSEVENT);
END;
/
--триггер выхода
CREATE OR REPLACE TRIGGER OUT_AUD BEFORE LOGOFF ON schema
BEGIN
IN_OUT_WRITER(ORA_SYSEVENT);
END;
/

4) a. триеры, реализующие бизнес логику:


В определенный сезон года(например зима), контролировать количество поставки
определенного топлива
*например не больше 1500*(например зимнего дизеля)

CREATE OR REPLACE TRIGGER CONTROL_waybills


BEFORE INSERT OR UPDATE
ON WAYBILLS
FOR EACH ROW
DECLARE
Z_d INTEGER:=1500;
d_c INTEGER;
BEGIN
CASE
WHEN INSERTING THEN
IF(:NEW.QUANTITY > Z_d) THEN
RAISE_APPLICATION_ERROR (
NUM => -20008,
MSG=>'АЗС уже имеет достаточное количество данного топлива');
END IF;
IF(:NEW.fuellubri_id = NULL OR :NEW.fuellubri_id = '' ) THEN
RAISE_APPLICATION_ERROR (
NUM => -20009,
MSG=>'ГСМ отсутсвует в базе');
END IF;
WHEN UPDATING('QUANTITY') THEN
IF(:NEW.QUANTITY > Z_d) THEN
RAISE_APPLICATION_ERROR (
NUM => -20008,
MSG=>('АЗС уже имеет достаточное количество данного топлива'));
END IF;
IF(:NEW.fuellubri_id = NULL OR :NEW.fuellubri_id = '' ) THEN
RAISE_APPLICATION_ERROR (
NUM => -20009,
MSG=>'ГСМ отсутсвует в базе');
END IF;
ELSE NULL;
END CASE;
END;
/

*****UPDATE waybills
SET quantity = 1501
WHERE waybill_id = 5;

b.*Отслеживать чтобы в день одна компания не делала более N поставок


create or replace TRIGGER CONTROL_sup
BEFORE INSERT OR UPDATE
ON waybills
FOR EACH ROW
DECLARE
max_pr INTEGER:=5;
cur_pr NUMBER;
BEGIN
CASE
WHEN INSERTING THEN
BEGIN
SELECT COUNT(*)
INTO cur_pr
from waybills
where waybills.supplier_ID = :NEW.SUPPLIER_ID AND
WAYBILLS.date_s = :NEW.date_s;
END;

IF(cur_pr+1 > Max_pr) THEN


RAISE_APPLICATION_ERROR (
NUM => -20008,
MSG => 'слишком много');
END IF;

WHEN UPDATING THEN


BEGIN
SELECT COUNT(*)
INTO cur_pr
from waybills
where waybills.supplier_ID = :NEW.SUPPLIER_ID AND
WAYBILLS.date_s = :NEW.date_s;
END;
IF(cur_pr+1 > Max_pr) THEN
RAISE_APPLICATION_ERROR (
NUM => -20008,
MSG => 'слишком много');
END IF;
ELSE NULL;
END CASE;
END;
/

В)

5)COMPOUND TRIGGER(ЕСЛИ ГСМ ЗАКОНЧИЛСЯ на АЗС)

6)
***CREATE OR REPLACE VIEW comp_inf AS
SELECT company_name||' '||city as COMPANY,quantity, price FROM suppliers s JOIN
waybills w ON s.supplier_id=w.supplier_id;***

****CREATE OR REPLACE VIEW vworkerv AS


SELECT name

CREATE OR REPLACE TRIGGER comp_inf


INSTEAD OF INSERT OR UPDATE
ON comp_inf
FOR EACH ROW
BEGIN
CASE
WHEN INSERTING THEN

END;
/

Вам также может понравиться