
- •ПоСіБник до вивчення курсу «оргаНізація баз даних»
- •Лабораторна робота № 1 Інсталяція та інтерфейс Microsoft sql Server
- •Завдання для самостійної роботи
- •Лабораторна робота № 2 Розробка реляційної бази даних
- •Завдання
- •Лабораторна робота № 3 Створення та наповнення таблиць бд
- •Теоретична частина
- •Insert into persons values ('ivanov', 'ivan', 'ivanovich')
- •Insert into persons values ('petrov', 'petr', 'petrovich')
- •Insert into persons values ('sidorov', 'sidor', 'sidorovich')
- •Id_pers int not null references persons)
- •Insert into students values (9560679, @id_pr)
- •Insert into students values (3945794, @id_pr)
- •Insert into students values (4596956, @id_pr)
- •Id_subj int references subjects,
- •Id_mark int references marks)
- •Insert into stud_progress(id_stud, id_subj, id_mark) values
- •Insert into stud_progress(id_stud, id_subj, id_mark) values
- •Insert into stud_progress(id_stud, id_subj, id_mark) values
- •Завдання
- •Лабораторна робота № 4 Виконання запитів до бази даних
- •Теоретична частина
- •Into ім'я_таблиці
- •In (список_імен_стовпців_значень_груп)
- •In (список_імен_стовпців))
- •Intersect
- •Intersect
- •Лабораторна робота № 5 Ітеративна обробка результату запита
- •Теоретична частина
- •5.1. Declare
- •5.2. Open
- •5.3. Fetch
- •5.4. Close
- •5.5. Deallocate
- •5.6. Функції роботи з курсорами
- •5.7. Приклади використання курсорів
- •Завдання
- •Лабораторна робота № 6 Створення тригерів бд
- •Теоретична частина.
- •Видалення тригерів.
- •Дозвіл | заборона спрацьовування тригерів.
- •Приклади тригерів.
- •Instead of delete
- •Instead of insert, update, delete
- •Insert into table1(c1, c2) (select c1, c2 from inserted)
- •Завдання.
Instead of delete
not for replication
as
begin
declare
@var int
set @var = (select [object_id] from sys.objects where
name = 'trig2'and TYPE = 'TR'
and schema_id = (select schema_id from sys.schemas
where name = 'dbo'
)
)
if (TRIGGER_NESTLEVEL(@var, 'IOT', 'DML') = 1)
begin
delete from table1 from deleted d where table1.c3 = d.c3
end
end
go
Оскільки тригер INSTEAD OF спрацьовує замість команди DELETE, то дані з таблиці table1 віддалятися не будуть. Для того щоб їх видалити (видаляються дані, що, зберігаються в спеціальній таблиці deleted), необхідно повторити цю дію в тілі тригера. Як і в минулому прикладі, максимальна кількість рекурсивних викликів цього тригера = 2.
У результаті виконання команди:
delete table1 where c1 = 2
що приведе до спрацьовування тригера trig2, таблиця table1 буде містити наступні дані:
c1 |
c2 |
c3 |
1 |
1 |
1 |
1 |
2 |
2 |
1 |
3 |
3 |
1 |
4 |
4 |
6 |
5 |
6 |
Приклад 3.
Створення найпростішого INSTEAD OF тригера, що спрацьовує при виконанні всіх трьох команд (INSERT, UPDATE, DELETE) і, визначаючи тип команди, повторює дії, які команда повинна була виконати над даними таблиці.
if exists(select * from sys.objects where name = 'trig3' and schema_id = (select schema_id from sys.schemas where name = 'dbo') and type = 'TR')
drop trigger trig3
go
create trigger trig3
on table1
Instead of insert, update, delete
not for replication
as
begin
/*
Установка noucount on приводить до того, що не виводиться кількість оброблених командами T-SQL рядків
*/
set nocount on
declare
@var int
set @var = (select [object_id] from sys.objects where name = 'trig3'
and TYPE = 'TR'
and schema_id = (select schema_id from sys.schemas
where name = 'dbo')
)
if (TRIGGER_NESTLEVEL(@var, 'IOT', 'DML') = 1)
begin
declare
@count1 int,
@count2 int,
@count3 int,
@col_upd varbinary(128)
set @count1 = (select count(*) from table1)
set @count2 = (select count(*) from inserted)
set @count3 = (select count(*) from deleted)
set @col_upd = columns_updated()
if (@col_upd != 0)
begin
if (@count2 = @count3)
begin
- Випадок, коли тригер активований командою UPDATE
declare
@col_name varchar(128),
@table_id int,
@col_id int,
@is_iden bit,
@is_comp bit,
@type_id tinyint,
@type_name sysname
- одержуємо ідентифікатор таблиці table1 із системеного подання sys.objects
set @table_id = (select [object_id] from sys.objects where
name = 'table1' and type = 'U' and
schema_id = (select [schema_id]
from sys.schemas where name = 'dbo')
)
set @col_id = 0
/*
При використанні команди EXECUTE не можна звертатися до таблиці inserted, тому копіюємо її вміст у тимчасову таблицю
*/
select * into #temp_ins from inserted
- відключаємо спрацьовування тригера trig3
alter table table1 disable trigger trig3
- запускаємо цикл по тимі стовпцям, значення яких змінювалися
while (@col_upd <> 0)
begin
- одержуємо поточний номер стовпця один по одному від початку таблиці
set @col_id = @col_id + 1
if ((@col_upd & 1) = 1)
begin
- якщо цей стовпець піддавався зміні
/*
Одержуємо назву цього стовпця, інформацію про те, чи має він властивість identity або чи є він таким, що обчислюється або чи має він властивість identity, і ідентифікатор системного типу даних для цього стовпця
*/
select @col_name = name, @is_iden = is_identity,
@is_comp = is_computed,
@type_id = system_type_id
from sys.columns where
([object_id] = @table_id)
and (column_id = @col_id)
- Якщо стовпець не має властивості idenity і не є що обчислюється
if ((@is_iden <> 1) and (@is_comp <>1))
begin
- Одержуємо назву типу даних для цього стовпця
set @type_name = (select name from sys.types
where system_type_id = @type_id)
/*
Використовуючи команду EXECUTE і конструювання пакета SQL команд у строковому виді за допомогою операції конкатенації рядків виконуємо наступні дії:
Оголошуємо курсор по таблиці #temp_ins, що зберігає змінені значення оброблюваного стовпця і значення первинного ключа.
Оголошуємо змінні, які будуть використовуватися при одержанні значень поточного рядка курсору.
Запускаємо цикл, у якому перебираємо по черзі всі рядки курсору.
У цьому циклі одержуємо значення зміненого стовпця для поточного рядка, а також значення первинного ключа і конструюємо відповідну команду update, що для оброблюваного стовпця змінює його значення на отримане при збігу первинних ключів.
По закінченні циклу закриваємо курсор.
Для таблиць, де можлива зміна первинного ключа потрібен більш складний алгоритм, тому що змінюваний стовпець може виявитися елементом первинного ключа.
*/
execute( 'declare cur_ins cursor local for
select ' + @col_name +
' from #temp_ins ' +
'open cur_ins ' +
'declare @value_new ' + @type_name + ', ' +
' @value_key int '+
'while (1 = 1) ' +
'begin ' +
' fetch next from cur_ins into @value_new ,
@value_key' +
' if (@@FETCH_STATUS = -1) ' +
break; ' +
' update table1 set ' + @col_name + ' =
@value_new where c3 = @value_key ' +
'end ' +
'close cur_ins '
);
end
end
- Переходимо до обробки наступного стовпця
set @col_upd = @col_upd / 2
end
-- Знову дозволяємо спрацьовування тригера
begin
enable trigger trig3 ON table1
end
end
else
if (@count3 = 0)
begin
- Тригер активований командою INSERT