Rozważmy poniżejDlaczego nie możemy używać sprzężeń zewnętrznych w rekurencyjnym CTE?
;WITH GetParentOfChild AS
(
SELECT
Rn = ROW_NUMBER() Over(Order By (Select 1))
,row_id AS Parents
,parent_account_id As ParentId
FROM siebelextract..account
WHERE row_id = @ChildId
UNION ALL
SELECT
Rn + 1
,a.row_id as Parents
,a.parent_account_id As ParentId
FROM siebelextract..account a
JOIN GetParentOfChild gp on a.row_id = gp.ParentId
)
SELECT TOP 1 @ChildId = Parents
FROM GetParentOfChild
ORDER BY Rn DESC
co robi jest, że biorąc pod uwagę każde dziecko, zwróci poziomie głównym rodzica .... Program doskonale działa dobrze przez cały czas ...
Wystarczy się z ciekawości/wzgląd eksperymentalnej Zmieniłem JOIN LEFT OUTER JOIN i zgłaszane
Msg 462, Level 16, State 1, postępowanie getParent, Linia 9 sprzężenie zewnętrzne nie jest dozwolone w rekurencyjnego ramach cyklicznej wspólnym stole wyrażenie "GetParentOfChild".
Moje pytanie brzmi: dlaczego rekurencyjna część CTE nie może zaakceptować Left Outer Join? Czy to projekt?
Dzięki
Nie sądzę, że ta odpowiedź lub link rzeczywiście odpowiada "dlaczego". Chciałem połączyć dwa lewe łączenia (do zewnętrznych stołów), aby na przykład kontrolować kierunek następnej iteracji. Nieskończona rekurencja nie wydaje się być dobrym powodem, aby porzucić wszystkie pętle. – crokusek
@crokusek, przygotuj zapytanie koalescencyjne w poprzednim wyrażeniu cte i wewnętrznie połącz je z rekurencyjnym zapytaniem cte. – danihp
Ha, spróbowałem i działa, schludna sztuczka. Jeśli zrobiłem to dobrze, musiałem przekształcić lewe sprzężenia na pełne zewnętrzne w cte. To działało, ale plan zapytania staje się nieszczęśliwy - oblicza pełną zewnętrzną całość przed rozpoczęciem rte (nie zakończyłby się, zależnie od rozmiarów), tracąc w ten sposób rekurencyjnie sondowanie tylko dokładnie tego, czego potrzebował. Kursor zakończyłby działanie, chyba że wynik cte jest mały. Prawdopodobnie jest to miłe obejście niektórych przypadków. – crokusek