2011-10-28 24 views
0

我有一個問題跟蹤執行以下代碼的順序:CTE如何在sql中工作?

的代碼是工作的罰款

我只是想了解如何。

with MyCTE(x) 
    as 
    (
    1) select x = convert(varchar(8000),'hello') // line 1 
    union all 
    3) select x + 'a' from MyCTE where len(x) < 100 //line 3 
    ) 
    select x from MyCTE 
    order by x 

MSDN:

遞歸執行的語義如下:

拆分的CTE表達成錨和遞歸成員。

運行錨定成員創建第一個調用或基礎結果 set(T0)。

用Ti作爲輸入,Ti + 1作爲輸出運行遞歸成員。

重複步驟3直到返回空集。

返回結果集。這是T0到Tn的聯盟。

階段:

1)第1行被執行(X =你好)

2)行3被執行(helloa)

3)現在它調用本身,以便:這裏x再次回到你好! (1號線)

  • 根據

    :行,每當CTE自稱 - 在x總是要復位! (或者T0是否在遞歸中繞過?)

  • (x)部分它的作用是什麼MyCTE(x)?輸入還是輸出?

報價:

與鈦運行遞歸構件(一個或多個)作爲輸入和Ti + 1作爲輸出。

據我所知,(x)是out值,而不是input。

+0

這是一個理論問題,還是你運行這個? – gbn

+0

@gbn - 嗨! ,我已經運行它,它的工作,但我不能找出如何。 - '每當cte調用自己 - x總是應該被重置,但它不(這是好的),但我無法找出原因:它說每次:'select x = convert(varchar(8000),'hello ')' –

回答

4

T0/Line1被執行一次作爲錨點。

  1. 線1被執行(你好)
  2. 線3被執行(helloa),因爲LEN(你好)= 5小於100
  3. 線3被執行(helloaa),因爲LEN(helloa)= 6小於100
  4. 線3被執行(helloaaa),因爲LEN(helloaa)= 7小於100
  5. 線3被執行(helloaaaa),因爲LEN(helloaaa)= 8小於100
  6. 線3被執行(helloaaaaa),因爲LEN(helloaaaa)= 9小於100
  7. 線3被執行(helloaaaaaa),因爲LEN(helloaaaa)= 10以下,然後100

...

隨着一些評論

with MyCTE(x) 
as 
(
    select x = convert(varchar(8000),'hello')  -- Anchor, executed once 
    union all 
    select x + 'a' from MyCTE where len(x) < 100 -- Recursion, executed n times 
) 
select x from MyCTE order by x 

在運行時,這是

select x = convert(varchar(8000),'hello')  -- Anchor 
    union all 
    select 'hello' + 'a'   -- Recursion 1 
    union all 
    select 'helloa' + 'a'  -- Recursion 2 
    union all 
    select 'helloaa' + 'a'  -- Recursion 3 
    union all 
    select 'helloaaa' + 'a'  -- Recursion 4 
    union all 
    select 'helloaaaa' + 'a'  -- Recursion 5 
    ... 
+0

一如既往 - 你是偉大的。謝謝。問題是,我認爲'1'行總是得到執行.... –

+1

超越eXcelent答案!!!謝謝你。 –