Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
palich12 Member Откуда: Сообщений: 359 |
Здравствуйте, Проблема следующая. Есть две таблицы, связанные 1:n, между связью NO ACTION Требуется удалить запись из основной таблицы и при этом чтобы удалились связанные записи во второй. Связь же удалить совсем нельзя, она нужна для ORM. Реализовал так Первая таблица CREATE TABLE [dbo].[Organization] ( [Id] BIGINT NOT NULL PRIMARY KEY IDENTITY, [Name] NVARCHAR(1000) NOT NULL, [Description] NVARCHAR(MAX) NULL ) Вторя таблица CREATE TABLE [dbo].[Group] ( [Id] BIGINT NOT NULL PRIMARY KEY IDENTITY, [OrganizationId] BIGINT NOT NULL, [Name] NVARCHAR(1000) NULL, [Description] NVARCHAR(MAX) NULL, [Icon] INT NULL, [Type] INT NOT NULL DEFAULT 1, CONSTRAINT [FK_Group_Organization] FOREIGN KEY ([OrganizationId]) REFERENCES [Organization]([Id]) ) В первой таблице добавил триггер CREATE TRIGGER [OrganizationDelete] ON Organization FOR DELETE AS BEGIN SET NOCOUNT ON DECLARE @Id bigint; SET @Id = (SELECT Id FROM deleted); DELETE FROM [Group] WHERE [Group].OrganizationId = @Id; END Однако он не отрабатывает при попытке удаление записи из первой таблицы, говорит, что не может удалить так как во второй таблице есть связанные записи |
5 май 13, 15:26 [14259739] Ответить | Цитировать Сообщить модератору |
Knyazev Alexey Member Откуда: Екб -> Мск Сообщений: 10234 Блог |
1) в сиквеле нет триггеров бефор...только ПОСЛЕ... 2) а что если удалять будут сразу N-записей, а не одну...то как отработает ваш триггер: SET NOCOUNT ON DECLARE @Id bigint; SET @Id = (SELECT Id FROM deleted); DELETE FROM [Group] WHERE [Group].OrganizationId = @Id; ? а по сабжу: как вариант, перекладывайте эту логику на вашего клиента...пусть он заботится за удаление связанных данных |
5 май 13, 15:30 [14259745] Ответить | Цитировать Сообщить модератору |
palich12 Member Откуда: Сообщений: 359 |
Knyazev Alexey, 1) FOR DELETE это и есть триггер BEFORE в MS SQL на сколько я знаю. 2) Это уже второй вопрос, для начала нужно хотябы по одной смочь удалять |
5 май 13, 15:40 [14259753] Ответить | Цитировать Сообщить модератору |
Knyazev Alexey Member Откуда: Екб -> Мск Сообщений: 10234 Блог |
к сожалению, вы плохо знаете...рекомендую для начала обратиться к официальной документации |
||
5 май 13, 15:41 [14259756] Ответить | Цитировать Сообщить модератору |
Knyazev Alexey Member Откуда: Екб -> Мск Сообщений: 10234 Блог |
http://msdn.microsoft.com/ru-ru/library/ms189799.aspx FOR | AFTER Тип AFTER указывает, что триггер DML срабатывает только после успешного выполнения всех операций в инструкции SQL, запускаемой триггером. Все каскадные действия и проверки ограничений, на которые имеется ссылка, должны быть успешно завершены, прежде чем триггер сработает. Если единственным заданным ключевым словом является FOR, аргумент AFTER используется по умолчанию. |
||||
5 май 13, 15:43 [14259760] Ответить | Цитировать Сообщить модератору |
palich12 Member Откуда: Сообщений: 359 |
Knyazev Alexey, да, вы авсолютно правы, тоже только что прочитал, изменил триггер следующим образом CREATE TRIGGER [OrganizationDelete] ON Organization INSTEAD OF DELETE AS BEGIN SET NOCOUNT ON DECLARE @Id bigint; SET @Id = (SELECT Id FROM deleted); DELETE FROM [Group] WHERE [Group].OrganizationId = @Id; DELETE FROM [Organization] WHERE [Organization].Id = @Id; END Все отработало нормально. Теперь думаю как сделать множественное удаление, посоветуйте, в FB я использовал SELECT FOR но не могу найти его аналога в MS SQL. Что лучше использовать? |
5 май 13, 15:51 [14259768] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47047 |
Я думаю, что в триггере в скалярных переменных нет никакой необходимости. Чаще всего это признак говнокода... |
||
5 май 13, 15:55 [14259776] Ответить | Цитировать Сообщить модератору |
alexeyvg Member Откуда: Moscow Сообщений: 31779 |
Не знаю, что такое SELECT FOR в FB, но судя по словам "SELECT" и "FOR" это явно не множественное удаление, а цикл по записям (но интуиция может меня подвести :-) ) |
||
5 май 13, 15:55 [14259777] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47047 |
Собственно говоря, при удалении более одной записи будет ошибка вот здесь:SET @Id = (SELECT Id FROM deleted); |
5 май 13, 15:56 [14259778] Ответить | Цитировать Сообщить модератору |
Knyazev Alexey Member Откуда: Екб -> Мск Сообщений: 10234 Блог |
delete g from Group g inner join deleted d on d.id = g.OrganizationId |
5 май 13, 15:56 [14259779] Ответить | Цитировать Сообщить модератору |
palich12 Member Откуда: Сообщений: 359 |
Knyazev Alexey, Спасибо большое, все отлично заработало |
5 май 13, 16:09 [14259800] Ответить | Цитировать Сообщить модератору |
Гость333 Member Откуда: Сообщений: 3683 |
ORM требует, чтобы связь была именно NO ACTION? Нельзя поменять на ON DELETE CASCADE? |
||
5 май 13, 16:50 [14259863] Ответить | Цитировать Сообщить модератору |
palich12 Member Откуда: Сообщений: 359 |
Гость333, там есть циклические связи типа table1 -> table2 table1-> table3 table2 -> table4 table3 -> table4 MS SQL не умеет разруливать такие каскады, поэтому не дает их создавать. Такое только Oracle умеет. Поэтому и пришлось триггеры воротить |
13 май 13, 23:53 [14290116] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |