Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
&引用;从表格中选择*;vs";从表中选择可乐、可乐等;SQLServer2005中有趣的行为_Sql_Sql Server_Sql Server 2005_Tsql_Views - Fatal编程技术网

&引用;从表格中选择*;vs";从表中选择可乐、可乐等;SQLServer2005中有趣的行为

&引用;从表格中选择*;vs";从表中选择可乐、可乐等;SQLServer2005中有趣的行为,sql,sql-server,sql-server-2005,tsql,views,Sql,Sql Server,Sql Server 2005,Tsql,Views,为一篇冗长的文章道歉,但我需要发布一些代码来说明这个问题 受这个问题的启发,我决定指出一些我不久前注意到的关于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](

为一篇冗长的文章道歉,但我需要发布一些代码来说明这个问题

受这个问题的启发,我决定指出一些我不久前注意到的关于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
如果执行以下查询并查看最后两条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
正如您在从dbo.vStartest中选择a、b、c的结果中所看到的,c列的数据已替换为d列的数据

我认为这与视图的编译方式有关,我的理解是列是通过列索引(1,2,3,4)而不是名称来映射的

我想我会把它作为一个警告发布给那些在SQL中使用select*并经历意外行为的人

注意:如果每次修改表后重新生成使用select*的视图,它将按预期工作。

修复视图,或在视图定义中使用WITH SCHEMABINDING

如果视图不是使用 SCHEMABINDING子句,sp_refreshview 应在对进行更改时运行 该视图下的对象 影响视图的定义。 否则,视图可能会产生 查询时出现意外结果


这是任何
RDBMS下的视图的标准行为,而不仅仅是MSSQL,而且使用包含“select*from”的视图必须谨慎对待的原因

SQL引擎将编译每个视图——基本上是词典编纂/解析步骤,并存储其结果。如果因此更改了基础表,则始终需要显式重新编译,除非数据库具有某种标记视图的方法,以便在这种情况下进行检查


这个问题也可能(将)适用于存储过程和类似的数据库对象。

好的观点。我总是使用SCHEMABINDING,这是不允许的。我不明白,示例代码中没有D列。@Hogan你需要向下滚动代码示例,表starTest被删除并再次创建,这次有4列:A、B、D、Cthanks,我不知道我怎么会漏掉它。非常好的信息,但我认为应该放进去“社区维基”,因为这不是一个问题。