Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Удаление из таблицы со связью NO ACTION  [new]
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]     Ответить | Цитировать Сообщить модератору
 Re: Удаление из таблицы со связью NO ACTION  [new]
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]     Ответить | Цитировать Сообщить модератору
 Re: Удаление из таблицы со связью NO ACTION  [new]
palich12
Member

Откуда:
Сообщений: 359
Knyazev Alexey,
1) FOR DELETE это и есть триггер BEFORE в MS SQL на сколько я знаю.
2) Это уже второй вопрос, для начала нужно хотябы по одной смочь удалять
5 май 13, 15:40    [14259753]     Ответить | Цитировать Сообщить модератору
 Re: Удаление из таблицы со связью NO ACTION  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10234
Блог
palich12
Knyazev Alexey,
1) FOR DELETE это и есть триггер BEFORE в MS SQL на сколько я знаю.

к сожалению, вы плохо знаете...рекомендую для начала обратиться к официальной документации
5 май 13, 15:41    [14259756]     Ответить | Цитировать Сообщить модератору
 Re: Удаление из таблицы со связью NO ACTION  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10234
Блог
Knyazev Alexey
palich12
Knyazev Alexey,
1) FOR DELETE это и есть триггер BEFORE в MS SQL на сколько я знаю.

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


http://msdn.microsoft.com/ru-ru/library/ms189799.aspx

FOR | AFTER  
Тип AFTER указывает, что триггер DML срабатывает только после успешного выполнения всех операций в инструкции SQL,
 запускаемой триггером.  
Все каскадные действия и проверки ограничений, на которые имеется ссылка, 
должны быть успешно завершены, прежде чем триггер сработает. 

Если единственным заданным ключевым словом является FOR, 
аргумент AFTER используется по умолчанию. 
5 май 13, 15:43    [14259760]     Ответить | Цитировать Сообщить модератору
 Re: Удаление из таблицы со связью NO ACTION  [new]
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]     Ответить | Цитировать Сообщить модератору
 Re: Удаление из таблицы со связью NO ACTION  [new]
iap
Member

Откуда: Москва
Сообщений: 47047
palich12
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. Что лучше использовать?
Что будет в переменной @Id, если удалить одним DELETE две записи?
Я думаю, что в триггере в скалярных переменных нет никакой необходимости.
Чаще всего это признак говнокода...
5 май 13, 15:55    [14259776]     Ответить | Цитировать Сообщить модератору
 Re: Удаление из таблицы со связью NO ACTION  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31779
palich12
Теперь думаю как сделать множественное удаление, посоветуйте, в FB я использовал SELECT FOR но не могу найти его аналога в MS SQL. Что лучше использовать?
Множественное удаление в MS SQL делается так же, как во всех поддерживающих SQL СУБД, то есть командой DELETE

Не знаю, что такое SELECT FOR в FB, но судя по словам "SELECT" и "FOR" это явно не множественное удаление, а цикл по записям (но интуиция может меня подвести :-) )
5 май 13, 15:55    [14259777]     Ответить | Цитировать Сообщить модератору
 Re: Удаление из таблицы со связью NO ACTION  [new]
iap
Member

Откуда: Москва
Сообщений: 47047
Собственно говоря, при удалении более одной записи будет ошибка вот здесь:
SET @Id = (SELECT Id FROM deleted);
5 май 13, 15:56    [14259778]     Ответить | Цитировать Сообщить модератору
 Re: Удаление из таблицы со связью NO ACTION  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10234
Блог
delete g from Group g inner join deleted d on d.id = g.OrganizationId
5 май 13, 15:56    [14259779]     Ответить | Цитировать Сообщить модератору
 Re: Удаление из таблицы со связью NO ACTION  [new]
palich12
Member

Откуда:
Сообщений: 359
Knyazev Alexey,
Спасибо большое, все отлично заработало
5 май 13, 16:09    [14259800]     Ответить | Цитировать Сообщить модератору
 Re: Удаление из таблицы со связью NO ACTION  [new]
Гость333
Member

Откуда:
Сообщений: 3683
palich12
Есть две таблицы, связанные 1:n, между связью NO ACTION
Требуется удалить запись из основной таблицы и при этом чтобы удалились связанные записи во второй. Связь же удалить совсем нельзя, она нужна для ORM.

ORM требует, чтобы связь была именно NO ACTION? Нельзя поменять на ON DELETE CASCADE?
5 май 13, 16:50    [14259863]     Ответить | Цитировать Сообщить модератору
 Re: Удаление из таблицы со связью NO ACTION  [new]
palich12
Member

Откуда:
Сообщений: 359
Гость333, там есть циклические связи типа
table1 -> table2
table1-> table3
table2 -> table4
table3 -> table4

MS SQL не умеет разруливать такие каскады, поэтому не дает их создавать. Такое только Oracle умеет. Поэтому и пришлось триггеры воротить
13 май 13, 23:53    [14290116]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить