View Full Version : سوال: Recursive Update Trigger in SQL 2000
Arghavan_Reza
پنج شنبه 19 فروردین 1389, 15:33 عصر
در جدولی با ساختار درختی:
Table1(ID, ParentID, Name, Flag)
ایراد تریگر زیر چیست؟ و چگونه اصلاح میشود؟
CREATE TRIGGER [Table1_Update_Childs] ON dbo.Table1
FOR UPDATE
AS
IF Update(Flag)
UPDATE Table1
SET Flag = I.Flag
FROM Inserted I
WHERE Table1.ParentID = I.ID
خطای ظاهر شده:
Maximum stored procedure, function, trigger, or
view nesting level exceeded (limit 32).
با تشکر.
AminSobati
پنج شنبه 19 فروردین 1389, 19:48 عصر
سلام دوست عزیزم،
Trigger و SP و Function میتونن حداکثر تا 32 مرحله تو در تو اجرا بشن. Updateی که در تریگر انجام میدین باعث میشه دوباره تریگر فعال بشه. میتونین با تابع TRIGGER_NESTLEVEL متوجه بشین که بار چندمه تریگر Nest میشه و در صورت لزوم Return کنین
محمد سلیم آبادی
پنج شنبه 19 فروردین 1389, 19:50 عصر
فکر می کنم بتونند با حلقه در یک SP هم نیازشون رو بر طرف کنند.
و اینکه استفاد از Trigger برای این اهداف ایده ی جالبی نمی تونه باشه.
Arghavan_Reza
شنبه 21 فروردین 1389, 16:54 عصر
با تشکر از دوستان
اما مشکل اینه که در یک درختی که 2 یا 3 سطح بیشتر ندارد چنین پیغامی دیده میشود (حتی اگر تغییرات در آخرین سطح انجام شود!).
محمد سلیم آبادی
شنبه 21 فروردین 1389, 17:03 عصر
مقدار ستون ParentID گره ی ریشه را برابر با NULL قرار دادین؟
Arghavan_Reza
شنبه 21 فروردین 1389, 17:21 عصر
بلی
مقدار ParentID ریشه NULL است. ارتباطی دارد؟!
AminSobati
شنبه 21 فروردین 1389, 18:55 عصر
احتمالا یک جای کد میلنگه! من جای شما باشم یک کپی از این دیتابیس رو در نسخه 2008 قرار میدم تا بتونم سطر به سطر Debug کنم
محمد سلیم آبادی
یک شنبه 22 فروردین 1389, 03:15 صبح
سلام،
این تابع و پروسیجر رو بعد از ساخت به جای trigger استفاده کنید.
CREATE FUNCTION dbo.fn(@ID AS INT) RETURNS @Subs TABLE
(
ID INT NOT NULL PRIMARY KEY NONCLUSTERED ,
lvl INT NOT NULL
)
AS
BEGIN
DECLARE @lvl AS INT;
SET @lvl = 0;
INSERT INTO @Subs(ID, lvl)
SELECT ID, @lvl FROM Table1 WHERE ParentID = @ID;
WHILE @@rowcount > 0
BEGIN
SET @lvl = @lvl + 1;
INSERT INTO @Subs(ID, lvl)
SELECT C.ID, @lvl
FROM @Subs AS P -- P = Parent
JOIN Table1 AS C -- C = Child
ON P.lvl = @lvl - 1
AND C.ParentID = P.ID;
END
RETURN;
END
GO
CREATE PROCEDURE edit (@ID INT) AS
BEGIN
DECLARE @Flag INT;
SELECT @Flag = Flag
FROM Table1
WHERE ID = @ID;
UPDATE T
SET T.Flag = @Flag
FROM Table1 AS T
INNER JOIN dbo.fn(@ID) AS F
ON T.ID = F.ID;
END
GO
محمد سلیم آبادی
یک شنبه 22 فروردین 1389, 03:23 صبح
بلی
مقدار ParentID ریشه NULL است. ارتباطی دارد؟!
تصور کردم مسیر از سمت برگ به ریشه هست ولی نگو از ریشه به سمت برگ حرکت می کنیم.
Arghavan_Reza
یک شنبه 22 فروردین 1389, 18:20 عصر
با تشکر از دوستانی که راهنمایی کردند.
ظاهرا مشکل از تابع تشخیص تغییر فیلد بود!
با تغییر کد به صورت زیر مشکل حل شد:
--IF Update(Flag)
IF EXISTS(SELECT * FROM Inserted I, Deleted D WHERE I.ID = D.ID AND I.Flag <> D.Flag)
UPDATE Table1
SET Flag = I.Flag
FROM Inserted I
WHERE Table1.ParentID = I.ID
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.