与*和显式字段列表不同的结果?

And*_*mar 3 sql sql-server recursion

当我在Sql Server 2005中遇到此行为时,我正在探索另一个问题.此查询将耗尽最大递归:

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
Run Code Online (Sandbox Code Playgroud)

但这样可行:

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
Run Code Online (Sandbox Code Playgroud)

这是Sql Server中的一个错误,还是我忽略了什么?

这是表定义:

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)
Run Code Online (Sandbox Code Playgroud)

Jos*_*rke 5

编辑

我想我知道发生了什么,并且是一个很好的例子,为什么要首先避免选择*.

您先使用childId然后使用parentId定义了您的表,但是CTE Foo需要parentId然后是childId,

所以基本上当你说选择#bar.*你的说法选择childId,parentId但你把它放入parentId,child.当你自己加入时,这会产生一个n级递归表达式.

所以这不是SQL中的错误.

课程的道德:避免选择*并避免头痛.

  • +1 - select*应仅用于快速即席查询,但绝不能在生产系统中使用.我完全同意! (3认同)