在视图定义中使用 SELECT * 是否存在问题?

Met*_*hor 5 sql-server view sql-server-2014

我正在为单独数据库中的视图创建多个代理视图。为了避免在两个地方定义视图,我想使用 SELECT * 创建代理视图。

我一直在寻找不这样做的原因,但没有找到。有人对使用 SELECT * 进行视图定义有意见吗?

Aar*_*and 14

是的,有理由不在SELECT *视图中使用。最重要的是,SQL Server 缓存了视图输出的元数据,如果底层对象发生变化,它不会神奇地更新。这是一个快速示例来演示:

USE tempdb;
GO
-- simple table with two int columns
CREATE TABLE dbo.x(a INT, b INT);
GO
INSERT dbo.x(a,b) VALUES(1,2);
GO

-- simple view using SELECT *
CREATE VIEW dbo.v_x
AS
  SELECT * FROM dbo.x;
GO

-- view will not be updated to see these changes:
EXEC sys.sp_rename N'dbo.x.b', N'c', N'COLUMN';
ALTER TABLE dbo.x ADD b DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;
GO

-- view shows wrong data
SELECT * FROM dbo.x;
SELECT * FROM dbo.v_x;
GO
Run Code Online (Sandbox Code Playgroud)

您需要强制 SQL Server 刷新其视图视图。

EXEC sys.sp_refreshview @viewname = N'dbo.v_x';
GO

-- now view is correct
SELECT * FROM dbo.v_x;
GO
Run Code Online (Sandbox Code Playgroud)

现在为什么要在视图中使用提出论点?因为您不想再次输入列名?您知道吗,您可以通过右键单击并说 Script View/Table As > SELECT To > clipboard 来轻松地从对象资源管理器中生成列列表?或者通过将列文件夹拖到查询窗口上?SELECT *

在此处输入图片说明

只是不要这样做。你在打字中节省的时间(以及你已经浪费在争论这个问题上的时间)不值得冒险,也不能证明有一些例外SELECT *是可以的。出于多种原因,这是一种不好的做法,并且特意制造异常是不一致的,并且通常会鼓励初级开发人员做错误的事情。

事实上,我尽量记住创建我的所有视图,WITH SCHEMABINDING以便以后更改它们一种痛苦。我不想能够准确无误地更改视图,因为这是破坏某些东西的万无一失的方式。

  • @Metaphor 我仍然认为,根据所做更改的类型,节省 4 秒的打字时间不值得潜在的灾难。你试过repro吗?如果对底层视图(或其底层表)进行更改,则应按计划方式对所有相关对象进行更改。时期。从现在到“最终”,你真的要做出多少改变?维护一个额外的列列表会真正创建多少额外的工作?你问了不做的理由,我给你不做的理由。如果你只是想忽略它们,你为什么要问? (3认同)