【发布时间】:2010-09-24 04:51:35
【问题描述】:
为一篇冗长的帖子道歉,但我需要发布一些代码来说明问题。
受问题 *What is the reason not to use select ? 的启发,我决定指出我前一段时间注意到的 select * 行为的一些观察结果。
让代码自己说话吧:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[starTest]') AND type in (N'U'))
DROP TABLE [dbo].[starTest]
CREATE TABLE [dbo].[starTest](
[id] [int] IDENTITY(1,1) NOT NULL,
[A] [varchar](50) NULL,
[B] [varchar](50) NULL,
[C] [varchar](50) NULL
) ON [PRIMARY]
GO
insert into dbo.starTest(a,b,c)
select 'a1','b1','c1'
union all select 'a2','b2','c2'
union all select 'a3','b3','c3'
go
IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[vStartest]'))
DROP VIEW [dbo].[vStartest]
go
create view dbo.vStartest as
select * from dbo.starTest
go
go
IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[vExplicittest]'))
DROP VIEW [dbo].[vExplicittest]
go
create view dbo.[vExplicittest] as
select a,b,c from dbo.starTest
go
select a,b,c from dbo.vStartest
select a,b,c from dbo.vExplicitTest
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[starTest]') AND type in (N'U'))
DROP TABLE [dbo].[starTest]
CREATE TABLE [dbo].[starTest](
[id] [int] IDENTITY(1,1) NOT NULL,
[A] [varchar](50) NULL,
[B] [varchar](50) NULL,
[D] [varchar](50) NULL,
[C] [varchar](50) NULL
) ON [PRIMARY]
GO
insert into dbo.starTest(a,b,d,c)
select 'a1','b1','d1','c1'
union all select 'a2','b2','d2','c2'
union all select 'a3','b3','d3','c3'
select a,b,c from dbo.vExplicittest
select a,b,c from dbo.vStartest
如果您执行以下查询并查看最后 2 个 select 语句的结果, 您将看到的结果如下:
select a,b,c from dbo.vExplicittest
a1 b1 c1
a2 b2 c2
a3 b3 c3
select a,b,c from dbo.vStartest
a1 b1 d1
a2 b2 d2
a3 b3 d3
正如您在 select a,b,c from dbo.vStartest 的结果中看到的那样,c 列的数据已替换为 d 列的数据。
我认为这与视图的编译方式有关,我的理解是列是由列索引 (1,2,3,4) 映射的,而不是名称。
我想我会将它发布为警告人们在他们的 SQL 中使用 select * 并遇到意外行为。
注意:如果每次修改表后都使用 select * 重建视图,它将按预期工作。
【问题讨论】:
-
我不明白,示例代码中的任何地方都没有 D 列。
-
@Hogan 你需要向下滚动代码示例,表 startTest 被删除并再次创建,这次有 4 列:A、B、D、C
-
谢谢,不知道我怎么错过了。
-
很好的信息,但我认为这应该放在“社区维基”中,因为这不是一个问题。
标签: sql sql-server sql-server-2005 tsql views