PDA

View Full Version : حرفه ای: پاک کردن تمام زیر شاخه های موجود در شاخه اصلی



M.KH-SH
دوشنبه 16 بهمن 1391, 12:25 عصر
با سلام

من نیاز دارم که در یک منو اصلی تمام زیر شاخه های اونو حذف کنم و تمام دسته های موجود در زیر شاخه ها هم پاک بشه و به همین ترتیب باید تا اخرین ردیف بره به نظر شما به چه صورت این کار رو انجام بدم؟


مرسی از کمک شما دوستان.


مشکل با کلمه delete نیست پس کوئری delete رو برام ننویسین مشکل با حلقه این کار هستش.

alihassanabadi
دوشنبه 16 بهمن 1391, 14:02 عصر
سلام

مشکل با کلمه delete نیست پس کوئری delete رو برام ننویسین مشکل با حلقه این کار هستش.
منظور شما اینه که منو رو از دیتا بیس میخونین؟
اگه اینجوریه طراحی و کد رو بزار.

M.KH-SH
دوشنبه 16 بهمن 1391, 17:33 عصر
دوست من من دوباره سئوال رو خودنم که نوشته بودم تا جایی که تونستم گفتم حذف میخوام بکنم پس دیگه چه کاری به خوندن دارم.

create table tb_ (id int primary key identity (1,1) , id_id int,name nvarchar(max))

این کد جدول درست

حالا برای یک منو تو در تو مییان id ستون رو میگیرن و در id_id فرزند اون قرار میدن و به همین ترتیب تا اخر میرن.

حالا من میخوام زمانی که پدر رو پاک کردم تمام فرزندان و فرزندان فرزندان و ... در این شاخه از بین بره.

یعنی حذف بشه

این کدها هم برای پاک کردن پدر و فرزند اول (شاخه اول بعد از پدر) هستش

delete from tb_ where id=1
delete from tb_ where id_id=1

حالا به این صورت من پدر و فرزند های ارشد رو پاک کردم ولی بقیه فرزندان در بانک باقی میمونه من میخوام تمام رو از بین ببرم. سئوالم هم دقیقا در همین جاست

shahab2025
سه شنبه 17 بهمن 1391, 08:33 صبح
من فکر میکنم بهترین راهش تابع بازگشتی باشه ولی من تجربه کمی در نوشتن آن دارم
منطقش اینطوری است
یک کلاس که یه عدد را به عنوان ID میگیره و اونو پاک میکنه
قبل از پاک کردن چک میکنه آیا ID وجود دارد که پدرش ID من باشه ؟ اگه نیست که پاک میکنه ولی اگه هست در یک حلقه همین کلاس را با ID فرزند تکرار میکنه
فکر کنم منطقش گویا باشه و امیدوارم در کد نویسی اش مشکلی نداشته باشید

در صورتی که مطلب مفید بود تشکر یادتان نرود

alihassanabadi
سه شنبه 17 بهمن 1391, 09:18 صبح
من فکر میکنم بهترین راهش تابع بازگشتی باشه ولی من تجربه کمی در نوشتن آن دارم
منطقش اینطوری است
یک کلاس که یه عدد را به عنوان ID میگیره و اونو پاک میکنه
قبل از پاک کردن چک میکنه آیا ID وجود دارد که پدرش ID من باشه ؟ اگه نیست که پاک میکنه ولی اگه هست در یک حلقه همین کلاس را با ID فرزند تکرار میکنه

سلام
آره منطقت خوبه ولی تو پای کد نویسی که میاد اعصاب آدم به هم میریزه تا بخوای خروجی بگیری
منم احساس میکنم
باید با یک for و یک تابع بازگشتی کار رو تموم کرد
من الان دارم تست میگیرم
ایشالا به نتیجه برسم جواب رو اینجا میزارم .

alihassanabadi
چهارشنبه 18 بهمن 1391, 17:48 عصر
مجددا سلام
خب با توجه به جدول شما
این پروسیجری که نوشتم قشنگ کار میکنه فقط کافی Root رو بهش بدی
اونوقت همه زیر مجموعه هاشو پاک میکنه
کوئری رو داخل دیتابیست بساز

ALTER PROC [dbo].[DeleteMenu]
(
@Root int
)
AS
BEGIN
if not exists (select name from [tempdb].[dbo].[sysobjects] where name like '#Temp%')
create table #Temp (Id int,
id_id int,
title nVarchar(50))
DECLARE @CID int
insert into #Temp SELECT tblMenu.Id , id_id , title from tblMenu WHERE Id = @Root
SET @CID = (SELECT MAX(Id) FROM tblMenu WHERE id_id = @Root)
WHILE @CID IS NOT NULL
BEGIN
EXEC dbo.DeleteMenu @CID
SET @CID = (SELECT MAX(Id) FROM tblMenu WHERE id_id = @Root AND Id < @CID )
END
END
Delete from tblMenu where Id in (select Id from #Temp)

موفق باشید.

M.KH-SH
جمعه 20 بهمن 1391, 19:23 عصر
میشه راجع به این sp یک توضیح بدی

M.KH-SH
جمعه 20 بهمن 1391, 19:49 عصر
خوب یک ساعت وقت گذاشتم چیزی از کوئری شما سر در نیاوردم میشه به تفکیک بهم بگین

ممنونم.

alihassanabadi
دوشنبه 23 بهمن 1391, 09:16 صبح
سلام
ببخشید سه روزی نبودم
این پروسیجر باعث میشه کل زیر شاخه های روت شما رو بکشه بیرون
با توجه به اینکه Id به صورت صعودی رشد میکنه ما هر بار مکس اونایی رو که Id_id شون برابر root هست رو در میاریم تا توسط while تمام زیر شاخه هاشو بازم بکشیم بیرون
بزارید نتیجه خروجی رو براتون اینجا بزارم خودتون کامل متوجه میشید
کلا به ازای هر فرزند(فرقی نداره یا فرزند-فرزند) یه تیبل خروجی میده

99900
کافی اون تیکه کد Delete رو غیر فعال کنی و به جاش یه Select بزنید تا نتیجه خروجی رو ببینید

--Delete from tblMenu where Id in (select Id from #Temp)
select * from #Temp

برای اینکه سرعت اجرای کوئری بالاتر بره میتونید این شرط رو بزار ید تا فقط از جدول آخر پاک کنه

if @@NESTLEVEL =1
Delete from tblMenu where Id in (select Id from #Temp)

موفق باشید.

M.KH-SH
دوشنبه 23 بهمن 1391, 21:17 عصر
دستت درد نکنه والا خطا میده:
Msg 208, Level 16, State 6, Procedure DeleteMenu, Line 22
Invalid object name 'dbo.DeleteMenu'.