PDA

View Full Version : یک مسئله جالب در استفاده از CTE



Omid Rekabsaz
پنج شنبه 25 مهر 1387, 16:40 عصر
سلام
منطق زیر را در نظر بگیرید :
چک 1 به فاکتور 1 و 2 متصل است. چک 2 به فاکتور 1 و 3 متصل است و چک 3 به فاکتور 3

می خواهیم این مجموعه چک های مرتبط با هم را بدست آوریم... بهترین و سریعترین روش برای انجام این موضوع چیست؟

در زمان استفاده از CTE برای حالت بازگشتی چگونه می توان حلقه های اضافی را جذف نمود که وقتی از چک یک حرکت می کنیم دوباره به چک یک برنگردیم؟!

AminSobati
جمعه 26 مهر 1387, 16:25 عصر
سلام،
شما در ذخیره اطلاعاتتون حلقه ایجاد کردین و این کاملا واضحه که CTE دوباره به سر خط برمیگرده. در ساختار سلسله مراتبی این باید کنترل بشه که Parent به Child خودش Refer نده. اگر بنا به هر دلیلی این مسئله باید وجود داشته باشه، تصور میکنم میبایست از حلقه های دستی به کمک WHILE استفاده کنین و هر سری که اطلاعات رو بدست میارین و در جدول موقتی قرار میدین، کنترل کنین که رکوردها تکراری نشن

Omid Rekabsaz
شنبه 27 مهر 1387, 23:04 عصر
من دنبال یک روش سریع بودم... چون بنظر می رسید CTE فوق العاده سریع باشه... در حال حاضر از یک sp نوشتم که خودشو بصورت بازگشتی صدا می زنه... فقط محدودیت 32 بار تکرار رو داره... می شه این محدودیت رو حذف کرد؟!

AminSobati
شنبه 27 مهر 1387, 23:24 عصر
خیر. ولی نیازی به Recursive SP نیست. بلکه با همون While میشه عینا الگوریتم CTE رو شبیه سازی کرد



use northwind
go

DECLARE @ManagerID int
SET @ManagerID =2

--holds the output treelevel lets us isolate a level in the looped query
DECLARE @outTable table (employeeId int, ManagerID int, treeLevel int, processed bit)

--used to hold the level of the tree we are currently at in the loop
DECLARE @treeLevel as int
SET @treelevel = 1

--get the top level
INSERT into @outTable
SELECT employeeId, ReportsTo, @treelevel, 0
FROM employees
WHERE (ReportsTo = @ManagerID)

WHILE (1 = 1) --imitates do...until construct
BEGIN

INSERT INTO @outTable
SELECT e.employeeId, e.ReportsTo,
ot.treelevel + 1,0
FROM employees e
JOIN @outTable as ot
ON e.ReportsTo = ot.employeeId
--this where isolates a given level of the tree
WHERE ot.processed=0

IF @@rowcount = 0 BREAK


UPDATE @outTable SET processed=1
WHERE treeLevel-1<@treelevel

SET @treelevel = @treelevel + 1
END

--now look at the data in context of the employees we have inserted.
select * from @outTable

Omid Rekabsaz
پنج شنبه 02 آبان 1387, 01:19 صبح
بله متشکرم... می خواستم بدانم از خود CTE می توان استفاده کرد یا خیر...