Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 TRIGGER на удаление нескольких записей (в цикле)  [new]
potkin
Member

Откуда: Ungvar
Сообщений: 1090
Есть триггер на удаление в котором надо обновить записи (уменьшить количество товара в таблице остатки).
ALTER TRIGGER [dbo].[TG_DELETE_RemMotions_RemRemnants] 
ON [dbo].[RemMotions] 
INSTEAD OF DELETE AS
BEGIN

	/* Изменяем "RemRemnants" */
	UPDATE RemRemnants     
	SET Quantity = Quantity - (SELECT RemMotions.Quantity FROM RemMotions WHERE RemMotionID = (SELECT RemMotionID FROM Deleted))     
	WHERE      
	 DirNomenID = (SELECT DirNomenID FROM RemMotions WHERE RemMotions.RemMotionID = (SELECT RemMotionID FROM Deleted))      
	 and      
	 DirWarehouseID = (SELECT DirWarehouseID FROM RemMotions WHERE RemMotionID = (SELECT RemMotionID FROM Deleted))

	/* Удаляем из "RemMotions" */
	DELETE FROM RemMotions WHERE RemMotions.RemMotionID = (SELECT Deleted.RemMotionID FROM Deleted)

END

Но проблема в том, что в под-запросе
(SELECT RemMotionID FROM Deleted)

может прийти не одна запись, а несколько.
Подскажите как быть в таком случае.
Может есть возможность "пробежаться" циклом и так обновить записи?

Заранее спасибо!
11 фев 16, 11:17    [18803140]     Ответить | Цитировать Сообщить модератору
 Re: TRIGGER на удаление нескольких записей (в цикле)  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
potkin,

UPDATE R
SET R.Quantity-=SUM(d.Quantity)
FROM deleted d JOIN RemRemnants R ON d.RemMotionID=R.RemMotionID
GROUP BY R.RemMotionID;

DELETE M
FROM deleted d JOIN RemMotionsID M ON d.RemMotionID=M.RemMotionID;
11 фев 16, 11:27    [18803210]     Ответить | Цитировать Сообщить модератору
 Re: TRIGGER на удаление нескольких записей (в цикле)  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
вы про джойны знаете ? зачем там цикл то ?
11 фев 16, 11:28    [18803216]     Ответить | Цитировать Сообщить модератору
 Re: TRIGGER на удаление нескольких записей (в цикле)  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
iap
potkin,

UPDATE R
SET R.Quantity-=SUM(d.Quantity)
FROM deleted d JOIN RemRemnants R ON d.RemMotionID=R.RemMotionID
GROUP BY R.RemMotionID;

DELETE M
FROM deleted d JOIN RemMotionsID M ON d.RemMotionID=M.RemMotionID;
Приврал. Нельзя так SUM() использовать, ЕМНИП.
UPDATE R
SET R.Quantity-=(SELECT SUM(d.Quantity) FROM deleted d WHERE d.RemMotionID=R.RemMotionID)
FROM RemRemnants R
WHERE EXISTS(SELECT * FROM deleted d WHERE d.RemMotionID=R.RemMotionID);

DELETE M
FROM deleted d JOIN RemMotionsID M ON d.RemMotionID=M.RemMotionID;
11 фев 16, 11:30    [18803229]     Ответить | Цитировать Сообщить модератору
 Re: TRIGGER на удаление нескольких записей (в цикле)  [new]
sega1999
Member

Откуда:
Сообщений: 9
iap, Возможно удаление нескольких записей одно и того же товара.
Поэтому нужно бы суммировать количество по товару в таблице DELETED и потом вычислять остатки
11 фев 16, 11:33    [18803248]     Ответить | Цитировать Сообщить модератору
 Re: TRIGGER на удаление нескольких записей (в цикле)  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
sega1999
iap, Возможно удаление нескольких записей одно и того же товара.
Поэтому нужно бы суммировать количество по товару в таблице DELETED и потом вычислять остатки
А у меня не так?
11 фев 16, 12:19    [18803517]     Ответить | Цитировать Сообщить модератору
 Re: TRIGGER на удаление нескольких записей (в цикле)  [new]
potkin
Member

Откуда: Ungvar
Сообщений: 1090
Ну я выложил малую часть ТРИГГЕРА.
Там ещё проверки на отрицательные остатки, если к-во = 0, то удалить запись, например:
	IF
	(
		SELECT Quantity FROM RemRemnants
		WHERE      
		 DirNomenID in (SELECT DirNomenID FROM RemMotions WHERE RemMotions.RemMotionID in (SELECT RemMotionID FROM Deleted))      
		 and      
		 DirWarehouseID in (SELECT DirWarehouseID FROM RemMotions WHERE RemMotionID in (SELECT RemMotionID FROM Deleted))
	) = 0
	BEGIN
		DELETE FROM RemRemnants 
		WHERE      
		 DirNomenID in (SELECT DirNomenID FROM RemMotions WHERE RemMotions.RemMotionID in (SELECT RemMotionID FROM Deleted))      
		 and      
		 DirWarehouseID in (SELECT DirWarehouseID FROM RemMotions WHERE RemMotionID in (SELECT RemMotionID FROM Deleted))
	END

Думаю без перебора всех удаляемых позиций не обойтись.
А можно как-то цикл WHILE прикрутить?
11 фев 16, 12:27    [18803549]     Ответить | Цитировать Сообщить модератору
 Re: TRIGGER на удаление нескольких записей (в цикле)  [new]
potkin
Member

Откуда: Ungvar
Сообщений: 1090
iap

Спасибо за примеры!
11 фев 16, 12:27    [18803554]     Ответить | Цитировать Сообщить модератору
 Re: TRIGGER на удаление нескольких записей (в цикле)  [new]
Glory
Member

Откуда:
Сообщений: 104751
potkin
Думаю без перебора всех удаляемых позиций не обойтись.

Вы думаете неправильно.

potkin
А можно как-то цикл WHILE прикрутить?

Прочитать в хелпе про синтаксис и начать "крутить" ?
11 фев 16, 12:28    [18803558]     Ответить | Цитировать Сообщить модератору
 Re: TRIGGER на удаление нескольких записей (в цикле)  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
potkin
Думаю без перебора всех удаляемых позиций не обойтись.
А можно как-то цикл WHILE прикрутить?
Уродский процедурный код, че тут еще скажешь. А еще туда конечно надо цикл затолкать, а если не поможет то и вложенный цикл.

У вас задание что-ли, написать код без единого JOIN-а? Вот так элементарно получаем количества которые были удалены:
SELECT DirNomenID, DirWarehouseID, SUM(Quantity) AS Quantity
FROM Deleted
GROUP BY DirNomenID, DirWarehouseID


Потом джойним и запихиваем все это в update:
UPDATE RR
SET Quantity = RR.Quantity - RM.Quantity
FROM RemRemnants RR
INNER JOIN 
(
	SELECT DirNomenID, DirWarehouseID, SUM(Quantity) AS Quantity
	FROM Deleted
	GROUP BY DirNomenID, DirWarehouseID
) RM ON RR.DirNomenID = RM.DirNomenID AND RR.DirWarehouseID = RM.DirWarehouseID


Удаление нулевых остатков еще проще. Нашли записи которые нужно удалить, и удалили. Не надо никаких дополнительных проверок.
DELETE RR 
FROM RemRemnants RR
INNER JOIN Deleted RM ON RR.DirNomenID = RM.DirNomenID AND RR.DirWarehouseID = RM.DirWarehouseID
WHERE RR.Quantity = 0

Да и зачем вам INSTEAD OF триггер то? Никакого смысла, только проблем больше. Все нужные вам данные находятся в таблице deleted. Замените на обычный AFTER.
11 фев 16, 21:31    [18806320]     Ответить | Цитировать Сообщить модератору
 Re: TRIGGER на удаление нескольких записей (в цикле)  [new]
potkin
Member

Откуда: Ungvar
Сообщений: 1090
Mind

Да, это рабочий вариант, вот только как не уйти в минуса?
То есть проверка на отрицательный остаток.
12 фев 16, 18:18    [18810756]     Ответить | Цитировать Сообщить модератору
 Re: TRIGGER на удаление нескольких записей (в цикле)  [new]
Glory
Member

Откуда:
Сообщений: 104751
potkin
То есть проверка на отрицательный остаток.

Вы что и операторов сравнения не знаете тоже ?
12 фев 16, 18:58    [18810894]     Ответить | Цитировать Сообщить модератору
 Re: TRIGGER на удаление нескольких записей (в цикле)  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
potkin
Mind

Да, это рабочий вариант, вот только как не уйти в минуса?
То есть проверка на отрицательный остаток.
Свою зарплату мне на счёт переведете?

Начните с хорошой книжки по SQL...
12 фев 16, 21:16    [18811322]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить