当我在Sql Server 2005中遇到此行为时,我正在探索another question。此查询将耗尽最大递归:
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
但这样可行:
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
这是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)
答案 0 :(得分:5)
修改强>
我想我知道发生了什么,并且是一个很好的例子,说明为什么要首先避免选择*。
您先使用childId然后使用parentId定义您的表,但CTE Foo需要parentId,然后是childId,
所以基本上当你说选择#bar。*你的说法选择childId,parentId但你把它放入parentId,child。当你自己重新加入时,这会产生一个n级递归表达式。
所以这不是SQL中的错误。
课程的道德:避免选择*并避免头痛。
答案 1 :(得分:-1)
我认为这可能是程序员故意选择作为安全值,因为你有一个联合,并且联合的所有部分必须具有相同数量的字段。我从不在工会中使用select *,所以我不能肯定地说。我试过SQL Server 2008并收到此消息: Msg 205,Level 16,State 1,Line 1 使用UNION,INTERSECT或EXCEPT运算符组合的所有查询在目标列表中必须具有相同数量的表达式。
这似乎支持了我的理论。
选择*是一种在任何产品代码中使用的技术都很差,所以我不明白为什么简单地指定字段会出现问题。