2009-05-06 9 views
3

ich another question erforschte, wenn ich dieses Verhalten in SQL Server-Hit 2005. Diese Abfrage die maximale Rekursion erschöpfen würde:Unterschiedliches Ergebnis mit * und expliziter Feldliste?

with foo(parent_id,child_id) as (
    select parent_id,child_id 
    from #bar where parent_id in (1,3) 
    union all 
    select #bar.* -- Line that changed 
    from #bar 
    join foo on #bar.parent_id = foo.child_id 
) 
select * from foo 

Aber das würde funktionieren:

in
with foo(parent_id,child_id) as (
    select parent_id,child_id 
    from #bar where parent_id in (1,3) 
    union all 
    select #bar.parent_id, #bar.child_id -- Line that changed 
    from #bar 
    join foo on #bar.parent_id = foo.child_id 
) 
select * from foo 

Ist das ein Bug SQL-Server, oder übersehe ich etwas?

Hier ist die Tabellendefinition:

if object_id('tempdb..#bar') is not null 
    drop table #bar 

create table #bar (
    child_id int, 
    parent_id int 
) 

insert into #bar (parent_id,child_id) values (1,2) 
insert into #bar (parent_id,child_id) values (1,5) 
insert into #bar (parent_id,child_id) values (2,3) 
insert into #bar (parent_id,child_id) values (2,6) 
insert into #bar (parent_id,child_id) values (6,4) 

Antwort

5

bearbeiten

Ich glaube, ich weiß, was los ist und ist ein gutes Beispiel dafür, warum in erster Linie select * zu vermeiden.

Sie definiert Ihre Tabelle mit childID zuerst dann parentId, aber der CTE Foo erwartet parentId dann childID,

So im Wesentlichen, wenn Sie wählen # bar sagen. * Sie sagen wählen childID, parentId aber Ihr, dass in parentId setzen, Kind. Dies führt zu einem rekursiven Ausdruck auf n-Ebene, wenn Sie sich selbst wieder anschließen.

Das ist also kein Fehler in SQL.

Moral der Lektion: Vermeiden Wählen Sie * und sparen Sie sich Kopfschmerzen.

+3

+1 - Wählen Sie * sollte NUR immer für Quickie Ad-hoc-Abfragen verwendet werden, aber niemals nie in einem Produktionssystem. Ich stimme vollkommen zu! –

+0

Cool, danke, ich blieb stecken und dachte über die Rekursion nach. – Andomar

-1

Ich würde sagen, es war wahrscheinlich eine bewusste Wahl von den Programmierern als Sicherheitswert, weil Sie eine Union haben und alle Teile einer Union müssen die gleiche Anzahl von Feldern haben. Ich benutze nie Select * in einer Union, so kann ich nicht sicher sagen. Ich versuchte auf SQL Server 2008 und erhielt diese Nachricht: Nachricht 205, Ebene 16, Status 1, Zeile 1 Alle Abfragen, die mit einem UNION-, INTERSECT- oder EXCEPT-Operator kombiniert wurden, müssen eine gleiche Anzahl von Ausdrücken in ihren Ziellisten enthalten.

Das scheint meine Theorie zu unterstützen.

Wählen Sie * ist eine schlechte Technik in jedem Produktcode zu verwenden, daher sehe ich nicht, warum es ein Problem wäre, einfach die Felder anzugeben.

Verwandte Themen