Пример использования триггеров SQL для поддержания ссылочной целостности


Ниже написанные триггеры сделаны для базы данных, которая была опубликована ранее (см. Пример создания базы данных из нескольких таблиц на SQL). Хочется отметить то, что все названия триггеров являются русскоязычными. Также напомню, что база данных и триггеры созданы для MS SQL (проверялось).

Ссылочная целостность в ранее созданной базе поддерживается за счет следующих триггеров:
— Ссылцелост_вид_вклада,
— Ссылцелост_вид_кредита,
— Ссылцелост_вклады,
— Ссылцелост_кредиты,
— Удаление_клиента,
— Удаление_вид_вклада,
— Запрет_удаления_базового_вклада,
— Удаление_вид_кредита.
Выше перечисленные триггеры обеспечивают корректную работу базы данных, поскольку, исключается ситуация существования в дочерних сущностях кортежей без родительских сущностей.

Код триггеров на SQL вместе с описаниями:

— Триггер Ссылцелост_вклады запрещает добавлять записи в таблицу Вклады, если соответствующие значения ид или ид_вклада отсутствуют в родительских таблицах (Клиенты и Вид_вклада)

CREATE TRIGGER Ссылцелост_вид_вклада on [dbo].[Вид_вклада]
after INSERT
as
BEGIN
if not exists (select * from [dbo].[Валюта] INNER JOIN inserted on [dbo].[Валюта].ид_валюта=inserted.ид_валюта)
BEGIN
rollback;
PRINT ‘Отсутствует запись в родительской таблице — Валюта’;
return;
END
END;

GO

— Аналогично триггеры Ссылцелост_вид_кредита, Ссылцелост_вклады, Ссылцелост_кредиты

CREATE TRIGGER Ссылцелост_вид_кредита on [dbo].[Вид_кредита]
after INSERT, UPDATE
as
BEGIN
if not exists (select * from [dbo].[Валюта] INNER JOIN inserted on [dbo].[Валюта].ид_валюта=inserted.ид_валюта)
BEGIN
rollback;
PRINT ‘Отсутствует запись в родительской таблице — Валюта’;
return;
END
END;

GO

CREATE TRIGGER Ссылцелост_вклады on [dbo].[Вклады]
after INSERT, UPDATE
as
BEGIN
if not exists (select * from [dbo].[Клиенты] INNER JOIN inserted on [dbo].[Клиенты].ид=inserted.ид_клиент)
or not exists (select * from [dbo].[Вид_вклада] INNER JOIN inserted on [dbo].[Вид_вклада].ид_вклада=inserted.вид_вклада)
BEGIN
rollback;
PRINT ‘Отсутствует запись в родительской таблице’;
return;
END
END;

GO

CREATE TRIGGER Ссылцелост_кредиты on [dbo].[Кредиты]
after INSERT, UPDATE
as
BEGIN
if not exists (select * from [dbo].[Клиенты] INNER JOIN inserted on [dbo].[Клиенты].ид=inserted.ид_клиент)
or not exists (select * from [dbo].[Вид_кредита] INNER JOIN inserted on [dbo].[Вид_кредита].ид_кредита=inserted.вид_кредита)
BEGIN
rollback;
PRINT ‘Отсутствует запись в родительской таблице’;
return;
END
END;

GO

— Триггер Удаление_клиента при удаление клиента из таблицы Клиенты, удаляет все вклады и кредиты этого клиента в дочерних таблицах (Вклады и Кредиты).

CREATE TRIGGER Удаление_клиента on [dbo].[Клиенты]
after DELETE
AS
BEGIN
IF EXISTS (SELECT * FROM DELETED INNER JOIN [dbo].[Вклады] on [dbo].[Вклады].ид_клиент=DELETED.ид)
OR EXISTS (SELECT * FROM DELETED INNER JOIN [dbo].[Кредиты] on [dbo].[Кредиты].ид_клиент=DELETED.ид)
BEGIN
DELETE FROM [dbo].[Вклады]
WHERE [dbo].[Вклады].ид_клиент = (SELECT ид FROM DELETED)
DELETE FROM [dbo].[Кредиты]
WHERE [dbo].[Кредиты].ид_клиент = (SELECT ид FROM DELETED)
END
END;

GO

— Триггер Удаление_вид_вклада при удаление какого-либо вида вклада (кроме базового) автоматически переведет все вклады на базовый вклад. Для запрета удаления базового вклада существует специальный триггер Запрет_удаления_базового_вклада

CREATE TRIGGER Удаление_вид_вклада on [dbo].[Вид_вклада]
AFTER Delete
AS
BEGIN
IF EXISTS (SELECT * FROM DELETED INNER JOIN [dbo].[Вклады] on [dbo].[Вклады].вид_вклада=DELETED.ид_вклада)
BEGIN
UPDATE [dbo].[Вклады] SET [dbo].[Вклады].вид_вклада=001 WHERE [dbo].[Вклады].вид_вклада = (SELECT ид_вклада FROM DELETED)
END
END;

GO

CREATE TRIGGER Запрет_удаления_базового_вклада on [dbo].[Вид_вклада]
AFTER Delete, update
AS
BEGIN
IF EXISTS (SELECT * FROM DELETED WHERE DELETED.ид_вклада=001)
rollback;
PRINT ‘Запрещено удалять или изменять номер базового вклада’;
return;
END;

GO

CREATE TRIGGER Удаление_вид_кредита on [dbo].[Вид_кредита]
AFTER Delete
AS
BEGIN
IF EXISTS (SELECT * FROM DELETED INNER JOIN [dbo].[Кредиты] on [dbo].[Кредиты].вид_кредита=DELETED.ид_кредита)
BEGIN
DELETE FROM [dbo].[Кредиты]
WHERE [dbo].[Кредиты].вид_кредита = (SELECT ид_кредита FROM DELETED)
END
END;

GO

— Хранимая процедура avgsum выводит идентификатор вклада, сумму вклада, номер клиента и название вклада среди всех вкладов, сумма вложений которых больше среднего.

CREATE PROCEDURE avgsum AS
BEGIN
SELECT [dbo].[Вклады].ид_вклад, [dbo].[Вклады].сумма, [dbo].[Вклады].ид_клиент, [dbo].[Вид_вклада].название
FROM [dbo].[Вклады], [dbo].[Вид_вклада]
WHERE ([dbo].[Вклады].сумма >= (select AVG([dbo].[Вклады].сумма) from [dbo].[Вклады])) and
([dbo].[Вклады].вид_вклада=[dbo].[Вид_вклада].ид_вклада)
END;

— Вызов процедуры avgsum :
exec avgsum

go

— Хранимая функция summa выводит средние значение суммы вклада

CREATE FUNCTION summa() RETURNS int
BEGIN
DECLARE @itog int;
SELECT @itog=AVG([dbo].[Вклады].сумма) from [dbo].[Вклады]
RETURN @itog
END;

— Вызов процедуры avgsum :
exec avgsum

go

— Представление Предвклады выводит фамилии клиентов, идентификаторы вкладов и суммы вкладов тех записей, у которых сумма вклада больше или равна 30000.

CREATE VIEW Предвклады
AS SELECT Клиенты.ф AS Фамилия, Вклады.ид_вклад AS Идентификатор_вклада, Вклады.сумма AS Сумма
FROM Клиенты, Вклады
WHERE (Вклады.сумма >= 30000) AND (Клиенты.ид=Вклады.ид_клиент)

— Вызов представления Предвклады:
select * from Предвклады


Комментарии запрещены.




Статистика