[MSSQL] Разрешить только каскадное удаление из Detail-таблицы
От: stomsky Россия  
Дата: 31.05.13 17:52
Оценка:
Привет всем!
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-таблицы
От: Softwarer http://softwarer.ru
Дата: 31.05.13 18:12
Оценка:
Здравствуйте, stomsky, Вы писали:

А не получится ли в before delete мастера делать какую-нибудь транзакционную переменную, а в триггере детали её проверять? Ну хотя бы создавать темповую табличку..
Re: [MSSQL] Разрешить только каскадное удаление из Detail-таблицы
От: londinium Украина  
Дата: 31.05.13 18:19
Оценка:
Здравствуйте, 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-таблицы
От: stomsky Россия  
Дата: 01.06.13 12:20
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Здравствуйте, stomsky, Вы писали:


S>А не получится ли в before delete мастера делать какую-нибудь транзакционную переменную, а в триггере детали её проверять? Ну хотя бы создавать темповую табличку..

Хм... А в Ms Sql версии 2000 такое разве прокатит?
Красота — наивысшая степень целесообразности. (c) И. Ефремов
Re[2]: [MSSQL] Разрешить только каскадное удаление из Detail-таблицы
От: stomsky Россия  
Дата: 01.06.13 12:28
Оценка:
Здравствуйте, londinium, Вы писали:
L>Я бы сделал проще: отобрать права на удаление, а разрешить только удаление через хранимую процедуру, где все разрулить так, как Вам нужно
Ну в принципе вариант с триггером можно оставить как "последнюю линию обороны" от админа с трясущимися руками, а основной функционал сделать через ХП, но я как раз хотел попытаться этого избежать
Красота — наивысшая степень целесообразности. (c) И. Ефремов
Re[2]: [MSSQL] Разрешить только каскадное удаление из Detail-таблицы
От: stomsky Россия  
Дата: 01.06.13 12:31
Оценка:
Здравствуйте, londinium, Вы писали:
L>Я бы сделал проще: отобрать права на удаление, а разрешить только удаление через хранимую процедуру, где все разрулить так, как Вам нужно
Я правильно понимаю, что выбранный мной метод чем-то Вам не нравится?
Если не сложно, в двух словах чем именно?
Только потому что логика на триггерах не достаточно очевидна, или потому что имеет место ROLLBACK TRANSACTION, или что-то еще?
Красота — наивысшая степень целесообразности. (c) И. Ефремов
Re[2]: [MSSQL] Разрешить только каскадное удаление из Detail-таблицы
От: _ABC_  
Дата: 02.06.13 07:13
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>А не получится ли в before delete мастера делать какую-нибудь транзакционную переменную, а в триггере детали её проверять? Ну хотя бы создавать темповую табличку..

SQL Server не поддерживает before триггеры.
Re[3]: [MSSQL] Разрешить только каскадное удаление из Detail-таблицы
От: Ромашка Украина  
Дата: 02.06.13 09:02
Оценка:
Здравствуйте, _ABC_, Вы писали:
_AB>SQL Server не поддерживает before триггеры.

Давно? 2000й поддерживал, 2005й тоже. Сейчас что-то изменилось???


Всё, что нас не убивает, ещё горько об этом пожалеет.
Re[4]: [MSSQL] Разрешить только каскадное удаление из Detail-таблицы
От: _ABC_  
Дата: 03.06.13 02:18
Оценка: +1
Здравствуйте, Ромашка, Вы писали:

_AB>>SQL Server не поддерживает before триггеры.

Р>Давно? 2000й поддерживал, 2005й тоже. Сейчас что-то изменилось???

Да вроде всю жизнь не поддерживает?
ЕМНИП, по 8-ую только after, потом еще instead of.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.