Özyinelemeli CTE'lerin BOL açıklaması özyinelemeli yürütmenin açıklar:
- CTE ifadesini bağlantı ve özyinelemeli üyelere ayırın.
- İlk aşılamayı veya temel sonuç kümesini (T0) oluşturan bağlantı üyelerini çalıştırın.
- Özyinelemeli üye (ler) i giriş olarak Ti ile ve giriş olarak Ti + 1 ile çalıştırın.
- Boş bir set geri dönene kadar 3. adımı tekrarlayın.
- Sonuç kümesini döndür. Bu, T0'dan Tn'ye kadar BÜTÜN BİR BİRLİKTİR.
Yukarıdakilerin mantıklı bir açıklaması olduğunu unutmayın. İşlemlerin fiziksel sırası burada gösterildiği gibi biraz farklı olabilir
Bunu CTE'nize uygulamak, aşağıdaki düzende sonsuz bir döngü beklerdim
+-----------+---------+---+---+---+
| Invocation| Results |
+-----------+---------+---+---+---+
| 1 | 1 | 2 | 3 | |
| 2 | 4 | 5 | | |
| 3 | 1 | 2 | 3 | |
| 4 | 4 | 5 | | |
| 5 | 1 | 2 | 3 | |
+-----------+---------+---+---+---+
Çünkü
select a
from cte
where a in (1,2,3)
Çapa ifadesidir. Bu açıkça döner 1,2,3olarakT0
Bundan sonra özyinelemeli ifade çalışır
select a
from cte
except
select a
from r
İle 1,2,3bir çıkış verecektir girdi olarak 4,5olarak T1o zaman dönecektir özyinelemeye sonraki turda içinde Sözünü geri takmayı 1,2,3vb süresiz ve.
Ancak gerçekte olan bu değil. Bunlar ilk 5 çağrının sonucudur
+-----------+---------+---+---+---+
| Invocation| Results |
+-----------+---------+---+---+---+
| 1 | 1 | 2 | 3 | |
| 2 | 1 | 2 | 4 | 5 |
| 3 | 1 | 2 | 3 | 4 |
| 4 | 1 | 2 | 3 | 5 |
| 5 | 1 | 2 | 3 | 4 |
+-----------+---------+---+---+---+
Artışlarla kullanım OPTION (MAXRECURSION 1)ve yukarı doğru ayarlamadan, 1art arda her seviyenin sürekli olarak çıkış 1,2,3,4ve arasında geçiş yapacağı bir döngüye girdiği görülebilir 1,2,3,5.
Tarafından açıklandığı gibi @Quassnoi içinde bu blog yayınında . Gözlemlenen sonuçların örneği, her çağrı önceki işlemden son satırın (1),(2),(3),(4),(5) EXCEPT (X)olduğu yerdedir X.
Düzenleme: SQL Kiwi'nin mükemmel cevabını okuduktan sonra , bunun neden ortaya çıktığı ve bunun hala işlenemeyen bir sürü şey olduğu konusundaki tüm hikayenin olmadığı açıktır.
Çapa 1,2,3istemciye gönderir3,2,1
3 yığılmış yığılmış, yığın içeriği 2,1
LASJ 1,2,4,5, Yığın İçeriği döndürür5,4,2,1,2,1
5 yığılmış yığılmış, yığın içeriği 4,2,1,2,1
LASJ 1,2,3,4 Yığın İçeriğini döndürür4,3,2,1,5,4,2,1,2,1
4 yığılmış yığılmış, yığın içeriği 3,2,1,5,4,2,1,2,1
LASJ 1,2,3,5 Yığın İçeriğini döndürür5,3,2,1,3,2,1,5,4,2,1,2,1
5 yığılmış yığılmış, yığın içeriği 3,2,1,3,2,1,5,4,2,1,2,1
LASJ 1,2,3,4 Yığın İçeriğini
döndürür4,3,2,1,3,2,1,3,2,1,5,4,2,1,2,1
Özyinelemeli üyeyi mantıksal olarak eşdeğer (yinelenen / NULL'ların yokluğunda) ifadesiyle değiştirmeye çalışırsanız
select a
from (
select a
from cte
where a not in
(select a
from r)
) x
Buna izin verilmiyor ve "Alt sorgularda özyineleli başvurulara izin verilmiyor" hatasını veriyor. Bu yüzden belki de EXCEPTbu durumda bile izin verilen bir gözetimdir .
Ekleme:
Microsoft şimdi Connect Feedback’e aşağıdaki gibi yanıt verdi :
Jack'in tahmini doğru: bu bir sözdizimi hatası olmalıydı; özyinelemeli referanslara gerçekten de EXCEPTmaddelerde izin verilmemelidir . Bu hatayı yaklaşan bir servis sürümünde ele almayı planlıyoruz. Bu arada, özyinelemeli referansları önlemek için öneriyorumEXCEPT
cümlelerde .
Yinelemeyi kısıtlamada, yinelemenin EXCEPTgetirilmesinden bu yana bu kısıtlamayı içeren ANSI SQL standardını takip ediyoruz (1999'da inanıyorum). EXCEPTSQL gibi bildirici dillerde , anlambilimde yinelemenin ne olması gerektiği konusunda ("kasıtsız olumsuzlama" olarak da bilinir) yaygın bir anlaşma yoktur . Ek olarak, bir RDBMS sisteminde bu anlambilimin verimli bir şekilde (makul büyüklükteki veri tabanları için) uygulanması oldukça zordur (mümkün değilse).
Ve nihayetinde uygulama 2014 yılında 120 ve daha üst düzeyde uyumluluk seviyesine sahip veritabanları için yapılmış gibi görünüyor .
Bir EXCEPT yan tümcesinde özyinelemeli referanslar, ANSI SQL standardına uygun bir hata oluşturur.