powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / проблемма с рекурсивным вызовом тригера
6 сообщений из 6, страница 1 из 1
проблемма с рекурсивным вызовом тригера
    #32056750
keystop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
создал тригер для установки флага логического удаления. В таблице храниться структура папок (дерево). Ясно, что при удалении "более верхней папки" нужно удалить и все "нижние". Так вот пытаюсь "удалить" (а на самом деле обновить) одну из строк и вижу ошибку
Server: Msg 217, Level 16, State 1, Procedure tAU_RUBRIC, Line 16
Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32).

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
CREATE TRIGGER tAU_RUBRIC
ON RUBRIC
AFTER UPDATE
AS
BEGIN

DECLARE @errnum   int,
	@errmsg   varchar( 255 )

if update(RubricDeleteDate) begin
	DECLARE @Status datetime

	SELECT TOP  1  @Status = RubricDeleteDate FROM inserted
	
	UPDATE RUBRIC
	SET RubricDeleteDate = @Status
	WHERE RubricParentID = (SELECT RubricID FROM inserted)
end

RETURN
ERROR:
	RAISERROR (@errnum, @errmsg,  10 )
	ROLLBACK TRANSACTION

END

 --и вот сам вызов
 
update rubric
set RubricDeleteDate = getdate()
where rubricID =  20 
...
Рейтинг: 0 / 0
проблемма с рекурсивным вызовом тригера
    #32056767
Есть такая глобальная переменная,
@@NESTLEVEL
которая показывает текущий уровень вложенности при рекурсивном вызове процедуры.

В вашем случае триггер должен выглядеть примерно так

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
CREATE TRIGGER tAU_RUBRIC
ON RUBRIC
AFTER UPDATE
AS
BEGIN

DECLARE @errnum   int,
	@errmsg   varchar( 255 )

if @@NESTLEVEL <  [b]1  
begin[/b]
if update(RubricDeleteDate) begin
	DECLARE @Status datetime

	SELECT TOP  1  @Status = RubricDeleteDate FROM inserted
	
	UPDATE RUBRIC
	SET RubricDeleteDate = @Status
	WHERE RubricParentID = (SELECT RubricID FROM inserted)
end

end

RETURN
ERROR:
	RAISERROR (@errnum, @errmsg,  10 )
	ROLLBACK TRANSACTION

END


Если update вызывается из хранимой процедуры, то следует использовать условие
if @@NESTLEVEL < 2 и т.д.

т.е. решение получается не совсем универсальное
...
Рейтинг: 0 / 0
проблемма с рекурсивным вызовом тригера
    #32056768
Есть такая глобальная переменная,
@@NESTLEVEL
которая показывает текущий уровень вложенности при рекурсивном вызове процедуры.

В вашем случае триггер должен выглядеть примерно так

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
CREATE TRIGGER tAU_RUBRIC
ON RUBRIC
AFTER UPDATE
AS
BEGIN

DECLARE @errnum   int,
	@errmsg   varchar( 255 )

if @@NESTLEVEL <  [b]1  
begin[/b]
if update(RubricDeleteDate) begin
	DECLARE @Status datetime

	SELECT TOP  1  @Status = RubricDeleteDate FROM inserted
	
	UPDATE RUBRIC
	SET RubricDeleteDate = @Status
	WHERE RubricParentID = (SELECT RubricID FROM inserted)
end

end

RETURN
ERROR:
	RAISERROR (@errnum, @errmsg,  10 )
	ROLLBACK TRANSACTION

END


Если update вызывается из хранимой процедуры, то следует использовать условие
if @@NESTLEVEL < 2 и т.д.

т.е. решение получается не совсем универсальное
...
Рейтинг: 0 / 0
проблемма с рекурсивным вызовом тригера
    #32056773
Фотография Garya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сэры, проблема не в этом. Проблема в том, что флаг Update(SomeField) будет установлен даже в том случае, если фактически не было модифицировано ни одной записи. Он устанавливается просто по факту включения поля в перечень модифицируемых полей командой update, а сколько там записей фактически модифицировано (пусть даже и ни одной), до фени. Это раз. Триггер срабатывает на команду update вне зависимости от того, сколько записей фактически должно быть модифицировано (может быть, тоже ни одной). Это два. Из всего сказанного следует вывод, что прежде чем внутри триггера выдавать команду update, которая может привести к рекурсивному запуску триггеров, необходимо до этой команды поставить корректное условие выхода из рекурсии. Я обычно для этой цели использовал if exists(...), в котором проверял, есть ли хоть одна запись, которую необходимо модифицировать.
...
Рейтинг: 0 / 0
проблемма с рекурсивным вызовом тригера
    #32056774
keystop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо разобрался! не хватало условия выхода из рекурсии ))
Однако получается что болле 31 уровня папок через тригер ни как не удалить ((((
...
Рейтинг: 0 / 0
проблемма с рекурсивным вызовом тригера
    #32056785
Фотография VVG_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно рекурсию преобразовать в цикл, где-то это уже было здесь. По типу обхода графа в ширину.
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / проблемма с рекурсивным вызовом тригера
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]