In SQL kann ein CTE nur in der (one) -Anweisung verwendet / referenziert werden, in der er definiert ist. Und wir wissen, wo Anweisungen enden, indem wir Anweisungsterminatoren ( ;
) verwenden.
SQL Server verzeiht und erlaubt Entwicklern, diese Terminatoren nicht zu setzen (außer in besonderen Fällen, in denen es sich beschwert), aber es ist wirklich eine gute Praxis (und Microsoft empfiehlt es), sie nach jeder Anweisung zu verwenden. Wenn Sie sie platziert hätten, wäre es offensichtlich, dass Ihr Code als 3 Anweisungen analysiert wird:
--- 1st statement starts ---
with ctegeneric as (select person from people where person = 'dumb')
Select * from ctegeneric ; -- and ends here
--- 2nd statement starts ---
Select * from ctegeneric ; -- and ends here
--- 3rd statement starts ---
Select * from ctegeneric ; -- and ends here
Ihre zweite und dritte Anweisung sollten also überhaupt nicht funktionieren und geben den Fehler zurück:
INVALID OBJECT NAME: ctegeneric
Sobald die Aussage, wo der CTE gemacht wird, endet, verlieren Sie die Fähigkeit, ihn erneut zu referenzieren.
Es ist so ähnlich (dies ist auch keine gültige Syntax, nur eine andere Art, über CTEs nachzudenken):
WITH ctegeneric AS (SELECT person
FROM people
WHERE person = 'dumb')
BEGIN
Select * from ctegeneric ;
END
Sie können die drei Auswahlen jedoch mit einem UNION/UNION ALL
:
WITH ctegeneric AS (SELECT person
FROM people
WHERE person = 'dumb')
Select * from ctegeneric
UNION
Select * from ctegeneric
UNION
Select * from ctegeneric ;