很抱歉篇幅有点长,但我需要贴一些代码来说明问题。
受到问题*为什么不使用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)而非名称进行映射的。
我想发出一个警告,告诫使用 select * 的 SQL 语句并遇到意外行为的人们。
注意:如果每次修改表后重建使用 select * 的视图,它将按预期工作。