Привет всем!
MS Sql Server (версия, думаю, безразлична).
Имею две связанные таблицы (модельный пример):
create table MasterTable
(
MasterTableId int identity(1, 1) primary key,
...
)
create table DetailTable
(
DetailTable int identity(1, 1) primary key,
MasterTableId int not null foreign key (MasterTableId)
references MasterTable(MasterTableId)
on update no action
on delete cascade,
...
)
Необходимо сделать так, чтобы строки из DetailTable могли удаляться только в результате каскадного удаления, инициированного удалением соответствующей master-строки из MasterTable. А удалять строки напрямую из DetailTable нужно запретить.
Я ничего лучше триггера для решения проблемы не нашел:
create trigger DetailTable_Trigger_Delete
on DetailTable AFTER DELETE
as
begin
if exists(select *
from MasterTable (rowlock),
deleted
where MasterTable.MasterTableId = deleted.MasterTableId)
begin
raiserror('Deleting error', 16, 1)
rollback
end
end
Вроде бы все работает как надо, но... Собственно вопрос: насколько надежно этот триггер будет работать при конкурентном доступе к одним и тем же строкам нескольких пользователей, выполняющих разные действия с разными уровнями изоляции транзакций. Можно ли быть на 100% уверенным, что строку из DetailTable напрямую удалить не удастся без отключения триггера?
Красота — наивысшая степень целесообразности. (c) И. Ефремов
Re: [MSSQL] Разрешить только каскадное удаление из Detail-таблицы
А не получится ли в before delete мастера делать какую-нибудь транзакционную переменную, а в триггере детали её проверять? Ну хотя бы создавать темповую табличку..
Re: [MSSQL] Разрешить только каскадное удаление из Detail-таблицы
Здравствуйте, stomsky, Вы писали:
S>Привет всем! S>MS Sql Server (версия, думаю, безразлична). S>Имею две связанные таблицы (модельный пример): S>
S>create table MasterTable
S>(
S> MasterTableId int identity(1, 1) primary key,
S> ...
S>)
S>create table DetailTable
S>(
S> DetailTable int identity(1, 1) primary key,
S> MasterTableId int not null foreign key (MasterTableId)
S> references MasterTable(MasterTableId)
S> on update no action
S> on delete cascade,
S> ...
S>)
S>
S>Необходимо сделать так, чтобы строки из DetailTable могли удаляться только в результате каскадного удаления, инициированного удалением соответствующей master-строки из MasterTable. А удалять строки напрямую из DetailTable нужно запретить. S>Я ничего лучше триггера для решения проблемы не нашел: S>
S>create trigger DetailTable_Trigger_Delete
S> on DetailTable AFTER DELETE
S>as
S>begin
S> if exists(select *
S> from MasterTable (rowlock),
S> deleted
S> where MasterTable.MasterTableId = deleted.MasterTableId)
S> begin
S> raiserror('Deleting error', 16, 1)
S> rollback
S> end
S>end
S>
S>Вроде бы все работает как надо, но... S>Собственно вопрос: насколько надежно этот триггер будет работать при конкурентном доступе к одним и тем же строкам нескольких пользователей, выполняющих разные действия с разными уровнями изоляции транзакций. Можно ли быть на 100% уверенным, что строку из DetailTable напрямую удалить не удастся без отключения триггера?
Я бы сделал проще: отобрать права на удаление, а разрешить только удаление через хранимую процедуру, где все разрулить так, как Вам нужно
Re[2]: [MSSQL] Разрешить только каскадное удаление из Detail-таблицы
Здравствуйте, Softwarer, Вы писали:
S>Здравствуйте, stomsky, Вы писали:
S>А не получится ли в before delete мастера делать какую-нибудь транзакционную переменную, а в триггере детали её проверять? Ну хотя бы создавать темповую табличку..
Хм... А в Ms Sql версии 2000 такое разве прокатит?
Красота — наивысшая степень целесообразности. (c) И. Ефремов
Re[2]: [MSSQL] Разрешить только каскадное удаление из Detail-таблицы
Здравствуйте, londinium, Вы писали: L>Я бы сделал проще: отобрать права на удаление, а разрешить только удаление через хранимую процедуру, где все разрулить так, как Вам нужно
Ну в принципе вариант с триггером можно оставить как "последнюю линию обороны" от админа с трясущимися руками, а основной функционал сделать через ХП, но я как раз хотел попытаться этого избежать
Красота — наивысшая степень целесообразности. (c) И. Ефремов
Re[2]: [MSSQL] Разрешить только каскадное удаление из Detail-таблицы
Здравствуйте, londinium, Вы писали: L>Я бы сделал проще: отобрать права на удаление, а разрешить только удаление через хранимую процедуру, где все разрулить так, как Вам нужно
Я правильно понимаю, что выбранный мной метод чем-то Вам не нравится?
Если не сложно, в двух словах чем именно?
Только потому что логика на триггерах не достаточно очевидна, или потому что имеет место ROLLBACK TRANSACTION, или что-то еще?
Красота — наивысшая степень целесообразности. (c) И. Ефремов
Re[2]: [MSSQL] Разрешить только каскадное удаление из Detail-таблицы
Здравствуйте, Softwarer, Вы писали:
S>А не получится ли в before delete мастера делать какую-нибудь транзакционную переменную, а в триггере детали её проверять? Ну хотя бы создавать темповую табличку..
SQL Server не поддерживает before триггеры.
Re[3]: [MSSQL] Разрешить только каскадное удаление из Detail-таблицы