Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Задачка: "Хитрое" удаление записей в подчиненной таблице  [new]
dneprsat
Member

Откуда:
Сообщений: 3
Hello, All!
Прошу вашей помощи в решении следующей задачи.

Есть главная и подчиненная таблицы:
- MainTable (ID int,Name varchar(10))
- ChildTable(ID int,PosID int,[ReadOnly] bit)

Эти таблицы связаны по полю ID типа "1 ко многим".
Значение поля PosID уникально для каждого ID, т.е.
что-то типа № позиции для строки детальной части
каждого ID.
Если в ChildTable поле [ReadOnly] имеет значение 1, то
необходимо запретить удаление такой строки с помощью
напр.: DELETE FROM ChildTable WHERE ID=1 AND PosID=1.
Но разрешить удаление записи в главной таблице и всех
относящихся к ней записей в подчиненной таблице
(включая записи с [ReadOnly]=1) с помощью каскадного
удаления при выполнении команды напр.
DELETE FROM MainTable WHERE ID=1

Заранее вам благодарен!
8 окт 13, 13:39    [14939394]     Ответить | Цитировать Сообщить модератору
 Re: Задачка: "Хитрое" удаление записей в подчиненной таблице  [new]
Ken@t
Member

Откуда: 大地
Сообщений: 3264
dneprsat,

INSTEAD OF триггер ?
8 окт 13, 14:01    [14939616]     Ответить | Цитировать Сообщить модератору
 Re: Задачка: "Хитрое" удаление записей в подчиненной таблице  [new]
aleks2
Guest
ALTER TRIGGER [dbo].[trChildDEL] 
   ON  [dbo].[Child] 
   AFTER DELETE
AS 
BEGIN
    SET NOCOUNT ON;

    if exists( select * from deleted d inner join dbo.main m on m.id=d.refid and d.ro = 1)
    begin
      raiserror('фиг вамм', 16, 1)
      rollback tran;
    end;

END
8 окт 13, 14:48    [14939935]     Ответить | Цитировать Сообщить модератору
 Re: Задачка: "Хитрое" удаление записей в подчиненной таблице  [new]
Гость333
Member

Откуда:
Сообщений: 3683
aleks2,

При каскадном удалении сначала удаляются записи из подчинённых таблиц, а уже затем — из главной таблицы. Поэтому такой триггер всегда будет выбрасывать исключение.
8 окт 13, 14:58    [14940032]     Ответить | Цитировать Сообщить модератору
 Re: Задачка: "Хитрое" удаление записей в подчиненной таблице  [new]
aleks2
Guest
Гость333
aleks2,

При каскадном удалении сначала удаляются записи из подчинённых таблиц, а уже затем — из главной таблицы. Поэтому такой триггер всегда будет выбрасывать исключение.

Ты не поверишь - я проверил и это работает.

Microsoft SQL Server 2005 - 9.00.5057.00 (Intel X86) Mar 25 2011 13:50:04 Copyright (c) 1988-2005 Microsoft Corporation Developer Edition on Windows NT 5.2 (Build 3790: Service Pack 2)
8 окт 13, 15:03    [14940077]     Ответить | Цитировать Сообщить модератору
 Re: Задачка: "Хитрое" удаление записей в подчиненной таблице  [new]
Гость333
Member

Откуда:
Сообщений: 3683
[quot aleks2]Ты не поверишь - я проверил и это работает.[quot]
Хех... ни фига оно не работает. Но моё объяснение "сначала удаляются записи из подчинённых таблиц, а уже затем — из главной таблицы" полностью неверно.

Я предполагал такую последовательность действий:
1) Удаление записей из подчинённой таблицы;
2) Срабатывание триггера на подчинённой таблице;
3) Удаление записей из главной таблицы;
4) Срабатывание триггера на главной таблице (если он есть).

Но по содержимому журнала транзакций, профайлеру и действиям триггеров видно, что последовательность совсем другая:
1) Удаление записей из главной таблицы;
2) Удаление записей из подчинённой таблицы;
3) Срабатывание триггера на подчинённой таблице;
4) Срабатывание триггера на главной таблице (если он есть).

То есть, к моменту срабатывания триггера на подчинённой таблице, записей в главной уже не будет. И триггер даст удалить записи независимо от признака ReadOnly.

Ну или скрипт в студию, показывающий, как это работает.
8 окт 13, 16:04    [14940483]     Ответить | Цитировать Сообщить модератору
 Re: Задачка: "Хитрое" удаление записей в подчиненной таблице  [new]
Ennor Tiegael
Member

Откуда:
Сообщений: 3274
Гость333,

Ну да - констрейнты всю жизнь срабатывали раньше триггеров :)
8 окт 13, 16:11    [14940541]     Ответить | Цитировать Сообщить модератору
 Re: Задачка: "Хитрое" удаление записей в подчиненной таблице  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Ennor Tiegael
Гость333,

Ну да - констрейнты всю жизнь срабатывали раньше триггеров :)

И даже в доке это описано, ну что ж, буду запомнить
BOL
Triggers and Cascading Referential Actions

Cascading referential actions fire the AFTER UPDATE or AFTER DELETE triggers in the following manner:
All the cascading referential actions directly caused by the original DELETE or UPDATE are performed first.
If there are any AFTER triggers defined on the affected tables, these triggers fire after all cascading actions are performed. These triggers fire in opposite order of the cascading action.
8 окт 13, 16:21    [14940607]     Ответить | Цитировать Сообщить модератору
 Re: Задачка: "Хитрое" удаление записей в подчиненной таблице  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Гость333
aleks2
Ты не поверишь - я проверил и это работает.

Хех... ни фига оно не работает

Ё-маё... задание не дочитал: "Но разрешить удаление записи в главной таблице и всех относящихся к ней записей в подчиненной таблице (включая записи с [ReadOnly]=1)".

Ну тогда прощенья просим, aleks2, всё работает как надо.
8 окт 13, 17:21    [14940982]     Ответить | Цитировать Сообщить модератору
 Re: Задачка: "Хитрое" удаление записей в подчиненной таблице  [new]
dneprsat
Member

Откуда:
Сообщений: 3
Подтвержаю: Все работает.
Thank you very match, aleks2!!!
8 окт 13, 17:34    [14941087]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить